The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
#! /usr/bin/env perl
#---------------------------------------------------------------------
# delete-folder.pl
# Created by Christopher J. Madsen
#
# This example script is in the public domain.
#
# Recursively delete a folder and all its contents from device
#---------------------------------------------------------------------

use 5.010;
use strict;
use warnings;

use Media::LibMTP::API qw(Get_First_Device
                          LIBMTP_FILETYPE_ALBUM LIBMTP_FILETYPE_PLAYLIST);

my $device;

while (1) {
  $device = Get_First_Device() and last;
  say STDERR "Trying again in 5 seconds...";
  sleep 5;
}

say STDERR "Connected to " . $device->Get_Friendlyname;

my $fileList   = $device->Get_Filelisting;
my $folderList = $device->Get_Folder_List;

#=====================================================================
sub folder_by_path
{
  my ($path) = @_;

  my @path = split qr!/!, $path;

  shift @path unless length $path[0];

  my $folder = $folderList;

  while (@path) {
    while ($folder->name ne $path[0]) {
      $folder = $folder->sibling // die "Can't find $path";
    }
    shift @path;
    $folder = $folder->child // die "Can't find $path" if @path
  }

  return $folder;
} # end folder_by_path

#---------------------------------------------------------------------
sub delete_folder
{
  my ($folder) = @_;

  my $id = $folder->folder_id;

  printf "Beginnning folder %s (%d)...\n", $folder->name, $id;

  my $child = $folder->child;
  while ($child) {
    delete_folder($child);
    $child = $child->sibling;
  }

  my (@albums, @playlists, @files);

  for (my $file = $fileList;  $file;  $file = $file->next) {
    next unless $file->parent_id == $id;

    given ($file->filetype) {
      when (LIBMTP_FILETYPE_ALBUM)    { push @albums,    $file }
      when (LIBMTP_FILETYPE_PLAYLIST) { push @playlists, $file }
      default                         { push @files,     $file }
    }
  }

  delete_files(playlist => @playlists);
  delete_files(album    => @albums);
  delete_files(file     => @files);

  printf "Deleting folder %s (%d)...\n", $folder->name, $id;
  delete_objects($id);
} # end delete_folder

#---------------------------------------------------------------------
sub delete_files
{
  my $type = shift;

  foreach my $file (@_) {
    printf "Deleting %s %s (%d)...\n", $type, $file->filename, $file->item_id;
    delete_objects($file->item_id);
  }
} # end delete_files

#---------------------------------------------------------------------
sub delete_objects
{
  foreach my $id (@_) {
    $device->Delete_Object($id) and die "$id failed: " . $device->errstr;
  }
} # end delete_objects

#=====================================================================
for my $path (@ARGV) {
  my $folder = folder_by_path($path);
  delete_folder($folder);
} # end for each $id in @ARGV

undef $device;