├── .gitignore
├── titl-core
├── src
│ ├── test
│ │ ├── resources
│ │ │ ├── Empty iTunes 8.0 Library.itl
│ │ │ ├── Empty iTunes 10.0 Library.itl
│ │ │ ├── Empty iTunes 10.0.1 Library.itl
│ │ │ ├── Empty iTunes 10.1 Library.itl
│ │ │ ├── Empty iTunes 10.2 Library.itl
│ │ │ ├── Empty iTunes 8.0.1 Library.itl
│ │ │ ├── Empty iTunes 9.0.3 Library.itl
│ │ │ ├── Empty iTunes 9.2.0 Library.itl
│ │ │ ├── iTunes 8.0.1 Library TMBG.itl
│ │ │ ├── Minimal iTunes 8.0.1 Library.itl
│ │ │ ├── Empty OS X iTunes 11.1.5 Library.itl
│ │ │ ├── iTunes 8.0.1 Library with TV show.itl
│ │ │ ├── iTunes 10.2.2 Library with single track.itl
│ │ │ └── iTunes 10.2.2 Library with single track with artwork.itl
│ │ └── java
│ │ │ └── org
│ │ │ └── kafsemo
│ │ │ └── titl
│ │ │ ├── TestParseLibraryWithTvShows.java
│ │ │ ├── TestInputImpl.java
│ │ │ ├── TestProcessLibrary.java
│ │ │ ├── TestITunesVersion.java
│ │ │ ├── art
│ │ │ └── TestArtworkFile.java
│ │ │ ├── tools
│ │ │ ├── TestMain.java
│ │ │ └── TestMoveMusic.java
│ │ │ ├── TestDates.java
│ │ │ ├── TestBase64.java
│ │ │ ├── TestUtil.java
│ │ │ ├── TestHohm.java
│ │ │ ├── TestHdfm.java
│ │ │ ├── TestHohmPodcast.java
│ │ │ └── TestParseLibrary.java
│ └── main
│ │ └── java
│ │ └── org
│ │ └── kafsemo
│ │ └── titl
│ │ ├── FlippedInputImpl.java
│ │ ├── Input.java
│ │ ├── ItlException.java
│ │ ├── ITunesVersion.java
│ │ ├── tools
│ │ ├── ShufflePlaylist.java
│ │ ├── Main.java
│ │ ├── ExportRatings.java
│ │ ├── ShowAllArtwork.java
│ │ ├── MoveMusic.java
│ │ └── ArtworkWebPage.java
│ │ ├── diag
│ │ └── InputRange.java
│ │ ├── Artwork.java
│ │ ├── Podcast.java
│ │ ├── Playlist.java
│ │ ├── Dates.java
│ │ ├── PlaylistRawItems.java
│ │ ├── art
│ │ ├── ArtworkFile.java
│ │ ├── ExtractArt.java
│ │ └── AlbumArtworkDirectory.java
│ │ ├── UnknownHohmException.java
│ │ ├── Base64.java
│ │ ├── InputImpl.java
│ │ ├── Util.java
│ │ ├── Library.java
│ │ ├── HohmPodcast.java
│ │ ├── ProcessLibrary.java
│ │ ├── Track.java
│ │ ├── Hdfm.java
│ │ └── RandomizePlaylist.java
└── pom.xml
├── README.md
├── BOILERPLATE
├── titl-rdf
├── pom.xml
└── src
│ └── main
│ └── java
│ └── org
│ └── kafsemo
│ └── titl
│ └── rdf
│ └── LibraryAsRdf.java
├── pom.xml
└── LGPL-3
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | .classpath
3 | .project
4 | .settings/
5 |
--------------------------------------------------------------------------------
/titl-core/src/test/resources/Empty iTunes 8.0 Library.itl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josephw/titl/HEAD/titl-core/src/test/resources/Empty iTunes 8.0 Library.itl
--------------------------------------------------------------------------------
/titl-core/src/test/resources/Empty iTunes 10.0 Library.itl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josephw/titl/HEAD/titl-core/src/test/resources/Empty iTunes 10.0 Library.itl
--------------------------------------------------------------------------------
/titl-core/src/test/resources/Empty iTunes 10.0.1 Library.itl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josephw/titl/HEAD/titl-core/src/test/resources/Empty iTunes 10.0.1 Library.itl
--------------------------------------------------------------------------------
/titl-core/src/test/resources/Empty iTunes 10.1 Library.itl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josephw/titl/HEAD/titl-core/src/test/resources/Empty iTunes 10.1 Library.itl
--------------------------------------------------------------------------------
/titl-core/src/test/resources/Empty iTunes 10.2 Library.itl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josephw/titl/HEAD/titl-core/src/test/resources/Empty iTunes 10.2 Library.itl
--------------------------------------------------------------------------------
/titl-core/src/test/resources/Empty iTunes 8.0.1 Library.itl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josephw/titl/HEAD/titl-core/src/test/resources/Empty iTunes 8.0.1 Library.itl
--------------------------------------------------------------------------------
/titl-core/src/test/resources/Empty iTunes 9.0.3 Library.itl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josephw/titl/HEAD/titl-core/src/test/resources/Empty iTunes 9.0.3 Library.itl
--------------------------------------------------------------------------------
/titl-core/src/test/resources/Empty iTunes 9.2.0 Library.itl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josephw/titl/HEAD/titl-core/src/test/resources/Empty iTunes 9.2.0 Library.itl
--------------------------------------------------------------------------------
/titl-core/src/test/resources/iTunes 8.0.1 Library TMBG.itl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josephw/titl/HEAD/titl-core/src/test/resources/iTunes 8.0.1 Library TMBG.itl
--------------------------------------------------------------------------------
/titl-core/src/test/resources/Minimal iTunes 8.0.1 Library.itl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josephw/titl/HEAD/titl-core/src/test/resources/Minimal iTunes 8.0.1 Library.itl
--------------------------------------------------------------------------------
/titl-core/src/test/resources/Empty OS X iTunes 11.1.5 Library.itl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josephw/titl/HEAD/titl-core/src/test/resources/Empty OS X iTunes 11.1.5 Library.itl
--------------------------------------------------------------------------------
/titl-core/src/test/resources/iTunes 8.0.1 Library with TV show.itl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josephw/titl/HEAD/titl-core/src/test/resources/iTunes 8.0.1 Library with TV show.itl
--------------------------------------------------------------------------------
/titl-core/src/test/resources/iTunes 10.2.2 Library with single track.itl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josephw/titl/HEAD/titl-core/src/test/resources/iTunes 10.2.2 Library with single track.itl
--------------------------------------------------------------------------------
/titl-core/src/test/resources/iTunes 10.2.2 Library with single track with artwork.itl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/josephw/titl/HEAD/titl-core/src/test/resources/iTunes 10.2.2 Library with single track with artwork.itl
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ##titl - Tools for iTunes Libraries
2 |
3 | A Java library for parsing iTunes' proprietary library file,
4 | along with command-line tools for modifying and extracting.
5 |
6 | See the
7 | [Tools](https://github.com/josephw/titl/wiki/Tools) wiki page for
8 | more details.
9 |
10 | ###License
11 | The GNU Lesser General Public License, v3 or later.
12 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/FlippedInputImpl.java:
--------------------------------------------------------------------------------
1 | package org.kafsemo.titl;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 |
6 | public class FlippedInputImpl extends InputImpl
7 | {
8 | public FlippedInputImpl(InputStream in)
9 | {
10 | super(in);
11 | }
12 |
13 | @Override
14 | public int readInt() throws IOException
15 | {
16 | return Integer.reverseBytes(super.readInt());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/titl-core/src/test/java/org/kafsemo/titl/TestParseLibraryWithTvShows.java:
--------------------------------------------------------------------------------
1 | package org.kafsemo.titl;
2 |
3 | import static org.junit.Assert.assertEquals;
4 | import static org.junit.Assert.assertNotNull;
5 |
6 | import java.io.File;
7 | import java.io.IOException;
8 |
9 | import org.junit.Test;
10 |
11 | public class TestParseLibraryWithTvShows
12 | {
13 | @Test
14 | public void testParseEmptyItunes80Library() throws IOException, ItlException
15 | {
16 | File f = new File("src/test/resources/iTunes 8.0.1 Library with TV show.itl");
17 |
18 | Library lib = ParseLibrary.parse(f);
19 | assertNotNull(lib);
20 | assertEquals("8.0.2", lib.getVersion());
21 | assertEquals("file://localhost/C:/Users/Joseph/Music/iTunes/iTunes%20Music/", lib.getMusicFolder());
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/BOILERPLATE:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 |
--------------------------------------------------------------------------------
/titl-rdf/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | org.kafsemo
7 | titl
8 | 0.3-SNAPSHOT
9 |
10 |
11 | titl-rdf
12 |
13 |
14 |
15 | org.kafsemo
16 | titl-core
17 | ${project.version}
18 |
19 |
20 | org.openrdf.sesame
21 | sesame-rio-turtle
22 | 2.7.10
23 |
24 |
25 | junit
26 | junit
27 | test
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/titl-core/src/test/java/org/kafsemo/titl/TestInputImpl.java:
--------------------------------------------------------------------------------
1 | package org.kafsemo.titl;
2 |
3 | import static org.junit.Assert.assertEquals;
4 |
5 | import java.io.ByteArrayInputStream;
6 | import java.io.IOException;
7 |
8 | import org.junit.Test;
9 |
10 | public class TestInputImpl
11 | {
12 | @Test
13 | public void getPositionReflectsReading() throws IOException
14 | {
15 | Input in = new InputImpl(new ByteArrayInputStream(new byte[1024]));
16 |
17 | assertEquals(0, in.getPosition());
18 | in.readUnsignedByte();
19 | assertEquals(1, in.getPosition());
20 | in.readShort();
21 | assertEquals(3, in.getPosition());
22 | in.readInt();
23 | assertEquals(7, in.getPosition());
24 | in.readFully(new byte[1]);
25 | assertEquals(8, in.getPosition());
26 | in.skipBytes(1);
27 | assertEquals(9, in.getPosition());
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/titl-core/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | org.kafsemo
7 | titl
8 | 0.3-SNAPSHOT
9 |
10 |
11 | titl-core
12 |
13 |
14 |
15 | junit
16 | junit
17 | test
18 |
19 |
20 |
21 |
22 |
23 |
24 | maven-jar-plugin
25 | 2.4
26 |
27 |
28 | false
29 |
30 | org.kafsemo.titl.tools.Main
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/Input.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | import java.io.IOException;
22 |
23 | public interface Input
24 | {
25 | int readUnsignedByte() throws IOException;
26 | short readShort() throws IOException;
27 | int readInt() throws IOException;
28 |
29 | void readFully(byte b[]) throws IOException;
30 |
31 | int skipBytes(int n) throws IOException;
32 | long getPosition();
33 | }
34 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/ItlException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 |
22 | /**
23 | * An exception with the structure of a library file.
24 | *
25 | * @author Joseph
26 | */
27 | public class ItlException extends Exception
28 | {
29 | public ItlException(String message, Throwable cause)
30 | {
31 | super(message, cause);
32 | }
33 |
34 | public ItlException(String message)
35 | {
36 | super(message);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/ITunesVersion.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | public class ITunesVersion
22 | {
23 | public static boolean isAtLeast(String fullVersion, int majorVersion)
24 | {
25 | int endOfFirstNumber = fullVersion.indexOf('.');
26 | if (endOfFirstNumber < 0) {
27 | endOfFirstNumber = fullVersion.length();
28 | }
29 |
30 | try {
31 | return Integer.parseInt(fullVersion.substring(0, endOfFirstNumber)) >= majorVersion;
32 | } catch (NumberFormatException nfe) {
33 | return false;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | org.kafsemo
5 | titl
6 | pom
7 |
8 | 0.3-SNAPSHOT
9 |
10 |
11 | titl-core
12 | titl-rdf
13 |
14 |
15 |
16 |
17 |
18 | junit
19 | junit
20 | 4.11
21 | test
22 |
23 |
24 |
25 |
26 |
27 | UTF-8
28 | 1.6
29 | 1.6
30 |
31 |
32 |
33 |
34 | LGPLv3
35 | http://www.gnu.org/licenses/lgpl-3.0.txt
36 | repo
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | maven-compiler-plugin
45 | 3.1
46 |
47 | 1.6
48 | 1.6
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/titl-core/src/test/java/org/kafsemo/titl/TestProcessLibrary.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | import static org.junit.Assert.assertEquals;
22 |
23 | import org.junit.Test;
24 | import org.kafsemo.titl.ProcessLibrary;
25 |
26 | public class TestProcessLibrary
27 | {
28 | @Test
29 | public void chooseCorrectEncoding()
30 | {
31 | ProcessLibrary.Encoding enc;
32 |
33 | enc = ProcessLibrary.chooseEncoding("");
34 | assertEquals(ProcessLibrary.Encoding.ISO88591, enc);
35 |
36 | enc = ProcessLibrary.chooseEncoding("Test");
37 | assertEquals(ProcessLibrary.Encoding.ISO88591, enc);
38 |
39 | enc = ProcessLibrary.chooseEncoding("T€st");
40 | assertEquals(ProcessLibrary.Encoding.UTF16BE, enc);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/titl-core/src/test/java/org/kafsemo/titl/TestITunesVersion.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | import static org.junit.Assert.assertFalse;
22 | import static org.junit.Assert.assertTrue;
23 |
24 | import org.junit.Test;
25 |
26 | public class TestITunesVersion
27 | {
28 | @Test
29 | public void versionsAreAtLeastTen()
30 | {
31 | assertTrue(ITunesVersion.isAtLeast("10", 10));
32 | assertTrue(ITunesVersion.isAtLeast("10.1", 10));
33 | assertTrue(ITunesVersion.isAtLeast("11", 10));
34 | }
35 |
36 | @Test
37 | public void earlierVersionsAreNotAtLeastTen()
38 | {
39 | assertFalse(ITunesVersion.isAtLeast("9", 10));
40 | assertFalse(ITunesVersion.isAtLeast("8.0", 10));
41 | assertFalse(ITunesVersion.isAtLeast("8.0.1", 10));
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/tools/ShufflePlaylist.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2013 Lael Jones
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl.tools;
20 |
21 | import java.io.File;
22 | import java.io.IOException;
23 |
24 | import org.kafsemo.titl.ItlException;
25 | import org.kafsemo.titl.RandomizePlaylist;
26 |
27 |
28 | /**
29 | * A simple command-line tool to shuffle the items in a playlist.
30 | *
31 | * @author Lael Jones
32 | */
33 | public class ShufflePlaylist
34 | {
35 | public static void main(String[] args) throws IOException, ItlException
36 | {
37 | if (args.length != 3) {
38 | System.err.println("Usage: Shuffle Playlist ");
39 | System.exit(5);
40 | }
41 |
42 | RandomizePlaylist.randomizePlaylist(new File(args[0]), new File(args[1]), args[2]);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/diag/InputRange.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl.diag;
20 |
21 | public class InputRange
22 | {
23 | public final long origin;
24 | public int length;
25 | public String type;
26 | public Object more;
27 | public String details;
28 |
29 | public InputRange(long origin)
30 | {
31 | this.origin = origin;
32 | }
33 |
34 | public String toString()
35 | {
36 | StringBuilder sb = new StringBuilder();
37 | sb.append(String.format("%08d: %s (%d)", origin, type, length));
38 | if (more != null) {
39 | sb.append(" ");
40 | sb.append(more);
41 | }
42 | if (details != null) {
43 | sb.append(" \"");
44 | sb.append(details);
45 | sb.append("\"");
46 | }
47 | return sb.toString();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/Artwork.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | import java.util.Arrays;
22 |
23 | public class Artwork
24 | {
25 | private final byte[] persistentId;
26 |
27 | public String title, artist, appTitle;
28 |
29 | public Artwork()
30 | {
31 | persistentId = null;
32 | }
33 |
34 | public Artwork(byte[] id)
35 | {
36 | persistentId = Arrays.copyOf(id, id.length);
37 | }
38 |
39 | public void setTitle(String title)
40 | {
41 | this.title = title;
42 | }
43 |
44 | public void setArtist(String artist)
45 | {
46 | this.artist = artist;
47 | }
48 |
49 | public void setAppTitle(String appTitle)
50 | {
51 | this.appTitle = appTitle;
52 | }
53 |
54 | public byte[] getPersistentId()
55 | {
56 | return persistentId;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/tools/Main.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl.tools;
20 |
21 | import java.lang.reflect.InvocationTargetException;
22 | import java.lang.reflect.Method;
23 | import java.util.Arrays;
24 |
25 | public class Main
26 | {
27 | public static void main(String... args)
28 | throws ClassNotFoundException, SecurityException,
29 | NoSuchMethodException, IllegalArgumentException,
30 | IllegalAccessException, InvocationTargetException
31 | {
32 | if (args.length < 1)
33 | {
34 | throw new IllegalArgumentException("Usage: Main ");
35 | }
36 |
37 | Class> cls = Class.forName(Main.class.getPackage().getName() + "." + args[0]);
38 |
39 | Method mm = cls.getMethod("main", String[].class);
40 |
41 | String[] subArgs = Arrays.copyOfRange(args, 1, args.length);
42 | mm.invoke(null, (Object) subArgs);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/tools/ExportRatings.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl.tools;
20 |
21 | import java.io.File;
22 | import java.io.IOException;
23 |
24 | import org.kafsemo.titl.ItlException;
25 | import org.kafsemo.titl.Library;
26 | import org.kafsemo.titl.ParseLibrary;
27 | import org.kafsemo.titl.Track;
28 |
29 |
30 | /**
31 | * A simple command-line tool to export ratings as a comma-separated list.
32 | *
33 | * @author Joseph
34 | */
35 | public class ExportRatings
36 | {
37 | public static void main(String[] args) throws IOException, ItlException
38 | {
39 | if (args.length != 1) {
40 | System.err.println("Usage: ExportRatings ");
41 | System.exit(5);
42 | }
43 |
44 | Library lib = ParseLibrary.parse(new File(args[0]));
45 |
46 | for (Track t : lib.getTracks()) {
47 | if(t.getLocation() != null) {
48 | System.out.println(t.getLocation() + "," + t.getRating());
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/Podcast.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | import java.util.ArrayList;
22 | import java.util.Collection;
23 | import java.util.Collections;
24 |
25 | public class Podcast extends Track
26 | {
27 | private String podcastUrl;
28 | private String podcastTitle;
29 | private Collection podcastAuthors = new ArrayList();
30 |
31 | public String getPodcastLocation()
32 | {
33 | return podcastUrl;
34 | }
35 |
36 | public void setPodcastLocation(String l)
37 | {
38 | this.podcastUrl = l;
39 | }
40 |
41 | public String getPodcastTitle()
42 | {
43 | return podcastTitle;
44 | }
45 |
46 | public void setPodcastTitle(String t)
47 | {
48 | this.podcastTitle = t;
49 | }
50 |
51 | public Collection getPodcastAuthors()
52 | {
53 | return Collections.unmodifiableCollection(podcastAuthors);
54 | }
55 |
56 | public void addPodcastAuthor(String author)
57 | {
58 | this.podcastAuthors.add(author);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/Playlist.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | import java.util.ArrayList;
22 | import java.util.List;
23 |
24 |
25 | class Playlist
26 | {
27 | byte[] ppid;
28 | String title;
29 | // int id;
30 | public byte[] smartInfo;
31 | public byte[] smartCriteria;
32 |
33 | private final List items = new ArrayList();
34 | private HohmPodcast hohmPodcast;;
35 |
36 | public byte[] getPpid()
37 | {
38 | return ppid;
39 | }
40 |
41 | public String getTitle()
42 | {
43 | return title;
44 | }
45 |
46 | public List getItems()
47 | {
48 | return items;
49 | }
50 |
51 | public void addItem(int key)
52 | {
53 | items.add(Integer.valueOf(key));
54 | }
55 |
56 | public void setHohmPodcast(HohmPodcast parse)
57 | {
58 | this.hohmPodcast = parse;
59 | }
60 |
61 | public HohmPodcast getHohmPodcast()
62 | {
63 | return hohmPodcast;
64 | }
65 |
66 | // public int getId()
67 | // {
68 | // return -1;
69 | // }
70 | }
71 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/Dates.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 | import java.text.DateFormat;
21 | import java.text.SimpleDateFormat;
22 | import java.util.Calendar;
23 | import java.util.Date;
24 | import java.util.TimeZone;
25 |
26 |
27 | public class Dates
28 | {
29 | static String toString(Date d)
30 | {
31 | DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
32 | df.setTimeZone(TimeZone.getTimeZone("UTC"));
33 |
34 | return df.format(d);
35 | }
36 |
37 | public static Date fromMac(long seconds)
38 | {
39 | if (seconds == 0)
40 | {
41 | return null;
42 | }
43 |
44 | seconds &= 0xFFFFFFFFL;
45 |
46 | Calendar cal = Calendar.getInstance();
47 | cal.setTimeZone(TimeZone.getTimeZone("Europe/London"));
48 | cal.clear();
49 | cal.set(Calendar.YEAR, 1904);
50 | cal.set(Calendar.MONTH, 0);
51 | cal.set(Calendar.DATE, 1);
52 |
53 | long epoch = cal.getTimeInMillis() - 60 * 60 * 1000L;
54 |
55 | return new Date((seconds * 1000L) + epoch);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/titl-core/src/test/java/org/kafsemo/titl/art/TestArtworkFile.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl.art;
20 |
21 | import static org.junit.Assert.assertEquals;
22 |
23 | import org.junit.Test;
24 |
25 | public class TestArtworkFile
26 | {
27 | @Test
28 | public void fileFromDefinition()
29 | {
30 | ArtworkFile af = new ArtworkFile(
31 | ArtworkFile.Directory.Cache,
32 | new byte[8],
33 | 2);
34 |
35 | String f = af.toString(new byte[8]);
36 |
37 | assertEquals(
38 | "Cache/0000000000000000/00/00/00/0000000000000000-0000000000000000.itc2",
39 | f);
40 | }
41 |
42 | @Test
43 | public void fileFromDefinitionWithNumbers()
44 | {
45 | ArtworkFile af = new ArtworkFile(
46 | ArtworkFile.Directory.Cache,
47 | new byte[]{0, 1, 2, 3, 4, 5, 6, 7},
48 | 1);
49 |
50 | String f = af.toString(
51 | new byte[]{8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF});
52 |
53 | assertEquals(
54 | "Cache/08090A0B0C0D0E0F/07/00/06/08090A0B0C0D0E0F-0001020304050607.itc",
55 | f);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/PlaylistRawItems.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2013 Lael Jones
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | import java.io.ByteArrayOutputStream;
22 | import java.util.ArrayList;
23 | import java.util.List;
24 |
25 | /**
26 | *
27 | * @author Lael
28 | */
29 | class PlaylistRawItems
30 | {
31 | public final int expectedItemCount;
32 | public long itemStartOffset;
33 | private final List itemIds = new ArrayList();
34 | private final List itemBytes = new ArrayList();
35 |
36 | /**
37 | *
38 | * @param expectedItemCount
39 | */
40 | public PlaylistRawItems(int expectedItemCount)
41 | {
42 | this.expectedItemCount = expectedItemCount;
43 | }
44 |
45 | public List getItemIds()
46 | {
47 | return itemIds;
48 | }
49 |
50 | public List getRawItems()
51 | {
52 | return itemBytes;
53 | }
54 |
55 | public void addItem(int key, ByteArrayOutputStream bo)
56 | {
57 | itemIds.add(Integer.valueOf(key));
58 | itemBytes.add(bo);
59 | }
60 |
61 | public int getExpectedItemCount()
62 | {
63 | return expectedItemCount;
64 | }
65 |
66 | public long getItemStartOffset()
67 | {
68 | return itemStartOffset;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/titl-core/src/test/java/org/kafsemo/titl/tools/TestMain.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl.tools;
20 |
21 | import static org.junit.Assert.fail;
22 |
23 | import java.io.IOException;
24 | import java.lang.reflect.InvocationTargetException;
25 | import java.util.Arrays;
26 |
27 | import org.junit.Test;
28 |
29 | public class TestMain
30 | {
31 | @Test(expected = IllegalArgumentException.class)
32 | public void exceptionWhenNoClassIsProvided() throws Exception
33 | {
34 | Main.main();
35 | }
36 |
37 | @Test(expected = ClassNotFoundException.class)
38 | public void unknownClassesAreNotFound() throws Exception
39 | {
40 | Main.main("UnknownClass");
41 | }
42 |
43 | @Test
44 | public void knownClassIsFound() throws Exception
45 | {
46 | Main.main("TestMain");
47 | }
48 |
49 | @Test(expected = IOException.class)
50 | public void correctArgumentsArePassedToMainMethod() throws Throwable
51 | {
52 | try {
53 | Main.main("TestMain", "arg1", "arg2");
54 | fail();
55 | } catch (InvocationTargetException ite) {
56 | throw ite.getCause();
57 | }
58 | }
59 |
60 | public static void main(String[] args) throws IOException
61 | {
62 | String[] expected = {"arg1", "arg2"};
63 |
64 | if (Arrays.equals(expected, args)) {
65 | throw new IOException("Expected args received");
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/art/ArtworkFile.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl.art;
20 |
21 | import java.io.File;
22 |
23 | import org.kafsemo.titl.Util;
24 |
25 | public class ArtworkFile
26 | {
27 | enum Directory {
28 | Cache,
29 | Download
30 | }
31 |
32 | final Directory dir;
33 | final byte[] id;
34 | final int version;
35 |
36 | public ArtworkFile(Directory dir, byte[] id, int version)
37 | {
38 | this.dir = dir;
39 | this.id = id;
40 | this.version = version;
41 | }
42 |
43 | public File getFile(File artworkDirectory, byte[] libraryPersistentId)
44 | {
45 | return new File(artworkDirectory, toString(libraryPersistentId));
46 | }
47 |
48 | public String toString(byte[] libraryPersistentId)
49 | {
50 | StringBuilder sb = new StringBuilder();
51 |
52 | sb.append(dir.name());
53 | sb.append('/');
54 |
55 | String libDir = Util.pidToString(libraryPersistentId);
56 |
57 | sb.append(libDir);
58 | sb.append('/');
59 | sb.append(String.format("%02d", id[7] & 0x0F));
60 | sb.append('/');
61 | sb.append(String.format("%02d", (id[7] >> 4) & 0x0F));
62 | sb.append('/');
63 | sb.append(String.format("%02d", id[6] & 0x0F));
64 |
65 | sb.append('/' + libDir + "-" + Util.pidToString(id));
66 |
67 | sb.append(".itc");
68 |
69 | if (version != 1) {
70 | sb.append(version);
71 | }
72 |
73 | return sb.toString();
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/titl-core/src/test/java/org/kafsemo/titl/TestDates.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | import java.util.Date;
22 |
23 | import org.junit.Test;
24 | import org.kafsemo.titl.Dates;
25 |
26 | import junit.framework.TestCase;
27 |
28 | public class TestDates extends TestCase
29 | {
30 | @Test
31 | public void testToUnsigned()
32 | {
33 | int a = -992945054;
34 |
35 | long res = a;
36 |
37 | res = 0x100000000L + a;
38 |
39 | res = (long) a & 0xFFFFFFFFL;
40 |
41 | assertEquals(3302022242L, res);
42 | }
43 |
44 | @Test
45 | public void testToDate()
46 | {
47 | long a = 3302022242L;
48 |
49 | Date d = Dates.fromMac(a);
50 |
51 | assertEquals("2008-08-19T19:24:02Z",
52 | Dates.toString(d));
53 | }
54 |
55 | @Test
56 | public void testToDate2()
57 | {
58 | long a = 3277369669L;
59 |
60 | Date d = Dates.fromMac(a);
61 |
62 | assertEquals("2007-11-08T11:27:49Z",
63 | Dates.toString(d));
64 | }
65 |
66 | @Test
67 | public void testToDate3()
68 | {
69 | long a = 3300033502L;
70 |
71 | Date d = Dates.fromMac(a);
72 |
73 | assertEquals("2008-07-27T18:58:22Z",
74 | Dates.toString(d));
75 | }
76 |
77 | @Test
78 | public void testFromLibraryFile()
79 | {
80 | int a = -988797720;
81 |
82 | Date d = Dates.fromMac(a);
83 |
84 | assertEquals("2008-10-06T19:26:16Z",
85 | Dates.toString(d));
86 | }
87 |
88 | @Test
89 | public void zeroBecomesNullDate()
90 | {
91 | int a = 0;
92 |
93 | Date d = Dates.fromMac(a);
94 | assertNull(d);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/UnknownHohmException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | /**
22 | * An unknown hohm type was encountered. This exception includes
23 | * the contents to give a clue to the data.
24 | */
25 | public class UnknownHohmException extends ItlException
26 | {
27 | private final int hohmType;
28 | private final byte[] contents;
29 |
30 | public UnknownHohmException(int hohmType, byte[] contents)
31 | {
32 | super(null);
33 | this.hohmType = hohmType;
34 | this.contents = contents;
35 | }
36 |
37 | @Override
38 | public String getMessage()
39 | {
40 | StringBuilder sb = new StringBuilder();
41 | sb.append("Unknown type: ");
42 | sb.append(hohmType);
43 | sb.append(String.format(" (0x%X)", hohmType));
44 |
45 | int len = Math.min(contents.length, 64);
46 |
47 | /* Hex */
48 | sb.append('\n');
49 | sb.append("Hex:");
50 | for(int i = 0; i < len; i++) {
51 | sb.append(' ');
52 | sb.append(String.format("0x%02X", contents[i] & 0xFF));
53 | }
54 |
55 | if (len < contents.length) {
56 | sb.append(" ...");
57 | }
58 |
59 | len = Math.min(contents.length, 96);
60 |
61 | /* ASCII */
62 | sb.append('\n');
63 | sb.append("ASCII: ");
64 | for (int i = 0; i < len; i++) {
65 | /* Only show printable ASCII characters */
66 | int c = contents[i] & 0xFF;
67 | if ((c >= 0x20) && (c <= 0x7E)) {
68 | sb.append((char) c);
69 | } else {
70 | sb.append('.');
71 | }
72 | }
73 |
74 | if (len < contents.length) {
75 | sb.append(" ...");
76 | }
77 |
78 | return sb.toString();
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/titl-core/src/test/java/org/kafsemo/titl/TestBase64.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | import static org.junit.Assert.assertEquals;
22 |
23 | import java.io.UnsupportedEncodingException;
24 |
25 | import org.junit.Test;
26 | import org.kafsemo.titl.Base64;
27 |
28 | public class TestBase64
29 | {
30 | @Test
31 | public void testDecodeEmpty()
32 | {
33 | byte[] ba = Base64.decode("");
34 | assertEquals(0, ba.length);
35 | }
36 |
37 | @Test
38 | public void testDecode() throws UnsupportedEncodingException
39 | {
40 | byte[] ba = Base64.decode("VGVzdA==");
41 | assertEquals("Test", new String(ba, "US-ASCII"));
42 | }
43 |
44 | @Test
45 | public void testDecodeWhitespaceStripped() throws UnsupportedEncodingException
46 | {
47 | byte[] ba = Base64.decode("VGV\nzdA==");
48 | assertEquals("Test", new String(ba, "US-ASCII"));
49 | }
50 |
51 | @Test
52 | public void testDecodeNoPadding() throws UnsupportedEncodingException
53 | {
54 | byte[] ba = Base64.decode("QUJD");
55 | assertEquals("ABC", new String(ba, "US-ASCII"));
56 | }
57 |
58 | @Test
59 | public void testDecodeOnePaddingChar() throws UnsupportedEncodingException
60 | {
61 | byte[] ba = Base64.decode("ISE=");
62 | assertEquals("!!", new String(ba, "US-ASCII"));
63 | }
64 |
65 | /**
66 | * Strings must only contain the defined Base64 characters.0
67 | */
68 | @Test(expected = IllegalArgumentException.class)
69 | public void testDecodeBadCharacter()
70 | {
71 | Base64.decode("!!!!");
72 | }
73 |
74 | /**
75 | * Strings must always be a multiple of four characters long.
76 | */
77 | @Test(expected = IllegalArgumentException.class)
78 | public void testDecodeBadStringLength()
79 | {
80 | Base64.decode("ISE");
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/Base64.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | import java.io.ByteArrayOutputStream;
22 |
23 | public class Base64
24 | {
25 | public static final String CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
26 | public static final char PAD = '=';
27 |
28 | private static final int val(char c)
29 | {
30 | int idx = CHARS.indexOf(c);
31 | if (idx < 0) {
32 | throw new IllegalArgumentException("Bad Base64 character: " + c);
33 | }
34 | return idx;
35 | }
36 |
37 | public static byte[] decode(String s)
38 | {
39 | s = s.replaceAll("\\s+", "");
40 |
41 | char[] ca = s.toCharArray();
42 |
43 | if (ca.length % 4 != 0)
44 | {
45 | throw new IllegalArgumentException();
46 | }
47 |
48 | ByteArrayOutputStream baos = new ByteArrayOutputStream((ca.length * 3 + 3) / 4);
49 |
50 | for (int i = 0; i < ca.length; i += 4) {
51 | if (ca[i + 2] == PAD) {
52 | int v1 = val(ca[i]),
53 | v2 = val(ca[i + 1]);
54 |
55 | byte b1 = (byte) ((v1 << 2) | ((v2 >> 4) & 0x03));
56 |
57 | baos.write(b1);
58 | } else if (ca[i + 3] == PAD) {
59 | int v1 = val(ca[i]),
60 | v2 = val(ca[i + 1]),
61 | v3 = val(ca[i + 2]);
62 |
63 | byte b1 = (byte) ((v1 << 2) | ((v2 >> 4) & 0x03));
64 | byte b2 = (byte) (((v2 << 4) & 0xF0) | ((v3 >> 2) & 0x0F));
65 |
66 | baos.write(b1);
67 | baos.write(b2);
68 | } else {
69 | int v1 = val(ca[i]),
70 | v2 = val(ca[i + 1]),
71 | v3 = val(ca[i + 2]),
72 | v4 = val(ca[i + 3]);
73 |
74 | byte b1 = (byte) ((v1 << 2) | ((v2 >> 4) & 0x03));
75 | byte b2 = (byte) (((v2 << 4) & 0xF0) | ((v3 >> 2) & 0x0F));
76 | byte b3 = (byte) (((v3 << 6) & 0x40) | v4);
77 |
78 | baos.write(b1);
79 | baos.write(b2);
80 | baos.write(b3);
81 | }
82 | }
83 |
84 | return baos.toByteArray();
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/titl-core/src/test/java/org/kafsemo/titl/TestUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | import static org.junit.Assert.assertEquals;
22 | import static org.junit.Assert.assertFalse;
23 | import static org.junit.Assert.assertTrue;
24 |
25 | import java.io.UnsupportedEncodingException;
26 |
27 | import org.junit.Test;
28 | import org.kafsemo.titl.Util;
29 |
30 | public class TestUtil
31 | {
32 | @Test
33 | public void testToString() throws UnsupportedEncodingException
34 | {
35 | int hdfmInt = 1751410285;
36 | assertEquals("hdfm", Util.toString(hdfmInt));
37 | }
38 |
39 | @Test
40 | public void testFromString() throws UnsupportedEncodingException
41 | {
42 | String s = "hdfm";
43 |
44 | assertEquals(1751410285, Util.fromString(s));
45 | }
46 |
47 | @Test
48 | public void isPlausibleIdentifier() throws UnsupportedEncodingException
49 | {
50 | assertTrue("Letters form a valid identifier", Util.isIdentifier("test"));
51 | assertTrue("Letters form a valid identifier", Util.isIdentifier("0123"));
52 | assertFalse("Non-alphanumeric characters are not a valid identifer",
53 | Util.isIdentifier("xĽ"));
54 |
55 | assertFalse("The empty string is not a valid identifier", Util.isIdentifier(""));
56 | }
57 |
58 | @Test
59 | public void testPidToString()
60 | {
61 | byte[] libraryPersistentId = {
62 | 0x30, 0x14, (byte) 0x96, (byte) 0xC1, 0x63, (byte) 0xC0, (byte) 0xDF, 0x40
63 | };
64 |
65 | assertEquals("301496C163C0DF40", Util.pidToString(libraryPersistentId));
66 | }
67 |
68 | @Test(expected = IllegalArgumentException.class)
69 | public void failsWithBadIdStringLength()
70 | {
71 | Util.fromString("");
72 | }
73 |
74 | @Test(expected = IllegalArgumentException.class)
75 | public void failsWithBadIdStringCharacters()
76 | {
77 | Util.fromString("€€€€");
78 | }
79 |
80 | @Test
81 | public void pathToUrl()
82 | {
83 | String p = "C:\\Users\\Joseph\\Music\\iTunes\\iTunes Music\\Podcasts\\CASH Music_ Kristin Hersh\\Fortune.mp3";
84 |
85 | String url = Util.toUrl(p);
86 |
87 | assertEquals("A Windows file path should be converted to a URL",
88 | "file://localhost/C:/Users/Joseph/Music/iTunes/iTunes%20Music/Podcasts/CASH%20Music_%20Kristin%20Hersh/Fortune.mp3",
89 | url);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/InputImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | import java.io.DataInput;
22 | import java.io.DataInputStream;
23 | import java.io.FilterInputStream;
24 | import java.io.IOException;
25 | import java.io.InputStream;
26 |
27 | public class InputImpl implements Input
28 | {
29 | private final InputStream in;
30 | private final DataInput di;
31 | private long position = 0;
32 |
33 | public InputImpl(InputStream in)
34 | {
35 | this.in = new CountingInputStream(in);
36 | this.di = new DataInputStream(this.in);
37 | }
38 |
39 | public long getPosition()
40 | {
41 | return position;
42 | }
43 |
44 | private class CountingInputStream extends FilterInputStream
45 | {
46 | public CountingInputStream(InputStream in)
47 | {
48 | super(in);
49 | }
50 |
51 | @Override
52 | public int read() throws IOException
53 | {
54 | int r = super.read();
55 | if (r >= 0) {
56 | position++;
57 | }
58 | return r;
59 | }
60 |
61 | @Override
62 | public int read(byte[] b, int off, int len) throws IOException
63 | {
64 | int count = super.read(b, off, len);
65 | if (count >= 0) {
66 | position += count;
67 | }
68 | return count;
69 | }
70 |
71 | @Override
72 | public long skip(long n) throws IOException
73 | {
74 | long count = super.skip(n);
75 | if (count >= 0) {
76 | position += count;
77 | }
78 | return count;
79 | }
80 | }
81 |
82 | @Override
83 | public int readUnsignedByte() throws IOException
84 | {
85 | return di.readUnsignedByte();
86 | }
87 |
88 | @Override
89 | public short readShort() throws IOException
90 | {
91 | return di.readShort();
92 | }
93 |
94 | @Override
95 | public int readInt() throws IOException
96 | {
97 | return di.readInt();
98 | }
99 |
100 | @Override
101 | public void readFully(byte[] b) throws IOException
102 | {
103 | di.readFully(b);
104 | }
105 |
106 | @Override
107 | public int skipBytes(int n) throws IOException
108 | {
109 | return di.skipBytes(n);
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/Util.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 | import java.io.IOException;
21 | import java.net.URI;
22 | import java.net.URISyntaxException;
23 | import java.util.regex.Pattern;
24 |
25 |
26 | public class Util
27 | {
28 | public static void assertEquals(String expected, String actual)
29 | throws IOException
30 | {
31 | if(!expected.equals(actual))
32 | {
33 | throw new IOException("Expected: " + expected + " but was: " + actual);
34 | }
35 | }
36 |
37 | public static String toString(int tag)
38 | {
39 | char[] ba = new char[4];
40 | for (int i = 0; i < 4; i++) {
41 | ba[i] = (char) (tag >> ((3 - i) * 8) & 0xff);
42 | }
43 |
44 | return new String(ba);
45 | }
46 |
47 | public static int fromString(String s) throws IllegalArgumentException
48 | {
49 | char[] ca = s.toCharArray();
50 | if (ca.length != 4) {
51 | throw new IllegalArgumentException();
52 | }
53 |
54 | int res = 0;
55 | for (int i = 0; i < 4; i++) {
56 | int c = ca[i];
57 | if (c > 0xff) {
58 | throw new IllegalArgumentException();
59 | }
60 |
61 | res |= (c << ((3 - i) * 8));
62 | }
63 |
64 | return res;
65 | }
66 |
67 | public static String pidToString(byte[] libraryPersistentId)
68 | {
69 | StringBuffer sb = new StringBuffer(libraryPersistentId.length * 2);
70 | for (byte b : libraryPersistentId) {
71 | sb.append(String.format("%02X", b & 0xFF));
72 | }
73 |
74 | return sb.toString();
75 | }
76 |
77 | /**
78 | * Converts a Windows path into a file: URL, as used by iTunes in its XML.
79 | *
80 | * @param p
81 | * @return
82 | */
83 | public static String toUrl(String p)
84 | {
85 | try {
86 | URI uri;
87 | uri = new URI("file", "localhost", '/' + p.replace('\\', '/'), null);
88 | return uri.toASCIIString();
89 | } catch (URISyntaxException use) {
90 | throw new RuntimeException(use);
91 | }
92 | }
93 |
94 | private static Pattern ID_PATTERN = Pattern.compile("[a-zA-Z0-9]+");
95 |
96 | public static boolean isIdentifier(String id)
97 | {
98 | return ID_PATTERN.matcher(id).matches();
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/titl-core/src/test/java/org/kafsemo/titl/tools/TestMoveMusic.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl.tools;
20 |
21 | import static org.junit.Assert.assertEquals;
22 | import static org.junit.Assert.assertFalse;
23 | import static org.junit.Assert.assertNull;
24 | import static org.junit.Assert.assertTrue;
25 |
26 | import org.junit.Test;
27 |
28 | public class TestMoveMusic
29 | {
30 | @Test
31 | public void enoughArguments()
32 | {
33 | assertNull("At least three arguments must be provided", MoveMusic.fromArgs(new String[0]));
34 | assertNull("At least three arguments must be provided", MoveMusic.fromArgs(new String[1]));
35 | assertNull("At least three arguments must be provided", MoveMusic.fromArgs(new String[2]));
36 | }
37 |
38 | @Test
39 | public void minimalArguments()
40 | {
41 | MoveMusic mm;
42 |
43 | mm = MoveMusic.fromArgs(new String[]{"lib", "a", "b"});
44 | assertEquals("lib", mm.getLibraryFilename());
45 | assertEquals("a", mm.getOrigDir());
46 | assertEquals("b", mm.getDestDir());
47 | assertFalse("Default is not to use URLs", mm.isUseUrls());
48 | }
49 |
50 | @Test
51 | public void useUrlsFlag()
52 | {
53 | MoveMusic mm;
54 |
55 | mm = MoveMusic.fromArgs(new String[]{"--use-urls", "lib", "a", "b"});
56 | assertEquals("lib", mm.getLibraryFilename());
57 | assertEquals("a", mm.getOrigDir());
58 | assertEquals("b", mm.getDestDir());
59 | assertTrue("Use URLs when requested", mm.isUseUrls());
60 | }
61 |
62 | @Test
63 | public void badArguments()
64 | {
65 | assertNull("A switch is not an acceptable argument",
66 | MoveMusic.fromArgs(new String[]{"--use-urls", "a"}));
67 |
68 | assertNull("Too many arguments is a problem",
69 | MoveMusic.fromArgs(new String[]{"a", "b", "c","d"}));
70 |
71 | assertNull("Too many arguments is a problem",
72 | MoveMusic.fromArgs(new String[]{"--use-urls", "a", "b", "c", "d"}));
73 |
74 | assertNull("An unknown switch is a problem",
75 | MoveMusic.fromArgs(new String[]{"--unknown", "a", "b"}));
76 | }
77 |
78 | @Test
79 | public void testConversion()
80 | {
81 | MoveMusic mm = new MoveMusic(null, "before-", "after-");
82 | assertEquals("xxx", mm.convert("xxx"));
83 | assertEquals("after-xx", mm.convert("before-xx"));
84 | assertEquals("after-xx", mm.convert("after-xx"));
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/titl-core/src/test/java/org/kafsemo/titl/TestHohm.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | import static org.junit.Assert.assertEquals;
22 |
23 | import java.io.ByteArrayInputStream;
24 | import java.io.IOException;
25 |
26 | import org.junit.Test;
27 |
28 | public class TestHohm
29 | {
30 | private static byte[] sampleUtf16Chunk = {
31 | 0x68, 0x6f, 0x68, 0x6d,
32 | 0x00, 0x00, 0x00, 0x18,
33 | 0x00, 0x00, 0x00, 0x3c,
34 | 0x00, 0x00, 0x00, 0x64,
35 | 0x00, 0x00, 0x00, 0x03,
36 | 0x00, 0x00, 0x00, 0x00,
37 | 0x00, 0x00, 0x00, 0x01,
38 | 0x00, 0x00, 0x00, 0x14,
39 | 0x00, 0x00, 0x00, 0x00,
40 | 0x00, 0x00, 0x00, 0x00,
41 | 0x00, 0x39, 0x00, 0x30,
42 | 0x20, 0x19, 0x00, 0x73,
43 | 0x00, 0x20, 0x00, 0x4d,
44 | 0x00, 0x75, 0x00, 0x73,
45 | 0x00, 0x69, 0x00, 0x63
46 | };
47 |
48 | private static byte[] sampleLatin1Chunk = {
49 | 0x68, 0x6f, 0x68, 0x6d,
50 | 0x00, 0x00, 0x00, 0x18,
51 | 0x00, 0x00, 0x00, 0x34,
52 | 0x00, 0x00, 0x00, 0x64,
53 | 0x00, 0x00, 0x00, 0x03,
54 | 0x00, 0x00, 0x00, 0x00,
55 | 0x00, 0x00, 0x00, 0x03,
56 | 0x00, 0x00, 0x00, 0x0c,
57 | 0x00, 0x00, 0x00, 0x00,
58 | 0x00, 0x00, 0x00, 0x00,
59 | 0x4d, 0x79, 0x20, 0x54,
60 | 0x6f, 0x70, 0x20, 0x52,
61 | 0x61, 0x74, 0x65, 0x64
62 | };
63 |
64 | @Test
65 | public void testHohmUtf16PlaylistTitle() throws IOException, ItlException
66 | {
67 | Input di = new InputImpl(new ByteArrayInputStream(sampleUtf16Chunk));
68 |
69 | String type = Util.toString(di.readInt());
70 | assertEquals("hohm", type);
71 |
72 | int length = di.readInt();
73 | assertEquals(24, length);
74 |
75 | assertEquals(60, di.readInt());
76 | assertEquals(0x64, di.readInt());
77 |
78 | String val = ParseLibrary.readGenericHohm(di);
79 |
80 | assertEquals("90\u2019s Music", val);
81 | }
82 |
83 | @Test
84 | public void testHohmLatin1PlaylistTitle() throws IOException, ItlException
85 | {
86 | Input di = new InputImpl(new ByteArrayInputStream(sampleLatin1Chunk));
87 |
88 | String type = Util.toString(di.readInt());
89 | assertEquals("hohm", type);
90 |
91 | int length = di.readInt();
92 | assertEquals(24, length);
93 |
94 | assertEquals(52, di.readInt());
95 | assertEquals(0x64, di.readInt());
96 |
97 | String val = ParseLibrary.readGenericHohm(di);
98 |
99 | assertEquals("My Top Rated", val);
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/titl-core/src/main/java/org/kafsemo/titl/Library.java:
--------------------------------------------------------------------------------
1 | /*
2 | * titl - Tools for iTunes Libraries
3 | * Copyright (C) 2008-2011 Joseph Walton
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Lesser General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Lesser General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Lesser General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package org.kafsemo.titl;
20 |
21 | import java.util.ArrayList;
22 | import java.util.Collection;
23 | import java.util.Collections;
24 |
25 | /**
26 | * A high-level view of a library, including all the data extracted.
27 | */
28 | public class Library
29 | {
30 | final Hdfm hdr;
31 | private final String path;
32 | private final Collection playlists;
33 | private final Collection podcasts;
34 | private final Collection