# Rescan.pm - Provide player UI for setting a scheduled server rescan # $Id: ScanTimer.pm,v 1.3 2004/05/10 07:02:27 fishbone Exp $ # This code is derived from code with the following copyright message: # # SlimServer Copyright (c) 2001-2004 Sean Adams, Slim Devices Inc. # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License, # version 2. package Plugins::ScanTimer; use Slim::Utils::Strings qw (string); use Time::HiRes; my $interval = 1; # check every x seconds my @browseMenuChoices; my %menuSelection; my %searchCursor; use vars qw($VERSION); $VERSION = substr(q$Revision: 1.3 $,10); sub getDisplayName { string('SCANTIMER_NAME'); } sub strings { local $/ = undef; ; } # the routines sub setMode() { my $client = shift; @browseMenuChoices = ( string('SCANTIMER_SET'), string('SCANTIMER_OFF'), ); if (!defined($menuSelection{$client})) { $menuSelection{$client} = 0; }; $client->lines(\&lines); #get previous alarm time or set a default my $time = Slim::Utils::Prefs::get($client, "rescan-time"); if (!defined($time)) { Slim::Utils::Prefs::get($client, "rescan-time", 9 * 60 * 60 ); } } my %functions = ( 'up' => sub { my $client = shift; my $newposition = Slim::Buttons::Common::scroll($client, -1, ($#browseMenuChoices + 1), $menuSelection{$client}); $menuSelection{$client} =$newposition; $client->update(); }, 'down' => sub { my $client = shift; my $newposition = Slim::Buttons::Common::scroll($client, +1, ($#browseMenuChoices + 1), $menuSelection{$client}); $menuSelection{$client} =$newposition; $client->update(); }, 'left' => sub { my $client = shift; Slim::Buttons::Common::popModeRight($client); }, 'right' => sub { my $client = shift; my @oldlines = Slim::Display::Display::curLines($client); if ($browseMenuChoices[$menuSelection{$client}] eq string('SCANTIMER_SET')) { Slim::Buttons::Common::pushModeLeft($client, 'scantimerset'); } elsif ($browseMenuChoices[$menuSelection{$client}] eq string('SCANTIMER_OFF')) { Slim::Utils::Prefs::set("rescan-scheduled", 1); $browseMenuChoices[$menuSelection{$client}] = string('SCANTIMER_ON'); Slim::Display::Animation::showBriefly($client,string('SCANTIMER_TURNING_ON'),''); setTimer($client); } elsif ($browseMenuChoices[$menuSelection{$client}] eq string('SCANTIMER_ON')) { Slim::Utils::Prefs::set("rescan-scheduled", 0); $browseMenuChoices[$menuSelection{$client}] = string('SCANTIMER_OFF'); Slim::Display::Animation::showBriefly($client,string('SCANTIMER_TURNING_OFF'),''); setTimer($client); } }, 'play' => sub { my $client = shift; }, ); sub setTimer { #timer to check alarms on an interval Slim::Utils::Timers::setTimer(0, Time::HiRes::time() + $interval, \&checkScanTimer); } sub checkScanTimer { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); my $time = $hour * 60 * 60 + $min * 60; if ($sec == 0) { # once we've reached the beginning of a minute, only check every 60s $interval = 60; } if ($sec >= 50) { # if we end up falling behind, go back to checking each second $interval = 1; } if (Slim::Utils::Prefs::get("rescan-scheduled")) { my $scantime = Slim::Utils::Prefs::get("rescan-time"); if ($scantime) { if ($time == $scantime +60 ) {$interval=1;}; #alarm is done, so reset to find the beginning of a minute if ($time == $scantime && !Slim::Music::MusicFolderScan::stillScanning()) { Slim::Music::MusicFolderScan::startScan(); } } } setTimer(); } sub lines { my $client = shift; my ($line1, $line2, $overlay); my $timeFormat = Slim::Utils::Prefs::get("timeFormat"); $overlay = overlay($client); $line1 = string('SCANTIMER_NAME'); if (Slim::Utils::Prefs::get("rescan-scheduled") && $browseMenuChoices[$menuSelection{$client}] eq string('SCANTIMER_OFF')) { $browseMenuChoices[$menuSelection{$client}] = string('SCANTIMER_ON'); } $line2 = ""; $line2 = $browseMenuChoices[$menuSelection{$client}]; return ($line1, $line2, undef, $overlay); } sub overlay { my $client = shift; return Slim::Hardware::VFD::symbol('rightarrow'); return undef; } sub getFunctions() { return \%functions; } ################################################################################# my %timerSetFunctions = ( 'up' => sub { my $client = shift; scrollDigit($client, +1); }, 'down' => sub { my $client = shift; scrollDigit($client, -1); }, 'left' => sub { my $client = shift; $searchCursor{$client}--; if ($searchCursor{$client} < 0) { Slim::Buttons::Common::popModeRight($client); } else { $client->update(); } }, 'right' => sub { my $client = shift; my ($h0, $h1, $m0, $m1, $p) = timeDigits($client); $searchCursor{$client}++; my $max = defined($p) ? 4 : 3; if ($searchCursor{$client} > $max) { $searchCursor{$client} = $max; } $client->update(); }, 'add' => sub { Slim::Display::Animation::bumpRight(shift); }, 'play' => sub { Slim::Display::Animation::bumpRight(shift); }, 'numberScroll' => sub { my $client = shift; my $button = shift; my $digit = shift; my ($h0, $h1, $m0, $m1, $p) = timeDigits($client); my $h = $h0 * 10 + $h1; if ($p && $h == 12) { $h = 0 }; my $c = $searchCursor{$client}; if ($c == 0 && $digit < ($p ? 2:3)) { $h0 = $digit; $searchCursor{$client}++; }; if ($c == 1 && (($h0 * 10 + $digit) < 24)) { $h1 = $digit; $searchCursor{$client}++; }; if ($c == 2) { $m0 = $digit; $searchCursor{$client}++; }; if ($c == 3) { $m1 = $digit }; $p = (defined $p && $p eq 'PM') ? 1 : 0; if ($c == 4) { $p = $digit % 2; } my $time = ($h0 * 10 + $h1) * 60 * 60 + $m0 * 10 * 60 + $m1 * 60 + $p * 12 * 60 * 60; Slim::Utils::Prefs::set("rescan-time", $time); $client->update(); #update the display $client->update(); } ); sub getTimerSetFunctions { return \%timerSetFunctions; } sub setScanTimerSetMode { my $client = shift; $searchCursor{$client} = 0; Slim::Utils::Prefs::set("rescan-scheduled", 0); $client->lines(\&timerSettingsLines); } sub timerSettingsLines { my $client = shift; my ($h0, $h1, $m0, $m1, $p) = timeDigits($client); my $cs = Slim::Hardware::VFD::symbol('cursorpos'); my $c = $searchCursor{$client}; my $timestring = ($c == 0 ? $cs : '') . ((defined($p) && $h0 == 0) ? ' ' : $h0) . ($c == 1 ? $cs : '') . $h1 . ":" . ($c == 2 ? $cs : '') . $m0 . ($c == 3 ? $cs : '') . $m1 . " " . ($c == 4 ? $cs : '') . (defined($p) ? $p : ''); return (string('SCANTIMER_SET'), $timestring); } sub scrollDigit { my $client = shift; my $dir = shift; my ($h0, $h1, $m0, $m1, $p) = timeDigits($client); my $h = $h0 * 10 + $h1; if ($p && $h == 12) { $h = 0 }; if ($searchCursor{$client} == 0) {$searchCursor{$client}++;}; my $c = $searchCursor{$client}; $p = ($p && $p eq 'PM') ? 1 : 0; if ($c == 1) { $h = Slim::Buttons::Common::scroll($client, $dir, ($p == 1) ? 12 : 24, $h); #change AM and PM if we scroll past midnight or noon boundary if (Slim::Utils::Prefs::get('timeFormat') =~ /%p/) { if (($h == 0 && $dir == 1)||($h == 11 && $dir == -1)) { $p = Slim::Buttons::Common::scroll($client, +1, 2, $p); }; }; }; if ($c == 2) { $m0 = Slim::Buttons::Common::scroll($client, $dir, 6, $m0) }; if ($c == 3) { $m1 = Slim::Buttons::Common::scroll($client, $dir, 10, $m1)}; if ($c == 4) { $p = Slim::Buttons::Common::scroll($client, +1, 2, $p); } my $time = $h * 60 * 60 + $m0 * 10 * 60 + $m1 * 60 + $p * 12 * 60 * 60; Slim::Utils::Prefs::set("rescan-time", $time); $client->update(); } sub timeDigits { my $client = shift; my $time = Slim::Utils::Prefs::get("rescan-time") || 0; my $h = int($time / (60*60)); my $m = int(($time - $h * 60 * 60) / 60); my $p = undef; my $timestring; if (Slim::Utils::Prefs::get('timeFormat') =~ /%p/) { $p = 'AM'; if ($h > 11) { $h -= 12; $p = 'PM'; } if ($h == 0) { $h = 12; } } #else { $p = " "; }; if ($h < 10) { $h = '0' . $h; } if ($m < 10) { $m = '0' . $m; } my $h0 = substr($h, 0, 1); my $h1 = substr($h, 1, 1); my $m0 = substr($m, 0, 1); my $m1 = substr($m, 1, 1); return ($h0, $h1, $m0, $m1, $p); } sub setupGroup { my %group = ( PrefOrder => ['rescan-scheduled','rescan-time'], PrefsInTable => 1, GroupHead => string('SCANTIMER_NAME'), GroupDesc => string('SCANTIMER_DESC'),, GroupLine => 1, GroupSub => 1, Suppress_PrefSub => 1, Suppress_PrefLine => 1, Suppress_PrefHead => 1 ); my %prefs = ( 'rescan-scheduled' => { 'validate' => \&Slim::Web::Setup::validateTrueFalse ,'PrefChoose' => string('SCANTIMER_NAME') ,'changeIntro' => string('SCANTIMER_NAME') ,'options' => { '1' => string('ON') ,'0' => string('OFF') } }, 'rescan-time' => { 'validate' => \&Slim::Web::Setup::validateAcceptAll ,'validateArgs' => [0,undef] ,'PrefChoose' => string('SCANTIMER_SET') ,'changeIntro' => string('SCANTIMER_SET') ,'currentValue' => sub { my $client = shift; my ($h0, $h1, $m0, $m1, $p) = timeDigits($client); my $timestring = ((defined($p) && $h0 == 0) ? ' ' : $h0) . $h1 . ":" . $m0 . $m1 . " " . (defined($p) ? $p : ''); return $timestring; } ,'onChange' => sub { my ($client,$changeref,$paramref,$pageref) = @_; my $time = $changeref->{'rescan-time'}{'new'}; my $newtime = 0; $time =~ s{ ^(0?[0-9]|1[0-9]|2[0-4]):([0-5][0-9])\s*(P|PM|A|AM)?$ }{ if (defined $3) { $newtime = ($1 == 12?0:$1 * 60 * 60) + ($2 * 60) + ($3 =~ /P/?12 * 60 * 60:0); } else { $newtime = ($1 * 60 * 60) + ($2 * 60); } }iegsx; Slim::Utils::Prefs::set('rescan-time',$newtime); } }, ); #&checkDefaults; return (\%group,\%prefs); }; #sub checkDefaults #{ # if (!Slim::Utils::Prefs::isDefined('rescan-time')) # { # Slim::Utils::Prefs::set('rescan-time', 36000); # } #} # some initialization code, adding modes for this module Slim::Buttons::Common::addMode('scantimer', getFunctions(), \&Plugins::ScanTimer::setMode); Slim::Buttons::Common::addMode('scantimerset', getTimerSetFunctions(), \&Plugins::ScanTimer::setScanTimerSetMode); setTimer(); 1; __DATA__ SCANTIMER_NAME EN Scan Timer SCANTIMER_SET EN Set Scan Time SCANTIMER_ON EN Scan Timer ON SCANTIMER_DESC EN You can choose to allow a scheduled rescan of your music library every 24 hours. Set the time, and set the Scan Timer to ON to use this feature. SCANTIMER_OFF EN Scan Timer OFF SCANTIMER_TURNING_ON EN Scan Timer Turning On SCANTIMER_TURNING_OFF EN Scan Timer Turning Off