## iPod database reading/writing

iPod database reading/writing — Functions to read, write, and create an iPod database

## Synopsis

                        Itdb_iTunesDB;
    enum                ItdbFileError;
    Itdb_iTunesDB *     itdb_new                            (void);
    void                itdb_free                           (Itdb_iTunesDB *itdb);
    Itdb_iTunesDB *     itdb_parse                          (const gchar *mp,
                                                             GError **error);
    gboolean            itdb_write                          (Itdb_iTunesDB *itdb,
                                                             GError **error);
    void                itdb_set_mountpoint                 (Itdb_iTunesDB *itdb,
                                                             const gchar *mp);
    const gchar *       itdb_get_mountpoint                 (Itdb_iTunesDB *itdb);
    gboolean            itdb_init_ipod                      (const gchar *mountpoint,
                                                             const gchar *model_number,
                                                             const gchar *ipod_name,
                                                             GError **error);
    guint32             itdb_tracks_number                  (Itdb_iTunesDB *itdb);
    guint32             itdb_tracks_number_nontransferred   (Itdb_iTunesDB *itdb);
    guint32             itdb_playlists_number               (Itdb_iTunesDB *itdb);
    void                (*ItdbUserDataDestroyFunc)          (gpointer userdata);
    gpointer            (*ItdbUserDataDuplicateFunc)        (gpointer userdata);

## Description

These functions are for reading, writing, creating, and deleting an iPod database and getting the total number of tracks and playlists.

Overview of using an iPod database:

`itdb_parse()`: read the iTunesDB and ArtworkDB

`itdb_write()`: write the iTunesDB and ArtworkDB

`itdb_parse()` will return a Itdb_iTunesDB structure with GLists containing all tracks the playlists in the database. Each track is represented by an Itdb_Track. Each playlist is represented by an Itdb_Playlist. See the Tracks and Playlists sections for details on tracks and playlists, respectively.

Each Itdb_Playlist has a GList called `members` which contains all of the tracks in the playlist. Tracks referenced in a playlist must also be present in the `tracks` GList of the Itdb_iTunesDB.

The iPod must contain one master playlist (MPL) containing all tracks accessible on the iPod through the Music->Tracks/Albums/Artists/etc. menu. In addition to the MPL there can be a number of normal playlists accessible through the Music->Playlists menu on the iPod. Tracks that are a member of one of these normal playlists must also be a member of the MPL.

The Podcasts playlist is just another playlist with some internal flags set differently. Tracks in the Podcasts playlist are not normally members of the MPL (so on the iPod they will only show up under the Podcasts menu). All tracks referenced must be in the `tracks` GList of the Itdb_iTunesDB, however.

Each track may have a thumbnail associated with it. You can retrieve a GdkPixmap of the thumbnail using `itdb_artwork_get_pixbuf()`. A thumbnail can be added with `itdb_track_set_thumbnails()`. A thumbnail can be removed with `itdb_track_remove_thumbnails()`. Please see the Artwork section for more details on artwork related functions and structures.

### Note

Be aware that iTunes additionally stores the artwork as tags in the original music file. That's also from where the data is read when artwork is displayed in iTunes, and there can be more than one piece of artwork. libgpod does not store the artwork as tags in the original music file. As a consequence, if iTunes attempts to access the artwork, it will find none, and remove libgpod's artwork. Luckily, iTunes will only attempt to access the artwork if you select a track in iTunes. To work around this, gtkpod keeps a list of the original filename of all artwork and silently adds the thumbnails if they were 'lost'. Your application might want to do something similar, or you can supply patches for (optionally!) adding tags to the original music files.

The Itdb_iTunesDB, Itdb_Playlist and Itdb_Track structures each have `userdata` and `usertype` fields that can be used by the application to store additional application-specific data. If `userdata` is a pointer to an external structure, you can supply a ItdbUserDataDuplicateFunc and a ItdbUserDataDestroyFunc so that this data can be duplicated or freed automatically with a call to the library `_duplicate()`/`_free()` functions.

## Details

### Itdb_iTunesDB

    typedef struct {
        GList *tracks;
        GList *playlists;
        gchar *filename;
        Itdb_Device *device;
        guint32 version;
        guint64 id;
        gint32 tzoffset;
        /* reserved for future use */
        gint32 reserved_int2;
        Itdb_iTunesDB_Private *priv;
        gpointer reserved2;
        /* below is for use by application */
        guint64 usertype;
        gpointer userdata;
        /* functions called to duplicate/free userdata */
        ItdbUserDataDuplicateFunc userdata_duplicate;
        ItdbUserDataDestroyFunc userdata_destroy;
    } Itdb_iTunesDB;

Structure representing an iTunes database

GList *`tracks`; | A list of tracks in the database (Itdb_Track)
GList *`playlists`; | A list of playlists in the database (Itdb_Playlist)
gchar *`filename`; | The filename of the iTunesDB
Itdb_Device *`device`; | iPod device info (Itdb_Device)
guint32 `version`; | The version number of the iTunesDB
guint64 `id`; | A 64 bit id value for the iTunesDB
gint32 `tzoffset`; |
gint32 `reserved_int2`; | Reserved for future use
Itdb_iTunesDB_Private *`priv`; |
gpointer `reserved2`; | Reserved for future use
guint64 `usertype`; | For use by application
gpointer `userdata`; | For use by application
ItdbUserDataDuplicateFunc `userdata_duplicate`; | A function to duplicate userdata
ItdbUserDataDestroyFunc `userdata_destroy`; | A function to free userdata

### enum ItdbFileError

    typedef enum
    {
        ITDB_FILE_ERROR_SEEK,
        ITDB_FILE_ERROR_CORRUPT,
        ITDB_FILE_ERROR_NOTFOUND,
        ITDB_FILE_ERROR_RENAME,
        ITDB_FILE_ERROR_ITDB_CORRUPT
    } ItdbFileError;

Error codes for iTunesDB file

`ITDB_FILE_ERROR_SEEK` | file corrupt: illegal seek occured
`ITDB_FILE_ERROR_CORRUPT` | file corrupt
`ITDB_FILE_ERROR_NOTFOUND` | file not found
`ITDB_FILE_ERROR_RENAME` | file could not be renamed
`ITDB_FILE_ERROR_ITDB_CORRUPT` | iTunesDB in memory corrupt

### itdb_new ()

    Itdb_iTunesDB *     itdb_new                            (void);

Creates a new Itdb_iTunesDB with the unknowns filled in to reasonable values.

Returns : | a newly created Itdb_iTunesDB to be freed with `itdb_free()` when it's no longer needed

### itdb_free ()

    void                itdb_free                           (Itdb_iTunesDB *itdb);

Free the memory taken by `itdb`.

`itdb` : | an Itdb_iTunesDB

### itdb_parse ()

    Itdb_iTunesDB *     itdb_parse                          (const gchar *mp,
                                                             GError **error);

Parse the Itdb_iTunesDB of the iPod located at `mp`

`mp` : | mount point of the iPod (eg "/mnt/ipod") in local encoding
`error` : | return location for a GError or NULL
Returns : | a newly allocated Itdb_iTunesDB struct holding the tracks and the playlists present on the iPod at `mp`, NULL if `mp` isn't an iPod mount point. If non-NULL, the Itdb_iTunesDB is to be freed with `itdb_free()` when it's no longer needed

### itdb_write ()

    gboolean            itdb_write                          (Itdb_iTunesDB *itdb,
                                                             GError **error);

Write out an iTunesDB. It reassigns unique IDs to all tracks. An existing "Play Counts" file is renamed to "Play Counts.bak" if the export was successful. An existing "OTGPlaylistInfo" file is removed if the export was successful.

`itdb` : | the Itdb_iTunesDB to write to disk
`error` : | return location for a GError or NULL
Returns : | TRUE on success, FALSE on error, in which case `error` is set accordingly.

### itdb_set_mountpoint ()

    void                itdb_set_mountpoint                 (Itdb_iTunesDB *itdb,
                                                             const gchar *mp);

Sets the mountpoint of `itdb`. Always use this function to set the mountpoint of an Itdb_iTunesDB as it will reset the number of available /iPod_Control/Music/F.. dirs. It doesn't attempt to parse an iPod database that may be present on the iPod at `mp`.

### Note

Calling this function removes the artwork in the Itdb_iTunesDB database using this Itdb_Device which was read from the iPod.

.

`itdb` : | an Itdb_iTunesDB
`mp` : | new mount point

Since 0.1.3

### itdb_get_mountpoint ()

    const gchar *       itdb_get_mountpoint                 (Itdb_iTunesDB *itdb);

Retrieve a reference to the mountpoint of `itdb`

`itdb` : | an Itdb_iTunesDB
Returns : | the `itdb` mountpoint, this string shouldn't be freed nor modified

Since 0.4.0

### itdb_init_ipod ()

    gboolean            itdb_init_ipod                      (const gchar *mountpoint,
                                                             const gchar *model_number,
                                                             const gchar *ipod_name,
                                                             GError **error);

Initialise an iPod device from scratch. The function attempts to create a blank database, complete with master playlist and device information as well as the directory structure required for the type of iPod. `model_number` is used to tell libgpod about the exact iPod model, which is needed for proper artwork writing. `model_number` can be found from the table returned by itdb_device_get_ipod_info_table (for example). On recent distros with iPods released in the last few years (starting with the iPod Color), it should be fine to pass in a NULL `model_number` while still getting artwork writing.

`mountpoint` : | the iPod mountpoint
`model_number` : | the iPod model number, can be NULL
`ipod_name` : | the name to give to the iPod. Will be displayed in gtkpod or itunes
`error` : | return location for a GError or NULL
Returns : | TRUE when successful, FALSE if a failure has occurred.

Since 0.4.0

### itdb_tracks_number ()

    guint32             itdb_tracks_number                  (Itdb_iTunesDB *itdb);

Counts the number of tracks stored in `itdb`

`itdb` : | an Itdb_iTunesDB
Returns : | the number of tracks in `itdb`

### itdb_tracks_number_nontransferred ()

    guint32             itdb_tracks_number_nontransferred   (Itdb_iTunesDB *itdb);

Counts the number of non-transferred tracks in `itdb`

`itdb` : | an Itdb_iTunesDB
Returns : | the number of tracks in `itdb` that haven't been transferred to the iPod yet (ie the number of Itdb_Track in which the transferred field is false)

### itdb_playlists_number ()

    guint32             itdb_playlists_number               (Itdb_iTunesDB *itdb);

Counts the number of playlists stored in `itdb`

`itdb` : | an Itdb_iTunesDB
Returns : | the number of playlists in `itdb` (including the master playlist)

### ItdbUserDataDestroyFunc ()

    void                (*ItdbUserDataDestroyFunc)          (gpointer userdata);

Function called to free userdata

`userdata` : | A gpointer to user data

### ItdbUserDataDuplicateFunc ()

    gpointer            (*ItdbUserDataDuplicateFunc)        (gpointer userdata);

Function called to duplicate userdata

`userdata` : | A gpointer to user data
Returns : | A gpointer