#!/usr/bin/perl ############################################################################################################################################## use strict; use warnings; use Cwd qw(getcwd); use Digest::MD5; use JSON::XS; use LWP::UserAgent; use HTTP::Request::Common; $| = 1; ###################################################################################################################################### if (!$ARGV[0]) { print "Run this script in the parent directory of your music files.\n"; print "To acquire a login token, enable the \"Simple Uploaders\" app by visiting https://ibroadcast.com, logging in to your account, and clicking the \"Apps\" button in the side menu.\n"; print "usage: ./ibroadcast-uploader \n"; exit; } ## UserAgent object, for talking with iBroadcast my $ua = LWP::UserAgent->new; ## Inital request, verifies login_token, returns user_id/token my $req = get_req("login_token"); $req->{login_token} = $ARGV[0]; $req->{app_id} = 1007; $req->{type} = "account"; ## Convert request to json my $json_out = JSON::XS->new->utf8->encode ($req); ## Post it to api.ibroadcast.com my $response = $ua->post("https://api.ibroadcast.com/s/JSON/" . $req->{mode}, Content => $json_out, "User-Agent" => "perl uploader 0.2"); ## Parse the response my $j = JSON::XS->new->utf8->decode($response->content); if (!$j->{user}->{id}) { print defined($j->{message}) ? $j->{message} : "Login failed. Please check that your login token is not expired.\n"; exit; } ## Get user id and token from response my $user_id = $j->{user}->{id}; my $token = $j->{user}->{token}; ## Get supported types $req = get_req("status"); $req->{user_id} = $user_id; $req->{token} = $token; $req->{supported_types} = 1; ## Convert request to json $json_out = JSON::XS->new->utf8->encode ($req); ## Post it to api.ibroadcast.com $response = $ua->post("https://api.ibroadcast.com/s/JSON/" . $req->{mode}, Content => $json_out, "User-Agent" => "perl uploader 0.2"); ## Parse the response $j = JSON::XS->new->utf8->decode($response->content); if (!$j->{user}->{id}) { print "Could not get list of supported file types\n"; exit; } ## convert the supported array ref to a hashref my $supported; foreach (@{ $j->{supported} }) { $supported->{ $_->{extension} } = 1; } ## current working directory my $cwd = getcwd; ## Get files from cwd my $res = _list_files($cwd); ## confirm upload with user my $ok = _confirm($res); ## upload _upload_files($res) if $ok; exit; ############################################################################################################################################## sub get_req { my $mode = shift; my $req = { mode => $mode, version => "0.2", client => "perl uploader", user_agent => "perl uploader 0.2" }; return $req; } sub _confirm { my $res = shift; print "Found " . ($#{$res} + 1) . " files. Press 'L' to list, or 'U' to start the upload.\n"; my $confirm = ; if ($confirm =~ /L/i) { print "\nListing found, supported files\n"; foreach (@{ $res }) { print " - $_\n"; } print "Press 'U' to start the upload if this looks reasonable.\n"; $confirm = ; if ($confirm =~ /U/i) { print "Starting upload\n"; return 1; } else { print "aborted.\n"; return 0; } } elsif ($confirm =~ /U/i) { print "Starting upload\n"; return 1; } else { print "aborted.\n"; return 0; } } sub _get_md5 { my $ua = LWP::UserAgent->new; my $req = HTTP::Request->new(POST => "https://upload.ibroadcast.com"); $req->content_type("application/x-www-form-urlencoded"); $req->content("user_id=$user_id&token=$token"); $req->header("User-Agent" => "perl uploader 0.2"); my $resp = $ua->request($req); my $j = JSON::XS->new->utf8->decode($resp->content); return $j->{md5}; } sub _upload_files { my $files = shift; my $md5 = _get_md5(); foreach my $f (@{ $files }) { open(my $fh, $f) or print "Unable read $f $!\n" and return; binmode $fh; ## Create MD5 my $ctx = Digest::MD5->new; $ctx->addfile($fh); close ($fh); my $digest = $ctx->hexdigest; my $ok = 1; print "Uploading: $f\n"; ## check against uploaded md5 list foreach my $m (@{ $md5 }) { next if !$m; ## already uploaded if ($m eq $digest) { $ok = 0; print " skipping, already uploaded\n"; last; } } next if !$ok; my $ua = LWP::UserAgent->new; my $req = POST 'https://upload.ibroadcast.com', Content_Type => 'form-data', Content => [ file => [ $f ], file_path => $f, method => 'perl uploader', user_id => $user_id, token => $token, ]; $req->header("User-Agent" => "perl uploader 0.2"); my $resp = $ua->request($req); if ($resp->is_success) { print " Done!\n"; } else { print " Failed.\n"; } } } sub _list_files { my $dir = shift; my $files = shift; opendir(my $dh, $dir) || return $files; while (my $fn = readdir($dh)) { ## skip hidden next if $fn =~ /^\./; ## file, fullpath name my $file = $dir . "/" . $fn; ## extension my ($ext) = $file =~ m/(\..{2,5})/; ## add push(@{ $files }, $file) if $ext && $supported->{$ext}; ## dir, decend if (-d $file) { ## sub-directory files $files = _list_files($file, $files); } } closedir($dh); return $files; } ##############################################################################################################################################