Mac-iPod-GNUpod

 view release on metacpan or  search on metacpan

GNUpod.pm  view on Meta::CPAN

    return $rv;
}

# Write the iTunes Db
#
# This code adapted from the mktunes.pl script, copyright (C) 2002-2003 Adrian
# Ulrich.
sub write_itunes {
    my $self = shift;

    require Mac::iPod::GNUpod::iTunesDBwrite or die;
 
    # Undocumented, used only for debugging
    my %opt = @_;
    $opt{name} = 'GNUpod' unless $opt{name};

    my ($num, %data, %length, %ids);
    my @newfiles = (undef); # Will become $self->{files} at end

    # Create mhits and mhods for all files
    for (@{$self->{files}}) {
        next if not $_ or not keys %$_;
        # iTunes ID and GNUpod ID are NOT necessarily the same!  So we build a
        # hash of GNUpod => iTunes ids for translating playlists
        $ids{$_->{id}} = ++$num;
        $_->{id} = $num;
        push @newfiles, $_;

        $data{mhit} .= Mac::iPod::GNUpod::iTunesDBwrite::render_mhit($_, $num);
    }
    $length{mhit} = length($data{mhit});

    # Here, after remaking all files, we remake our indexes and playlists
    $self->_remake(\@newfiles, \%ids);

    # Create header for mhits
    $data{mhlt} = Mac::iPod::GNUpod::iTunesDBwrite::mk_mhlt({ songs => $num });
    $length{mhlt} = length($data{mhlt});

    # Create header for the mhlt
    $data{mhsd_1} = Mac::iPod::GNUpod::iTunesDBwrite::mk_mhsd({
        size => $length{mhit} + $length{mhlt},
        type => 1
    });
    $length{mhsd_1} = length($data{mhsd_1});

    # Create the master playlist
    ($data{playlist}, $num) = Mac::iPod::GNUpod::iTunesDBwrite::r_mpl(
        name => $opt{name},
        ids => [ 1 .. $num ],
        type => 1,
        curid => $num
    );

    # Create child playlists
    for my $plname (@{$self->{plorder}}) {
        my %common = ( name => $plname, type => 0, curid => $num );
        if (my $spl = $self->get_spl($plname)) {
            (my $dat, $num) = Mac::iPod::GNUpod::iTunesDBwrite::r_mpl(
                %common, 
                splprefs => $spl->{pref},
                spldata => $spl->{data}
            );
            $data{playlist} .= $dat;
        }
        else {
            (my $dat, $num) = Mac::iPod::GNUpod::iTunesDBwrite::r_mpl(
                %common, 
                ids => [ $self->render_pl($plname) ]
            );
            $data{playlist} .= $dat;
        }
    }
    $data{playlist} = Mac::iPod::GNUpod::iTunesDBwrite::mk_mhlp({ playlists => scalar @{$self->{plorder}} + 1  }) . $data{playlist};
    $length{playlist} = length($data{playlist});

    # Make pl headers
    $data{mhsd_2} = Mac::iPod::GNUpod::iTunesDBwrite::mk_mhsd({ size => $length{playlist}, type => 2 });
    $length{mhsd_2} = length($data{mhsd_2});

    # Calculate total file length
    my $totlength = 0;
    $totlength += $_ for values %length;

    # Make master header
    $data{mhbd} = Mac::iPod::GNUpod::iTunesDBwrite::mk_mhbd({ size => $totlength });

    # Debug me!
    if ($opt{dump}) {
        use Data::Dumper;
        open DUMP, '>', $opt{dump} or croak "Couldn't open dump file: $!";
        print DUMP Dumper(\%data);
        close DUMP;
    }

    # Write it all
    open IT, '>', $self->{itunes_db} or croak "Couldn't write iTunes DB: $!";
    binmode IT;
    for ('mhbd', 'mhsd_1', 'mhlt', 'mhit', 'mhsd_2', 'playlist') {
        no warnings 'uninitialized'; # In case one of these is empty
        print IT $data{$_};
    }
    close IT;
}

sub _remake {
    my ($self, $newfiles, $ids) = @_;

    # Set new files
    $self->{files} = $newfiles;

    # Update playlists
    for (@{$self->{plorder}}) {
        my $pl = $self->get_pl($_);
        if ($pl) {
            for (@$pl) {
                if ($_ eq int $_) {
                    $_ = $ids->{$_};
                }
            }
        }



( run in 1.156 second using v1.01-cache-2.11-cpan-ceb78f64989 )