Smart Playlists

## Smart Playlists Smart Playlists — Data structure to represent an iPod smart playlist |

## Synopsis

                        Itdb_SPLPref;
                        Itdb_SPLRule;
                        Itdb_SPLRules;
    enum                ItdbLimitSort;
    enum                ItdbLimitType;
    enum                ItdbSPLAction;
    enum                ItdbSPLActionLast;
    enum                ItdbSPLActionType;
    enum                ItdbSPLField;
    enum                ItdbSPLFieldType;
    enum                ItdbSPLMatch;
    #define             ITDB_SPL_DATE_IDENTIFIER
    #define             ITDB_SPL_STRING_MAXLEN
    ItdbSPLFieldType    itdb_splr_get_field_type            (const Itdb_SPLRule *splr);
    ItdbSPLActionType   itdb_splr_get_action_type           (const Itdb_SPLRule *splr);
    void                itdb_splr_validate                  (Itdb_SPLRule *splr);
    void                itdb_splr_remove                    (Itdb_Playlist *pl,
                                                             Itdb_SPLRule *splr);
    Itdb_SPLRule*       itdb_splr_new                       (void);
    void                itdb_splr_add                       (Itdb_Playlist *pl,
                                                             Itdb_SPLRule *splr,
                                                             gint pos);
    Itdb_SPLRule*       itdb_splr_add_new                   (Itdb_Playlist *pl,
                                                             gint pos);
    void                itdb_spl_copy_rules                 (Itdb_Playlist *dest,
                                                             Itdb_Playlist *src);
    gboolean            itdb_splr_eval                      (Itdb_SPLRule *splr,
                                                             Itdb_Track *track);
    void                itdb_spl_update                     (Itdb_Playlist *spl);
    void                itdb_spl_update_all                 (Itdb_iTunesDB *itdb);
    void                itdb_spl_update_live                (Itdb_iTunesDB *itdb);

## Description

These functions and structures are for dealing with smart playlists.

## Details

### Itdb_SPLPref

    typedef struct {
        guint8  liveupdate;        /* "live Updating" check box */
        guint8  checkrules;        /* "Match X of the following
    				  conditions" check box */
        guint8  checklimits;       /* "Limit To..." check box */
        guint32 limittype;         /* See types defined above */
        guint32 limitsort;         /* See types defined above */
        guint32 limitvalue;        /* The value typed next to "Limit
    				  type" */
        guint8  matchcheckedonly;  /* "Match only checked songs" check box */
        /* reserved for future use */
        gint32 reserved_int1;
        gint32 reserved_int2;
        gpointer reserved1;
        gpointer reserved2;
    } Itdb_SPLPref;

### Itdb_SPLRule

    typedef struct {
        guint32 field;
        guint32 action;
        gchar *string;             /* data in UTF8  */
        /* from and to are pretty stupid.. if it's a date type of field,
           then
             value = 0x2dae2dae2dae2dae,
             date = some number, like 2 or -2
             units = unit in seconds, like 604800 = a week
           but if this is actually some kind of integer comparison, like
           rating = 60 (3 stars)
             value = the value we care about
    	 date = 0
    	 units = 1 */
        guint64 fromvalue;
        gint64 fromdate;
        guint64 fromunits;
        guint64 tovalue;
        gint64 todate;
        guint64 tounits;
        guint32 unk052;
        guint32 unk056;
        guint32 unk060;
        guint32 unk064;
        guint32 unk068;
        /* reserved for future use */
        gint32 reserved_int1;
        gint32 reserved_int2;
        gpointer reserved1;
        gpointer reserved2;
    } Itdb_SPLRule;

### Itdb_SPLRules

    typedef struct {
        guint32 unk004;
        guint32 match_operator;  /* "All" (logical AND): Itdb_SPLMATCH_AND,
    				"Any" (logical OR): Itdb_SPLMATCH_OR */
        GList *rules;
        /* reserved for future use */
        gint32 reserved_int1;
        gint32 reserved_int2;
        gpointer reserved1;
        gpointer reserved2;
    } Itdb_SPLRules;

### enum ItdbLimitSort

    typedef enum {
        ITDB_LIMITSORT_RANDOM = 0x02,
        ITDB_LIMITSORT_SONG_NAME = 0x03,
        ITDB_LIMITSORT_ALBUM = 0x04,
        ITDB_LIMITSORT_ARTIST = 0x05,
        ITDB_LIMITSORT_GENRE = 0x07,
        ITDB_LIMITSORT_MOST_RECENTLY_ADDED = 0x10,
        ITDB_LIMITSORT_LEAST_RECENTLY_ADDED = 0x80000010, /* See note above */
        ITDB_LIMITSORT_MOST_OFTEN_PLAYED = 0x14,
        ITDB_LIMITSORT_LEAST_OFTEN_PLAYED = 0x80000014,   /* See note above */
        ITDB_LIMITSORT_MOST_RECENTLY_PLAYED = 0x15,
        ITDB_LIMITSORT_LEAST_RECENTLY_PLAYED = 0x80000015,/* See note above */
        ITDB_LIMITSORT_HIGHEST_RATING = 0x17,
        ITDB_LIMITSORT_LOWEST_RATING = 0x80000017,        /* See note above */
    } ItdbLimitSort;

### enum ItdbLimitType

    typedef enum {
        ITDB_LIMITTYPE_MINUTES = 0x01,
        ITDB_LIMITTYPE_MB      = 0x02,
        ITDB_LIMITTYPE_SONGS   = 0x03,
        ITDB_LIMITTYPE_HOURS   = 0x04,
        ITDB_LIMITTYPE_GB      = 0x05
    } ItdbLimitType;

### enum ItdbSPLAction

    typedef enum {
        ITDB_SPLACTION_IS_INT = 0x00000001,          /* "Is Set" in iTunes */
        ITDB_SPLACTION_IS_GREATER_THAN = 0x00000010, /* "Is After" in iTunes */
        ITDB_SPLACTION_IS_LESS_THAN = 0x00000040,    /* "Is Before" in iTunes */
        ITDB_SPLACTION_IS_IN_THE_RANGE = 0x00000100,
        ITDB_SPLACTION_IS_IN_THE_LAST = 0x00000200,
        ITDB_SPLACTION_BINARY_AND = 0x00000400,

        ITDB_SPLACTION_IS_STRING = 0x01000001,
        ITDB_SPLACTION_CONTAINS = 0x01000002,
        ITDB_SPLACTION_STARTS_WITH = 0x01000004,
        ITDB_SPLACTION_ENDS_WITH = 0x01000008,

        ITDB_SPLACTION_IS_NOT_INT = 0x02000001,     /* "Is Not Set" in iTunes */

        /* Note: Not available in iTunes 4.5 (untested on iPod) */
        ITDB_SPLACTION_IS_NOT_GREATER_THAN = 0x02000010,
        /* Note: Not available in iTunes 4.5 (untested on iPod) */
        ITDB_SPLACTION_IS_NOT_LESS_THAN = 0x02000040,
        /* Note: Not available in iTunes 4.5 (seems to work on iPod) */
        ITDB_SPLACTION_IS_NOT_IN_THE_RANGE = 0x02000100,

        ITDB_SPLACTION_IS_NOT_IN_THE_LAST = 0x02000200,
        ITDB_SPLACTION_IS_NOT = 0x03000001,
        ITDB_SPLACTION_DOES_NOT_CONTAIN = 0x03000002,

        /* Note: Not available in iTunes 4.5 (seems to work on iPod) */
        ITDB_SPLACTION_DOES_NOT_START_WITH = 0x03000004,
        /* Note: Not available in iTunes 4.5 (seems to work on iPod) */
        ITDB_SPLACTION_DOES_NOT_END_WITH = 0x03000008,
    } ItdbSPLAction;

### enum ItdbSPLActionLast

    typedef enum {
        ITDB_SPLACTION_LAST_DAYS_VALUE = 86400,    /* nr of secs in 24 hours */
        ITDB_SPLACTION_LAST_WEEKS_VALUE = 604800,  /* nr of secs in 7 days   */
        ITDB_SPLACTION_LAST_MONTHS_VALUE = 2628000,/* nr of secs in 30.4167
    					     days ~= 1 month */
    } ItdbSPLActionLast;

### enum ItdbSPLActionType

    typedef enum
    {
        ITDB_SPLAT_STRING = 1,
        ITDB_SPLAT_INT,
        ITDB_SPLAT_DATE,
        ITDB_SPLAT_RANGE_INT,
        ITDB_SPLAT_RANGE_DATE,
        ITDB_SPLAT_INTHELAST,
        ITDB_SPLAT_PLAYLIST,
        ITDB_SPLAT_NONE,
        ITDB_SPLAT_INVALID,
        ITDB_SPLAT_UNKNOWN,
        ITDB_SPLAT_BINARY_AND
    } ItdbSPLActionType;

### enum ItdbSPLField

    typedef enum {
        ITDB_SPLFIELD_SONG_NAME = 0x02,    /* String */
        ITDB_SPLFIELD_ALBUM = 0x03,        /* String */
        ITDB_SPLFIELD_ARTIST = 0x04,       /* String */
        ITDB_SPLFIELD_BITRATE = 0x05,      /* Int (e.g. from/to = 128) */
        ITDB_SPLFIELD_SAMPLE_RATE = 0x06,  /* Int  (e.g. from/to = 44100) */
        ITDB_SPLFIELD_YEAR = 0x07,         /* Int  (e.g. from/to = 2004) */
        ITDB_SPLFIELD_GENRE = 0x08,        /* String */
        ITDB_SPLFIELD_KIND = 0x09,         /* String */
        ITDB_SPLFIELD_DATE_MODIFIED = 0x0a,/* Int (e.g. from/to = bcf93280 ==
    				     is before 6/19/2004)*/
        ITDB_SPLFIELD_TRACKNUMBER = 0x0b,  /* Int (e.g. from = 1, to = 2) */
        ITDB_SPLFIELD_SIZE = 0x0c,         /* Int (e.g. from/to = 0x00600000
    				     for 6MB) */
        ITDB_SPLFIELD_TIME = 0x0d,         /* Int (e.g. from/to = 83999 for
    				     1:23/83 seconds) */
        ITDB_SPLFIELD_COMMENT = 0x0e,      /* String */
        ITDB_SPLFIELD_DATE_ADDED = 0x10,   /* Int (e.g. from/to = bcfa83ff ==
    				     is after 6/19/2004) */
        ITDB_SPLFIELD_COMPOSER = 0x12,     /* String */
        ITDB_SPLFIELD_PLAYCOUNT = 0x16,    /* Int  (e.g. from/to = 1) */
        ITDB_SPLFIELD_LAST_PLAYED = 0x17,  /* Int/ (e.g. from = bcfa83ff (6/19/2004)
    				     to = 0xbcfbd57f (6/20/2004)) */
        ITDB_SPLFIELD_DISC_NUMBER = 0x18,  /* Int  (e.g. from/to = 1) */
        ITDB_SPLFIELD_RATING = 0x19,       /* Int/Stars Rating (e.g. from/to =
                                         60 (3 stars)) */
        ITDB_SPLFIELD_COMPILATION = 0x1f,  /* Int (e.g. is set ->
    				     ITDB_SPLACTION_IS_INT/from=1,
    				     is not set ->
    				     ITDB_SPLACTION_IS_NOT_INT/from=1) */
        ITDB_SPLFIELD_BPM = 0x23,          /* Int  (e.g. from/to = 60) */
        ITDB_SPLFIELD_GROUPING = 0x27,     /* String */
        ITDB_SPLFIELD_PLAYLIST = 0x28,     /* FIXME - Unknown...not parsed
    				     correctly...from/to = 0xb6fbad5f
    				     for "Purchased Music".  Extra
    				     data after "to"... */
        ITDB_SPLFIELD_VIDEO_KIND = 0x3c,   /* Logic Int */
        ITDB_SPLFIELD_TVSHOW = 0x3e,       /* String */
        ITDB_SPLFIELD_SEASON_NR = 0x3f,    /* Int */
        ITDB_SPLFIELD_SKIPCOUNT = 0x44,    /* Int */
        ITDB_SPLFIELD_LAST_SKIPPED = 0x45, /* Int */
        ITDB_SPLFIELD_ALBUMARTIST = 0x47   /* String */
    } ItdbSPLField;

### enum ItdbSPLFieldType

    typedef enum
    {
        ITDB_SPLFT_STRING = 1,
        ITDB_SPLFT_INT,
        ITDB_SPLFT_BOOLEAN,
        ITDB_SPLFT_DATE,
        ITDB_SPLFT_PLAYLIST,
        ITDB_SPLFT_UNKNOWN,
        ITDB_SPLFT_BINARY_AND
    } ItdbSPLFieldType;

### enum ItdbSPLMatch

    typedef enum { /* types for match_operator */
        ITDB_SPLMATCH_AND = 0, /* AND rule - all of the rules must be true in
    			 order for the combined rule to be applied */
        ITDB_SPLMATCH_OR = 1   /* OR rule */
    } ItdbSPLMatch;

### ITDB_SPL_DATE_IDENTIFIER

    #define ITDB_SPL_DATE_IDENTIFIER (G_GINT64_CONSTANT (0x2dae2dae2dae2daeU))

### ITDB_SPL_STRING_MAXLEN

    #define ITDB_SPL_STRING_MAXLEN 255

### itdb_splr_get_field_type ()

    ItdbSPLFieldType    itdb_splr_get_field_type            (const Itdb_SPLRule *splr);

Gets the type of the field of the `splr` rule

`splr` : | an Itdb_SPLRule
Returns : | an Itdb_SPLFieldType corresponding to `splr` field type (string, int, date, ...)

### itdb_splr_get_action_type ()

    ItdbSPLActionType   itdb_splr_get_action_type           (const Itdb_SPLRule *splr);

Gets the type of the action associated with `splr`.

`splr` : | an Itdb_SPLRule
Returns : | type (range, date, string...) of the action field

### itdb_splr_validate ()

    void                itdb_splr_validate                  (Itdb_SPLRule *splr);

Validates a rule

`splr` : | an Itdb_SPLRule

### itdb_splr_remove ()

    void                itdb_splr_remove                    (Itdb_Playlist *pl,
                                                             Itdb_SPLRule *splr);

Removes the smart playlist rule `splr` from playlist `pl`. The memory used by `splr` is freed.

`pl` : | an Itdb_Playlist
`splr` : | an Itdb_SPLRule

### itdb_splr_new ()

    Itdb_SPLRule*       itdb_splr_new                       (void);

Creates a new default smart rule

Returns : | a new Itdb_SPLRule that must be freed with `itdb_splr_free()` when no longer needed

### itdb_splr_add ()

    void                itdb_splr_add                       (Itdb_Playlist *pl,
                                                             Itdb_SPLRule *splr,
                                                             gint pos);

Adds the smart rule `splr` to `pl` at position `pos`. If `pos` is -1, `splr` gets appended to the end. After this call, `splr` memory is managed by `pl`, so you no longer need to call `itdb_splr_free()`

`pl` : | an Itdb_Playlist
`splr` : | an Itdb_SPLRule
`pos` : | position of the rule

### itdb_splr_add_new ()

    Itdb_SPLRule*       itdb_splr_add_new                   (Itdb_Playlist *pl,
                                                             gint pos);

Creates a new smart rule and inserts it at position `pos` in `pl`. If `pos` is -1, the new rule gets appended to the end.

`pl` : | an Itdb_Playlist
`pos` : | position to insert the rule at
Returns : | pointer to the newly created Itdb_SPLRule. Its memory is handled by `pl` though, so you don't need to explicitly call `itdb_splr_free()` on it

### itdb_spl_copy_rules ()

    void                itdb_spl_copy_rules                 (Itdb_Playlist *dest,
                                                             Itdb_Playlist *src);

Copy all relevant information for smart playlist from playlist `src` to playlist `dest`. If `dest` is already a smart playlist, the existing data is overwritten/deleted.

`dest` : | destination Itdb_Playlist
`src` : | source Itdb_Playlist

### itdb_splr_eval ()

    gboolean            itdb_splr_eval                      (Itdb_SPLRule *splr,
                                                             Itdb_Track *track);

Evaluates `splr`'s truth against `track`. track->itdb must be set.

`splr` : | an Itdb_SPLRule
`track` : | an Itdb_Track
Returns : | TRUE if `track` matches `splr`, FALSE otherwise.

### itdb_spl_update ()

    void                itdb_spl_update                     (Itdb_Playlist *spl);

Updates the content of the smart playlist `spl` (meant to be called if the tracks stored in the Itdb_iTunesDB associated with `spl` have changed somehow and you want spl->members to be accurate with regards to those changes. Does nothing if `spl` isn't a smart playlist.

`spl` : | an Itdb_Playlist

### itdb_spl_update_all ()

    void                itdb_spl_update_all                 (Itdb_iTunesDB *itdb);

Updates all smart playlists contained in `itdb`

`itdb` : | an Itdb_iTunesDB

### itdb_spl_update_live ()

    void                itdb_spl_update_live                (Itdb_iTunesDB *itdb);

Updates all 'live' smart playlists contained in `itdb`, ie those which have the 'live updating' flag set

`itdb` : | an Itdb_iTunesDB

## See Also

Playlists