Index: Slim/Music/iTunes.pm =================================================================== --- Slim/Music/iTunes.pm (revision 1920) +++ Slim/Music/iTunes.pm (working copy) @@ -209,7 +209,7 @@ my $base = ""; $base = $ENV{HOME} if $ENV{HOME}; - my $audiodir = Slim::Utils::Prefs::get('audiodir'); + my $audiodir = Slim::Utils::Prefs::getAudioDir(); my $autolocate = Slim::Utils::Prefs::get('itunes_library_autolocate'); if ($autolocate) { @@ -297,7 +297,7 @@ return $path; } - $path = Slim::Utils::Prefs::get('audiodir'); + $path = Slim::Utils::Prefs::getAudioDir(); return undef unless $path; $::d_itunes && msg("itunes: set iTunes library to audiodir value of: $path\n"); Slim::Utils::Prefs::set('itunes_library_music_path',$path); Index: Slim/Music/MusicFolderScan.pm =================================================================== --- Slim/Music/MusicFolderScan.pm (revision 1920) +++ Slim/Music/MusicFolderScan.pm (working copy) @@ -17,7 +17,7 @@ sub startScan { - if (!defined(Slim::Utils::Prefs::get('audiodir')) or not -d Slim::Utils::Prefs::get("audiodir")) { + if (!defined(Slim::Utils::Prefs::getAudioDir()) or not -d Slim::Utils::Prefs::getAudioDir()) { $::d_info && msg("Skipping music folder scan - audiodir is undefined.\n"); doneScanning(); return; @@ -30,17 +30,26 @@ $stillScanning = 1; - $::d_info && msg("Starting music folder scan\n"); - Slim::Utils::Scan::addToList(\@dummylist, Slim::Utils::Prefs::get('audiodir'), 1, 0, \&doneScanning, 0); - Slim::Music::Import::startScan('folder'); + my $dirs = Slim::Utils::Prefs::getAudioDirArray(); + my $dir = pop @{$dirs}; + $::d_info && msg("Starting music folder scan: $dir\n"); + Slim::Utils::Scan::addToList(\@dummylist, $dir, 1, 0, \&doneScanning, $dirs); + Slim::Music::Import::addImporter('folder'); } sub doneScanning { - $::d_info && msg("finished background scan of music folder.\n"); - - $stillScanning = 0; - @dummylist = (); - Slim::Music::Import::endImporter('folder'); + my $dirs = shift; + my $dir = pop @{$dirs}; + + if ($dir) { + $::d_info && msg("Starting music folder scan: $dir\n"); + Slim::Utils::Scan::addToList(\@dummylist, $dir, 1, 0, \&doneScanning, $dirs); + } else { + $::d_info && msg("finished background scan of music folder(s)\n"); + $stillScanning = 0; + @dummylist = (); + Slim::Music::Import::endImporter('folder'); + } } sub stillScanning { Index: Slim/Music/MusicMagic.pm =================================================================== --- Slim/Music/MusicMagic.pm (revision 1920) +++ Slim/Music/MusicMagic.pm (working copy) @@ -194,7 +194,7 @@ return $mmsPath if (Slim::Utils::Prefs::get('MMSHost') eq 'localhost'); my $remoteRoot = Slim::Utils::Prefs::get('MMSremoteRoot'); - my $nativeRoot = Slim::Utils::Prefs::get('audiodir'); + my $nativeRoot = Slim::Utils::Prefs::getAudioDir(); my $original = $mmsPath; my $winPath = $mmsPath =~ m/\\/; # test if this is a windows path Index: Slim/Utils/Scan.pm =================================================================== --- Slim/Utils/Scan.pm (revision 1920) +++ Slim/Utils/Scan.pm (working copy) @@ -98,6 +98,11 @@ $recursive = 1 if (!defined($recursive)); $callbackf = 0 if (!defined($callbackf)); + if (!defined $playlisturl) { + $callbackf && (&$callbackf(@callbackargs, scalar@{$listref})); + return; + } + $playlisturl = Slim::Utils::Misc::fixPath($playlisturl); if (!defined($sorted)) { Index: Slim/Utils/Misc.pm =================================================================== --- Slim/Utils/Misc.pm (revision 1920) +++ Slim/Utils/Misc.pm (working copy) @@ -32,24 +32,24 @@ our $log = ""; BEGIN { - if ($^O =~ /Win32/) { - *EWOULDBLOCK = sub () { 10035 }; - *EINPROGRESS = sub () { 10036 }; + if ($^O =~ /Win32/) { + *EWOULDBLOCK = sub () { 10035 }; + *EINPROGRESS = sub () { 10036 }; require Win32::Shortcut; require Win32::OLE::NLS; - } else { - require Errno; - import Errno qw(EWOULDBLOCK EINPROGRESS); - } + } else { + require Errno; + import Errno qw(EWOULDBLOCK EINPROGRESS); + } } # Find out what code page we're in, so we can properly translate file/directory encodings. our $locale = ''; { - if ($^O =~ /Win32/) { + if ($^O =~ /Win32/) { my $langid = Win32::OLE::NLS::GetUserDefaultLangID(); my $lcid = Win32::OLE::NLS::MAKELCID($langid); @@ -97,12 +97,16 @@ sub blocking { my $sock = shift; - return $sock->blocking(@_) unless $^O =~ /Win32/; + + return $sock->blocking(@_) unless $^O =~ /Win32/; + my $nonblocking = $_[0] ? "0" : "1"; my $retval = ioctl($sock, 0x8004667e, \$nonblocking); + if (!defined($retval) && $] >= 5.008) { $retval = "0 but true"; } + return $retval; } @@ -328,7 +332,7 @@ # fixPath takes relative file paths and puts the base path in the beginning # to make them full paths, if possible. # URLs are left alone - + sub fixPath { my $file = shift || return; my $base = shift; @@ -353,7 +357,7 @@ # the only kind of absolute file we like is one in # the music directory or the playlist directory... - my $audiodir = Slim::Utils::Prefs::get("audiodir"); + my $audiodir = Slim::Utils::Prefs::getAudioDir(); my $savedplaylistdir = Slim::Utils::Prefs::get("playlistdir"); if ($audiodir && $file =~ /^\Q$audiodir\E/) { @@ -403,6 +407,11 @@ sub ascendVirtual { my $curVP = shift; my @components = splitdir($curVP); + + for my $dir (@{Slim::Utils::Prefs::getAudioDirArray()}) { + return '' if $dir =~ /\Q$curVP\E/i; + last if $curVP =~ /\Q$dir\E/i; + } pop @components; @@ -421,16 +430,16 @@ my $curAP; $curAP = virtualToAbsolute($curVP); - + if (!defined($curVP)) { $curVP = ""; } $::d_paths && msg("descendVirtual(curVP = $curVP, item = $item, itemindex = $itemindex, curAP = $curAP)\n"); - if (Slim::Music::Info::isPlaylist($curAP)) { + if (defined $curAP && Slim::Music::Info::isPlaylist($curAP)) { $component = $itemindex; - } elsif (Slim::Music::Info::isPlaylistURL($item)) { + } elsif (Slim::Music::Info::isPlaylistURL($item) || !defined $curAP) { $component = $item; } elsif (Slim::Music::Info::isURL($item)) { $component = Slim::Web::HTTP::unescape((split(m|/|,$item))[-1]); @@ -463,7 +472,7 @@ sub virtualToAbsolute { my $virtual = shift; my $recursion = shift; - my $curdir = Slim::Utils::Prefs::get('audiodir'); + my $curdir; my $playdir = Slim::Utils::Prefs::get('playlistdir'); if (!defined($virtual)) { $virtual = "" }; @@ -473,7 +482,7 @@ if (file_name_is_absolute($virtual)) { $::d_paths && msg("virtualToAbsolute: $virtual is already absolute.\n"); - return $virtual; + return fileURLFromPath($virtual); } $::d_paths && msg("virtualToAbsolute: " . ($virtual ? $virtual : 'UNDEF') . "\n"); @@ -494,7 +503,7 @@ $recursion = 1; } else { - $curdir = Slim::Utils::Prefs::get('audiodir'); + $curdir = Slim::Utils::Prefs::getAudioDirArray(); } # Always unescape ourselves @@ -506,12 +515,18 @@ } return undef if (!$curdir); - $curdir = fileURLFromPath($curdir); + my @levels = (); if (defined($virtual)) { @levels = splitdir($virtual); } - + if (ref $curdir eq 'ARRAY') { + return undef if scalar @levels <= 1; + $curdir = ""; + } else { + $curdir = fileURLFromPath($curdir); + } + my $level; if ($::d_paths) { @@ -724,7 +739,7 @@ # always round down to avoid overshooting EOF on last track $fracrounded = int($seconds * 100) + 100; $frac = substr($fracrounded, -2, 2); - + return "$min:$sec.$frac"; } @@ -756,7 +771,7 @@ $assertline = $line; } } - + if ($assertfile) { open SRC, $assertfile; my $line; @@ -846,7 +861,7 @@ $allowedoctets[$i] =~ s/\s+//g; #if the octet is * or a specific match, pass octet match if (($allowedoctets[$i] eq "*") || ($allowedoctets[$i] eq $hostoctets[$i])) - { + { $matched[$i] = 1; } elsif ($allowedoctets[$i] =~ /-/) { #Look for a range formatted octet rule my ($low, $high) = split /-/,$allowedoctets[$i]; @@ -967,7 +982,7 @@ unless (at_eol($line)) { if (!defined($result) && $err != EWOULDBLOCK) { - return undef; + return undef; } next SLEEP; } Index: Slim/Utils/Prefs.pm =================================================================== --- Slim/Utils/Prefs.pm (revision 1920) +++ Slim/Utils/Prefs.pm (working copy) @@ -428,6 +428,23 @@ assert($client); return getArray($client->id() . "-" . $arrayPref); } + +sub getAudioDir { + return getArrayMax('multidirs'); +} + +sub getAudioDirArray { + my @dirs; + + if (getArrayMax('multidirs')) { + @dirs = getArray('multidirs'); + } else { + CORE::push(@dirs, get('audiodir')); + set('multidir',get('audiodir'),0); + } + return \@dirs; +} + # get($pref) sub get { return $prefs{$_[0]} Index: Slim/Web/Olson.pm =================================================================== --- Slim/Web/Olson.pm (revision 1920) +++ Slim/Web/Olson.pm (working copy) @@ -35,7 +35,7 @@ #if (Slim::Music::iTunes::useiTunesLibrary()) { # $params->{'itunes'} = 1; #} - if (defined(Slim::Utils::Prefs::get('audiodir'))) { + if (defined(Slim::Utils::Prefs::getAudioDir())) { $params->{'audiodir'} = 1; } @@ -236,7 +236,7 @@ #if (Slim::Music::iTunes::useiTunesLibrary()) { # $params->{'itunes'} = 1; #} - if (defined(Slim::Utils::Prefs::get('audiodir'))) { + if (defined(Slim::Utils::Prefs::getAudioDir())) { $params->{'audiodir'} = 1; } Index: Slim/Web/Pages.pm =================================================================== --- Slim/Web/Pages.pm (revision 1920) +++ Slim/Web/Pages.pm (working copy) @@ -445,7 +445,7 @@ $params->{'noartwork'} = 1; } - if (Slim::Utils::Prefs::get('audiodir')) { + if (Slim::Utils::Prefs::getAudioDir()) { addLinks("browse",{'BROWSE_MUSIC_FOLDER' => "browse.html?dir="}); } else { addLinks("browse",{'BROWSE_MUSIC_FOLDER' => undef}); @@ -537,7 +537,8 @@ my $items = []; my $fulldir = Slim::Utils::Misc::virtualToAbsolute($dir); - + + $::d_http && msg("browse virtual path: " . $dir . "\n"); $::d_http && msg("with absolute path: " . $fulldir . "\n"); @@ -545,121 +546,129 @@ $current_player = $client->id(); } - if ($dir =~ /^__playlists/) { - - $playlist = 1; - $params->{'playlist'} = 1; - - if (!Slim::Utils::Prefs::get("playlistdir") && !Slim::Music::Import::countImporters()) { - $::d_http && msg("no valid playlists directory!!\n"); - return Slim::Web::HTTP::filltemplatefile("badpath.html", $params); + my $suffix; + + if (defined $fulldir) { + if ($dir =~ /^__playlists/) { + + $playlist = 1; + $params->{'playlist'} = 1; + + if (!Slim::Utils::Prefs::get("playlistdir") && !Slim::Music::Import::countImporters()) { + $::d_http && msg("no valid playlists directory!!\n"); + return Slim::Web::HTTP::filltemplatefile("badpath.html", $params); + } + + if ($dir =~ /__current.m3u$/) { + + # write out the current playlist to a file with the special name __current + if (defined($client)) { + my $count = Slim::Player::Playlist::count($client); + $::d_http && msg("Saving playlist of $count items to $fulldir\n"); + Slim::Control::Command::execute($client, ['playlist', 'save', '__current']) if $count; + + } else { + $::d_http && msg("no client, so we can't save a file!!\n"); + return Slim::Web::HTTP::filltemplatefile("badpath.html", $params); + } + } + + } else { + + if (!Slim::Utils::Prefs::getAudioDir()) { + $::d_http && msg("no audiodir, so we can't save a file!!\n"); + return Slim::Web::HTTP::filltemplatefile("badpath.html", $params); + } } - - if ($dir =~ /__current.m3u$/) { - - # write out the current playlist to a file with the special name __current - if (defined($client)) { - my $count = Slim::Player::Playlist::count($client); - $::d_http && msg("Saving playlist of $count items to $fulldir\n"); - Slim::Control::Command::execute($client, ['playlist', 'save', '__current']) if $count; - + + if (!$fulldir || !Slim::Music::Info::isList($fulldir)) { + + # check if we're just showing itunes playlists + if (Slim::Music::Import::countImporters()) { + browser_addtolist_done($current_player, $callback, $httpClient, $params, [], $response); + return undef; } else { - $::d_http && msg("no client, so we can't save a file!!\n"); + $::d_http && msg("the selected playlist $fulldir isn't good!!.\n"); return Slim::Web::HTTP::filltemplatefile("badpath.html", $params); } } - - } else { - - if (!Slim::Utils::Prefs::get("audiodir")) { - $::d_http && msg("no audiodir, so we can't save a file!!\n"); - return Slim::Web::HTTP::filltemplatefile("badpath.html", $params); - } - } - - if (!$fulldir || !Slim::Music::Info::isList($fulldir)) { - - # check if we're just showing itunes playlists - if (Slim::Music::Import::countImporters()) { - browser_addtolist_done($current_player, $callback, $httpClient, $params, [], $response); - return undef; - } else { - $::d_http && msg("the selected playlist $fulldir isn't good!!.\n"); - return Slim::Web::HTTP::filltemplatefile("badpath.html", $params); - } - } - - my $suffix = Slim::Formats::Parse::getPlaylistSuffix($fulldir); - - # if they are renaming the playlist, let 'em. - if ($playlist && $params->{'newname'}) { - - my $newname = $params->{'newname'}; - - # don't allow periods, colons, control characters, slashes, backslashes, just to be safe. - $newname =~ tr|.:\x00-\x1f\/\\| |s; - - if (defined($suffix)) { - $newname .= $suffix; - }; + + $suffix = Slim::Formats::Parse::getPlaylistSuffix($fulldir); + + # if they are renaming the playlist, let 'em. + if ($playlist && $params->{'newname'}) { + + my $newname = $params->{'newname'}; + + # don't allow periods, colons, control characters, slashes, backslashes, just to be safe. + $newname =~ tr|.:\x00-\x1f\/\\| |s; + + if (defined($suffix)) { + $newname .= $suffix; + }; + + if ($newname) { + + my @newpath = splitdir(Slim::Utils::Misc::pathFromFileURL($fulldir)); + pop @newpath; + + my $container = Slim::Utils::Misc::fileURLFromPath(catdir(@newpath)); + + push @newpath, $newname; + + my $newfullname = Slim::Utils::Misc::fileURLFromPath(catdir(@newpath)); + + $::d_http && msg("renaming $fulldir to $newfullname\n"); + + if ($newfullname ne $fulldir && (!-e Slim::Utils::Misc::pathFromFileURL($newfullname) || defined $params->{'overwrite'}) && rename(Slim::Utils::Misc::pathFromFileURL($fulldir), Slim::Utils::Misc::pathFromFileURL($newfullname))) { + + Slim::Music::Info::clearCache($container); + Slim::Music::Info::clearCache($fulldir); + + $fulldir = $newfullname; + + $dir = Slim::Utils::Misc::descendVirtual(Slim::Utils::Misc::ascendVirtual($dir), $newname); + + $params->{'dir'} = $dir; + $::d_http && msg("new dir value: $dir\n"); + + } else { + + $::d_http && msg("Rename failed!\n"); + $params->{'RENAME_WARNING'} = 1; + } + } + + } elsif ($playlist && $params->{'delete'} ) { + + my $path = Slim::Utils::Misc::pathFromFileURL($fulldir); + + if ($path && -f $path && unlink $path) { + + $::d_http && msg("deleted playlist: $path\n"); + + my @newpath = splitdir(Slim::Utils::Misc::pathFromFileURL($fulldir)); + pop @newpath; - if ($newname) { - - my @newpath = splitdir(Slim::Utils::Misc::pathFromFileURL($fulldir)); - pop @newpath; - - my $container = Slim::Utils::Misc::fileURLFromPath(catdir(@newpath)); - - push @newpath, $newname; - - my $newfullname = Slim::Utils::Misc::fileURLFromPath(catdir(@newpath)); - - $::d_http && msg("renaming $fulldir to $newfullname\n"); - - if ($newfullname ne $fulldir && (!-e Slim::Utils::Misc::pathFromFileURL($newfullname) || defined $params->{'overwrite'}) && rename(Slim::Utils::Misc::pathFromFileURL($fulldir), Slim::Utils::Misc::pathFromFileURL($newfullname))) { - + my $container = Slim::Utils::Misc::fileURLFromPath(catdir(@newpath)); + Slim::Music::Info::clearCache($container); Slim::Music::Info::clearCache($fulldir); - - $fulldir = $newfullname; - - $dir = Slim::Utils::Misc::descendVirtual(Slim::Utils::Misc::ascendVirtual($dir), $newname); - + + $dir = Slim::Utils::Misc::ascendVirtual($dir); $params->{'dir'} = $dir; - $::d_http && msg("new dir value: $dir\n"); - + $fulldir = Slim::Utils::Misc::virtualToAbsolute($dir); + $suffix = Slim::Formats::Parse::getPlaylistSuffix($fulldir); + } else { - - $::d_http && msg("Rename failed!\n"); - $params->{'RENAME_WARNING'} = 1; + + $::d_http && msg("couldn't delete playlist: $path\n"); } } - - } elsif ($playlist && $params->{'delete'} ) { - - my $path = Slim::Utils::Misc::pathFromFileURL($fulldir); - - if ($path && -f $path && unlink $path) { - - $::d_http && msg("deleted playlist: $path\n"); - - my @newpath = splitdir(Slim::Utils::Misc::pathFromFileURL($fulldir)); - pop @newpath; - - my $container = Slim::Utils::Misc::fileURLFromPath(catdir(@newpath)); - - Slim::Music::Info::clearCache($container); - Slim::Music::Info::clearCache($fulldir); - - $dir = Slim::Utils::Misc::ascendVirtual($dir); - $params->{'dir'} = $dir; - $fulldir = Slim::Utils::Misc::virtualToAbsolute($dir); - $suffix = Slim::Formats::Parse::getPlaylistSuffix($fulldir); - - } else { - - $::d_http && msg("couldn't delete playlist: $path\n"); - } + } else { + #if virtualToAbsolute retusn undef, then we have multiple Audiodirs to deal with, + #so we'll create the list for scanning here. + $items = Slim::Utils::Prefs::getAudioDirArray(); } # @@ -672,6 +681,21 @@ $list_form{'skinOverride'} = $params->{'skinOverride'}; $params->{'pwd_list'} = " "; + my $audiodir; + + for my $whichdir (@{Slim::Utils::Prefs::getAudioDirArray()}) { + next unless $dir =~ /\Q$whichdir\E/i; + $audiodir = $whichdir; + } + + if (defined $audiodir) { + $list_form{'dir'} = Slim::Web::HTTP::escape($audiodir); + + $list_form{'shortdir'} = Slim::Music::Info::standardTitle(undef, Slim::Utils::Misc::fileURLFromPath($audiodir)); + + $params->{'pwd_list'} = ${Slim::Web::HTTP::filltemplatefile("browse_pwdlist.html", \%list_form)}; + } + my $lastpath; my $aggregate = $playlist ? "__playlists" : ""; @@ -679,12 +703,29 @@ if ($c ne "" && $c ne "__playlists" && $c ne "__current.m3u") { + if (defined $audiodir) { + + if ($audiodir =~ /\Q$aggregate\E$/i && $aggregate ne '') { + $list_form{'dir'} = Slim::Web::HTTP::escape($audiodir); + + $list_form{'shortdir'} = Slim::Music::Info::standardTitle(undef, Slim::Utils::Misc::fileURLFromPath($audiodir)); + + $params->{'pwd_list'} = ${Slim::Web::HTTP::filltemplatefile("browse_pwdlist.html", \%list_form)}; + + $audiodir = undef; + + } else { + $aggregate = (defined($aggregate) && $aggregate ne '') ? catdir($aggregate, $c) : $c; + next; + } + } + # incrementally build the path for each link $aggregate = (defined($aggregate) && $aggregate ne '') ? catdir($aggregate, $c) : $c; - + $list_form{'dir'} = Slim::Web::HTTP::escape($aggregate); - $list_form{'shortdir'} = Slim::Music::Info::standardTitle(undef, Slim::Utils::Misc::virtualToAbsolute($c)); + $list_form{'shortdir'} = Slim::Music::Info::standardTitle(undef, Slim::Utils::Misc::virtualToAbsolute($aggregate)); $params->{'pwd_list'} .= ${Slim::Web::HTTP::filltemplatefile("browse_pwdlist.html", \%list_form)}; } @@ -858,7 +899,7 @@ $list_form{'includeArtist'} = ($webFormat !~ /ARTIST/); $list_form{'includeAlbum'} = ($webFormat !~ /ALBUM/) ; - $list_form{'title'} = Slim::Music::Info::standardTitle(undef, $item); + $list_form{'title'} = Slim::Music::Info::standardTitle(undef, Slim::Utils::Misc::fileURLFromPath($item)); $list_form{'artist'} = Slim::Music::Info::artist($item); $list_form{'album'} = Slim::Music::Info::album($item); } @@ -1283,7 +1324,7 @@ unless ($item && $command) { - return Slim::Utils::MemoryUsage->status_memory_usage(); + return $client->status_memory_usage(); } if (defined $item && defined $command && Slim::Utils::MemoryUsage->can($command)) { @@ -1693,7 +1734,7 @@ $loc = Slim::Utils::Misc::utf8decode($loc); } - my $curdir = Slim::Utils::Prefs::get('audiodir'); + my $curdir = Slim::Utils::Prefs::getAudioDir(); if (!$curdir) { $downloadurl = undef; Index: Slim/Web/Setup.pm =================================================================== --- Slim/Web/Setup.pm (revision 1920) +++ Slim/Web/Setup.pm (working copy) @@ -1135,15 +1135,27 @@ $paramref->{'versionInfo'} = string('SERVER_VERSION') . string("COLON") . $::VERSION; $paramref->{'newVersion'} = $::newVersion; } - ,'GroupOrder' => ['language', 'Default'] + ,'GroupOrder' => ['language', 'AudioDirs','Default'] #,'template' => 'setup_server.html' ,'Groups' => { 'language' => { 'PrefOrder' => ['language'] }, 'Default' => { - 'PrefOrder' => ['audiodir','playlistdir','rescan',undef] + 'PrefOrder' => ['playlistdir','rescan',undef] } + ,'AudioDirs' => { + 'PrefOrder' => ['audiodirs'] + ,'PrefsInTable' => 1 + ,'Suppress_PrefHead' => 1 + ,'Suppress_PrefDesc' => 1 + ,'Suppress_PrefLine' => 1 + ,'Suppress_PrefSub' => 1 + ,'GroupHead' => string('SETUP_AUDIODIRS') + ,'GroupDesc' => string('SETUP_AUDIODIRS_DESC') + ,'GroupLine' => 1 + ,'GroupSub' => 1 + } } ,'Prefs' => { 'language' => { @@ -1151,12 +1163,26 @@ ,'validateArgs' => [\&Slim::Utils::Strings::hash_of_languages] ,'options' => undef #filled by initSetup using Slim::Utils::Strings::hash_of_languages() } - ,'audiodir' => { - 'validate' => \&validateIsAudioDir - ,'validateArgs' => [1] + ,'audiodirs' => { + 'isArray' => 1 + ,'arrayAddExtra' => 1 + ,'arrayDeleteNull' => 1 + ,'arrayDeleteValue' => '' + ,'arrayBasicValue' => 0 + ,'PrefSize' => 'large' + ,'inputTemplate' => 'setup_input_array_txt.html' + ,'validate' => \&validateIsAudioDir ,'changeIntro' => string('SETUP_OK_USING') ,'rejectMsg' => string('SETUP_BAD_DIRECTORY') - ,'PrefSize' => 'large' + ,'onChange' => sub { + my ($client,$changeref,$paramref,$pageref) = @_; + if (exists($changeref->{'audiodirs'}{'Processed'})) { + return; + } + processArrayChange($client,'audiodirs',$paramref,$pageref); + $setup{'server'}{'Prefs'}{'audiodirs'}{'options'} = {hash_of_prefs('audiodirs')}; + $changeref->{'audiodirs'}{'Processed'} = 1; + } } ,'playlistdir' => { 'validate' => \&validateIsDir Index: Slim/Buttons/Home.pm =================================================================== --- Slim/Buttons/Home.pm (revision 1920) +++ Slim/Buttons/Home.pm (working copy) @@ -150,7 +150,7 @@ if ($client->curSelection($client->curDepth()) eq 'MUSIC') { # add the whole of the music folder to the playlist! Slim::Buttons::Block::block($client, $client->string('ADDING_TO_PLAYLIST'), $client->string('MUSIC')); - Slim::Control::Command::execute($client, ['playlist', 'add', Slim::Utils::Prefs::get('audiodir')], \&Slim::Buttons::Block::unblock, [$client]); + Slim::Control::Command::execute($client, ['playlist', 'add', Slim::Utils::Prefs::getAudioDir()], \&Slim::Buttons::Block::unblock, [$client]); } elsif($client->curSelection($client->curDepth()) eq 'NOW_PLAYING') { $client->showBriefly($client->string('CLEARING_PLAYLIST'), ''); Slim::Control::Command::execute($client, ['playlist', 'clear']); @@ -168,7 +168,7 @@ } else { Slim::Buttons::Block::block($client, $client->string('NOW_PLAYING_FROM'), $client->string('MUSIC')); } - Slim::Control::Command::execute($client, ['playlist', 'load', Slim::Utils::Prefs::get('audiodir')], \&Slim::Buttons::Block::unblock, [$client]); + Slim::Control::Command::execute($client, ['playlist', 'load', Slim::Utils::Prefs::getAudioDir()], \&Slim::Buttons::Block::unblock, [$client]); } elsif($client->curSelection($client->curDepth()) eq 'NOW_PLAYING') { Slim::Control::Command::execute($client, ['play']); #The address of the %functions hash changes from compile time to run time @@ -430,7 +430,7 @@ $menuChoices{""} = ""; for my $menuOption (sort keys %home) { - if ($menuOption eq 'BROWSE_MUSIC_FOLDER' && !Slim::Utils::Prefs::get('audiodir')) { + if ($menuOption eq 'BROWSE_MUSIC_FOLDER' && !Slim::Utils::Prefs::getAudioDir()) { next; } if ($menuOption eq 'SAVED_PLAYLISTS' && !Slim::Utils::Prefs::get('playlistdir')) { Index: Slim/Buttons/Browse.pm =================================================================== --- Slim/Buttons/Browse.pm (revision 1920) +++ Slim/Buttons/Browse.pm (working copy) @@ -46,7 +46,7 @@ ); for my $name (sort keys %browse) { - if ($name eq 'BROWSE_MUSIC_FOLDER' && !Slim::Utils::Prefs::get('audiodir')) { + if ($name eq 'BROWSE_MUSIC_FOLDER' && !Slim::Utils::Prefs::getAudioDir()) { next; } if ($name eq 'SAVED_PLAYLISTS' && @@ -316,8 +316,9 @@ (Slim::Music::Info::isFileURL($abspwd) && -e (Slim::Utils::Misc::pathFromFileURL($abspwd))) ) ) { + push @{$client->dirItems},@{Slim::Utils::Prefs::getAudioDirArray()}; + $::d_files && msg("No such file or dir: [$pwd] removed out from under?\n"); opendir_done($client, $pwd, $direction, $oldlinesref, 0); - $::d_files && msg("No such file or dir: [$pwd] removed out from under?\n"); return; } @@ -402,7 +403,7 @@ if ($client->pwd() eq "__playlists") { $line1 = $client->string('SAVED_PLAYLISTS'); - } elsif ((defined $client->pwd() and $client->pwd() =~ m|^[/\\]?$|) || !Slim::Utils::Prefs::get('audiodir')) { + } elsif ((defined $client->pwd() and $client->pwd() =~ m|^[/\\]?$|) || !Slim::Utils::Prefs::getAudioDir()) { $line1 = $client->string('MUSIC'); } else { my $dir; @@ -439,7 +440,7 @@ if (!$client->numberOfDirItems()) { $line2 = $client->string('EMPTY'); } else { - my $fullpath = $client->dirItems($client->currentDirItem()); + my $fullpath = Slim::Utils::Misc::fileURLFromPath($client->dirItems($client->currentDirItem())); # try and use the id3 tag $line2 = Slim::Music::Info::standardTitle($client, $fullpath); Index: slimserver.pl =================================================================== --- slimserver.pl (revision 1920) +++ slimserver.pl (working copy) @@ -810,10 +810,14 @@ Slim::Utils::Prefs::set("cliport", $cliport); } + if (!Slim::Utils::Prefs::getAudioDir()) { + Slim::Utils::Prefs::set('audiodirs',Slim::Utils::Prefs::get('audiodir'),0); + } + # warn if there's no audiodir preference # FIXME put the strings in strings.txt - if (!(defined Slim::Utils::Prefs::get("audiodir") && - -d Slim::Utils::Prefs::get("audiodir")) && + if (!(defined Slim::Utils::Prefs::getAudioDir() && + -d Slim::Utils::Prefs::getAudioDir()) && !$quiet && !Slim::Music::iTunes::useiTunesLibrary() && !Slim::Music::MoodLogic::useMoodLogic() && @@ -825,8 +829,8 @@ } else { - if (defined(Slim::Utils::Prefs::get("audiodir")) && Slim::Utils::Prefs::get("audiodir") =~ m|[/\\]$|) { - $audiodir = Slim::Utils::Prefs::get("audiodir"); + if (defined(Slim::Utils::Prefs::getAudioDir()) && Slim::Utils::Prefs::getAudioDir() =~ m|[/\\]$|) { + $audiodir = Slim::Utils::Prefs::getAudioDir(); $audiodir =~ s|[/\\]$||; Slim::Utils::Prefs::set("audiodir",$audiodir); } Index: strings.txt =================================================================== --- strings.txt (revision 1920) +++ strings.txt (working copy) @@ -2309,23 +2309,13 @@ PT O idioma escolhido é SE Valt språk är: -SETUP_AUDIODIR - DE Musikverzeichnis - EN Music Folder - ES Carpeta de Música - FR Dossier de musique - JP ミュージック フォルダー - SE Musikmapp +SETUP_AUDIODIRS + EN Music Folders -SETUP_AUDIODIR_DESC - DE Sie können ein Verzeichnis definieren, dessen Musikdateien vom SlimServer durchsucht und zur Musiksammlung hinzugefügt werden sollen. Definieren Sie den Pfad zum Ordner im folgenden Feld. Sie können den Eintrag leer lassen, falls Sie die Musiksammlung von iTunes oder MoodLogic verwenden. - EN You can specify a folder containing music files that SlimServer will scan and add to your music library. Enter the path to the folder below. You can leave this field blank if you are importing your music library information from iTunes or MoodLogic. - ES Se puede especificar una carpeta que contenga archivos de música que SlimServer va a recopilar y añadir a la colección musical. Ingrese el camino a la carpeta debajo. Se puede dejar este campo en blanco si se está importando la información de la colección musical desde iTunes o MoodLogic. - FR Vous pouvez spécifier un dossier contenant vos fichiers musicaux afin que le SlimServer le répertorie et ajoute son contenu à votre collection de musique. Entrez le chemin ci-dessous. Vous pouvez ignorer ce champ si vous utilisez iTunes ou Moodlogic pour gérer votre collection de musique. - JP SlimServerが検索するフォルダーを指定することができます。iTunesまたはムードロジックの情報を利用する場合はブランクで構いません。 - SE Du kan ange en mapp som SlimServer kommer scanna för att lägga till musik till ditt bibliotek. Ange läget nedan. Om du importerar MoodLogic eller iTunes behöver ingenting anges. +SETUP_AUDIODIRS_DESC + EN You can specify a number of folders containing music files that SlimServer will scan and add to your music library. Enter the path to the folder below. You can leave this field blank if you want to only import your data from an external source. -SETUP_AUDIODIR_OK +SETUP_AUDIODIRS_OK DE Der Server verwendet den folgenden Pfad zu ihren MP3 Dateien: DK OK, anvender: EN The server will use the following path to your music files: