diff --git a/install.sh b/install.sh
index 4c058beb9..d173dae5f 100644
--- a/install.sh
+++ b/install.sh
@@ -2,8 +2,12 @@
alias=r1
-# 20221005
-[[ -e /srv/http/data/system/hddspindown ]] && mv /srv/http/data/system/{hddspindown,apm}
+. /srv/http/bash/addons.sh
+
+# 20221007
+grep -q hard,intr /etc/fstab && sed -i '/hard,intr/soft/' /etc/fstab
+
+[[ -e $dirsystem/hddspindown ]] && mv $dirsystem/{hddspindown,apm}
if [[ ! -e /boot/kernel.img ]]; then
dir=/etc/systemd/system
@@ -43,11 +47,10 @@ fi
systemctl daemon-reload
# 20220916
-dirmpd=/srv/http/data/mpd
if (( $( cat $dirmpd/counts | wc -l ) == 1 )); then
echo '{
- "playlists" : '$( ls -1 /srv/http/data/playlists | wc -l )'
-, "webradio" : '$( find -L /srv/http/data/webradio -type f ! -path '*/img/*' | wc -l )'
+ "playlists" : '$( ls -1 $dirplaylists | wc -l )'
+, "webradio" : '$( find -L $dirwebradio -type f ! -path '*/img/*' | wc -l )'
}' > $dirmpd/counts
fi
@@ -58,15 +61,16 @@ fi
rm /srv/http/bash/{camilladsp*,features*,networks*,player*,relays*,system*} &> /dev/null
#-------------------------------------------------------------------------------
-. /srv/http/bash/addons.sh
-
installstart "$1"
getinstallzip
-chmod +x $dirbash/cmd.sh
-$dirbash/cmd.sh dirpermissions
+chmod +x $dirbash/settings/system.sh
+$dirbash/settings/system.sh dirpermissions
[[ -e $dirsystem/color ]] && $dirbash/cmd.sh color
installfinish
#-------------------------------------------------------------------------------
+
+# 20221010
+[[ -e /srv/http/shareddata ]] && echo -e "$info Shared Data must be disabled and setup again."
diff --git a/srv/http/assets/css/common.css b/srv/http/assets/css/common.css
index 1c46ae13b..883d05d8b 100644
--- a/srv/http/assets/css/common.css
+++ b/srv/http/assets/css/common.css
@@ -1,6 +1,6 @@
@font-face {
font-family: rern;
- src: url( '/assets/fonts/rern.2022100300.woff2' ) format( 'woff2' );
+ src: url( '/assets/fonts/rern.2022101100.woff2' ) format( 'woff2' );
font-display: block;
font-style: normal;
font-weight: normal;
diff --git a/srv/http/assets/fonts/rern.woff2 b/srv/http/assets/fonts/rern.woff2
index d48a8fb3f..8af781cb9 100644
Binary files a/srv/http/assets/fonts/rern.woff2 and b/srv/http/assets/fonts/rern.woff2 differ
diff --git a/srv/http/assets/js/context.js b/srv/http/assets/js/context.js
index 4a014458c..800920307 100644
--- a/srv/http/assets/js/context.js
+++ b/srv/http/assets/js/context.js
@@ -1,9 +1,8 @@
function addReplace( cmd, command, title, msg ) {
- if ( cmd === 'addplay' || cmd === 'replaceplay' || cmd === 'replace' ) $( '#stop' ).click();
+ var play = cmd === 'addplay' || cmd === 'replaceplay';
+ if ( play || cmd === 'replace' ) $( '#stop' ).click();
bash( command, function() {
- if ( !G.display.playbackswitch ) return
-
- if ( cmd === 'addplay' || cmd === 'replaceplay' ) $( '#playback' ).click();
+ if ( G.display.playbackswitch && play ) $( '#playback' ).click();
} );
banner( title, msg, 'playlist' );
}
@@ -780,6 +779,7 @@ $( '.contextmenu a, .contextmenu .submenu' ).click( function() {
}
if ( !mpccmd ) mpccmd = [];
var sleep = G.mode.slice( -5 ) === 'radio' ? 1 : 0.2;
+ if ( G.status.state === 'play' && G.status.webradio ) sleep += 1;
var contextCommand = {
add : mpccmd
, playnext : mpccmd
diff --git a/srv/http/assets/js/features.js b/srv/http/assets/js/features.js
index 8dc7fda13..c49a1e4b9 100644
--- a/srv/http/assets/js/features.js
+++ b/srv/http/assets/js/features.js
@@ -390,6 +390,7 @@ $( '#nfsserver' ).click( function() {
, title : 'Server rAudio'
, message : $this.prev().html()
} );
+ $this.prop( 'checked', G.nfsserver );
return
}
diff --git a/srv/http/assets/js/function.js b/srv/http/assets/js/function.js
index a2b5c016d..7432af567 100644
--- a/srv/http/assets/js/function.js
+++ b/srv/http/assets/js/function.js
@@ -573,8 +573,8 @@ function getPlaybackStatus( withdisplay ) {
if ( G.playback ) {
displayPlayback();
} else if ( G.library ) {
- if ( !$( '#lib-search-close' ).text() && !G.librarylist ) {
- $.post( 'index-body.php', { modelist: 1 }, function( html ) {
+ if ( !G.librarylist ) {
+ $.post( 'mpdlibrary.php', { query: 'home' }, function( html ) {
$( '#lib-mode-list' ).html( html );
renderLibrary();
} );
@@ -1248,9 +1248,7 @@ function renderPlaylist( data ) {
setPlaylistScroll();
} else {
G.htmlplaylist = data.html;
- var timestamp = Math.floor( Date.now() / 1000 );
- var html = data.html.replaceAll( 'thumb.jpg', 'thumb.'+ timestamp +'.jpg' );
- $( '#pl-list' ).html( html +'
'
@@ -568,8 +564,6 @@ function info( json ) {
O.nochange = O.values && O.checkchanged ? true : false;
$( '#infoOk' ).toggleClass( 'disabled', O.blank || O.short || O.nochange ); // initial check
infoCheckSet();
- //////////////////////////////////////////////////////////////////////////
- }, 0 );
}
function checkBlank() {
diff --git a/srv/http/assets/js/main.js b/srv/http/assets/js/main.js
index 89cc042ba..4b758f83a 100644
--- a/srv/http/assets/js/main.js
+++ b/srv/http/assets/js/main.js
@@ -4,7 +4,6 @@ var G = {
, apikeylastfm : 'd666cd06ec4fcf84c3b86279831a1c8e'
, sharedsecret : '390372d3a1f60d4030e2a612260060e0'
, bioartist : []
- , bookmarkedit : 0
, coverart : '/assets/img/coverart.svg'
, coversave : 0
, covervu : '/assets/img/vu.svg'
@@ -438,15 +437,18 @@ $( '#addons' ).click( function () {
loader();
} );
$( '#library, #button-library' ).click( function() {
- $( '#lib-path span' ).removeClass( 'hide' );
- if ( !$( '#lib-search-input' ).val() ) $( '#lib-search-close' ).empty();
- if ( G.library ) {
- if ( G.librarylist ) G.scrolltop[ $( '#lib-path .lipath' ).text() ] = $( window ).scrollTop();
- renderLibrary();
- } else {
- switchPage( 'library' );
- if ( G.status.updating_db ) banner( 'Library Database', 'Update ...', 'refresh-library blink' );
- }
+ $.post( 'mpdlibrary.php', { query: 'home' }, function( html ) {
+ $( '#lib-mode-list' ).html( html );
+ $( '#lib-path span' ).removeClass( 'hide' );
+ if ( !$( '#lib-search-input' ).val() ) $( '#lib-search-close' ).empty();
+ if ( G.library ) {
+ if ( G.librarylist ) G.scrolltop[ $( '#lib-path .lipath' ).text() ] = $( window ).scrollTop();
+ renderLibrary();
+ } else {
+ switchPage( 'library' );
+ if ( G.status.updating_db ) banner( 'Library Database', 'Update ...', 'refresh-library blink' );
+ }
+ } );
} );
$( '#playback' ).click( function() {
if ( G.playback && ( G.wH - $( '#coverart' )[ 0 ].getBoundingClientRect().bottom ) < 30 ) {
@@ -1314,7 +1316,9 @@ $( '#button-lib-back' ).click( function() {
}
}
} );
-$( '.mode' ).click( function() {
+$( '#lib-mode-list' ).click( function( e ) {
+ if ( !G.press && $( '.bkedit' ).length && !$( e.target ).hasClass( 'bkedit' ) ) setBookmarkEdit();
+} ).on( 'click', '.mode', function() {
var $this = $( this );
G.mode = $this.data( 'mode' );
$( '#lib-search-close' ).click();
@@ -1386,11 +1390,7 @@ $( '.mode' ).click( function() {
query.path = G.mode.slice( -5 ) === 'radio' ? '' : path;
query.modetitle = path;
if ( query.query !== 'ls' ) G.query.push( query );
-} );
-$( '#lib-mode-list' ).click( function( e ) {
- if ( !G.press && $( '.bkedit' ).length && !$( e.target ).hasClass( 'bkedit' ) ) setBookmarkEdit();
-} );
-$( '#lib-mode-list' ).on( 'click', '.mode-bookmark', function( e ) { // delegate - id changed on renamed
+} ).on( 'click', '.mode-bookmark', function( e ) { // delegate - id changed on renamed
$( '#lib-search-close' ).click();
if ( G.press || $( '.bkedit' ).length ) return
@@ -1503,7 +1503,7 @@ $( '#lib-mode-list' ).on( 'click', '.mode-bookmark', function( e ) { // delegate
}
} );
} )
-$( '.mode-bookmark' ).press( setBookmarkEdit );
+$( '#lib-mode-list' ).press( '.mode-bookmark', setBookmarkEdit );
new Sortable( document.getElementById( 'lib-mode-list' ), {
// onChoose > onClone > onStart > onMove > onChange > onUnchoose > onUpdate > onSort > onEnd
ghostClass : 'lib-sortable-ghost'
diff --git a/srv/http/assets/js/settings.js b/srv/http/assets/js/settings.js
index dae81a6bf..791e0c0b8 100644
--- a/srv/http/assets/js/settings.js
+++ b/srv/http/assets/js/settings.js
@@ -2,9 +2,12 @@ function bash( command, callback, json ) {
if ( typeof command === 'string' ) {
var args = { cmd: 'bash', bash : command }
} else {
- if ( command[ 0 ] === 'cmd' ) {
+ var cmd0 = command[ 0 ];
+ if ( cmd0 === 'cmd' ) {
var filesh = 'cmd';
command.shift();
+ } else if ( cmd0 === 'pkgstatus' || cmd0 === 'rebootlist' ) {
+ var filesh = 'settings/system';
} else {
var filesh = 'settings/'+ page;
}
@@ -67,7 +70,7 @@ function currentStatus( id, refresh ) {
notify( 'Get Data', id, page );
}, 1000 );
}
- var command = services.includes( id ) ? [ 'cmd', 'pkgstatus', id ] : cmd[ id ]+' 2> /dev/null';
+ var command = services.includes( id ) ? [ 'pkgstatus', id ] : cmd[ id ]+' 2> /dev/null';
bash( command, function( status ) {
clearTimeout( timeoutGet );
$el.html( status ).promise().done( function() {
@@ -413,32 +416,27 @@ $( '.container' ).on( 'click', '.status', function( e ) {
if ( !$this.hasClass( 'single' ) ) currentStatus( $this.data( 'status' ) );
} );
$( '.close' ).click( function() {
- if ( page === 'networks' ) {
- clearTimeout( G.timeoutScan );
- bash( 'killall networks-scan.sh &> /dev/null' );
- }
- bash( [ 'cmd', 'rebootlist' ], function( list ) {
+ bash( [ 'rebootlist' ], function( list ) {
if ( !list ) {
location.href = '/';
- } else {
- var list = list.replace( /\^/s, '\n' );
- info( {
- icon : page
- , title : 'System Setting'
- , message : `\
-Reboot required for:
-
${ list }`
- , cancel : function() {
- bash( 'rm -f /srv/http/data/shm/reboot /srv/http/data/tmp/backup.*' );
- location.href = '/';
- }
- , okcolor : orange
- , oklabel : '
Reboot'
- , ok : function() {
- bash( [ 'cmd', 'power', 'reboot' ] );
- }
- } );
+ return
}
+
+ info( {
+ icon : page
+ , title : 'System Setting'
+ , message : 'Reboot required for:
'
+ +'
'+ list +'
'
+ , cancel : function() {
+ bash( 'rm -f /srv/http/data/shm/reboot /srv/http/data/tmp/backup.*' );
+ location.href = '/';
+ }
+ , okcolor : orange
+ , oklabel : '
Reboot'
+ , ok : function() {
+ bash( [ 'cmd', 'power', 'reboot' ] );
+ }
+ } );
} );
} );
$( '#button-data' ).click( function() {
diff --git a/srv/http/assets/js/system.js b/srv/http/assets/js/system.js
index 8940faa04..a6f7a3a7d 100644
--- a/srv/http/assets/js/system.js
+++ b/srv/http/assets/js/system.js
@@ -131,6 +131,15 @@ $( '#menu a' ).click( function() {
var icon = 'usbdrive';
var title = 'Local Mount';
}
+ if ( G.shareddata && mountpoint === '/mnt/MPD/NAS/data' ) {
+ info( {
+ icon : 'networks'
+ , title : 'Network Storage'
+ , message : '
Shared Data is currently enabled.'
+ } );
+ return
+ }
+
switch ( cmd ) {
case 'forget':
notify( title, 'Forget ...', icon );
@@ -512,9 +521,9 @@ $( '#setting-mpdoled' ).click( function() {
, cancel : function() {
$( '#mpdoled' ).prop( 'checked', G.mpdoled );
}
- , buttonlabel : '
Logo'
+ , buttonlabel : !G.mpdoled ? '' : '
Logo'
, button : !G.mpdoled ? '' : function() {
- bash( '/srv/http/bash/cmd.sh mpdoledlogo' );
+ bash( [ 'mpdoledlogo' ] );
}
, ok : function() {
notify( 'Spectrum OLED', G.mpdoled ? 'Change ...' : 'Enable ...', 'mpdoled' );
@@ -911,6 +920,7 @@ function infoMount( values ) {
, title : shareddata ? 'Shared Data Server' : 'Add Network Storage'
, content : htmlmount
, values : values || [ 'cifs', '', ipsub, '', '', '', '', true ]
+ , checkblank : [ 0, 1, 2 ]
, beforeshow : function() {
$( '#infoContent td' ).eq( 0 ).css( 'width', 90 );
$( '#infoContent td' ).eq( 1 ).css( 'width', 230 );
@@ -952,7 +962,7 @@ function infoMount( values ) {
} );
$share.on( 'keyup paste', function() {
setTimeout( function() {
- var slash = $( '#infoContent input[type=radio]:checked' ).val() === 'cifs' ? /[\/\\]/g : /\\//g;
+ var slash = $( '#infoContent input[type=radio]:checked' ).val() === 'cifs' ? /[\/\\]/g : /\\/g;
$share.val( $share.val().replace( slash, '' ) );
}, 0 );
} );
@@ -1023,9 +1033,7 @@ function infoNFSconnect( ip ) {
$( '#shareddata' ).prop( 'checked', false );
}
, ok : function() {
- setTimeout( function() {
- infoNFSconnect( ip );
- },0 );
+ infoNFSconnect( ip );
}
} );
}
diff --git a/srv/http/bash/cmd.sh b/srv/http/bash/cmd.sh
index 8cfdf7a3a..f3e073689 100644
--- a/srv/http/bash/cmd.sh
+++ b/srv/http/bash/cmd.sh
@@ -114,11 +114,6 @@ jpgThumbnail() {
esac
pushstreamImage "$target" $type "$covername"
}
-mpdoledLogo() {
- systemctl stop mpd_oled
- type=$( grep mpd_oled /etc/systemd/system/mpd_oled.service | cut -d' ' -f3 )
- mpd_oled -o $type -L
-}
plAddPlay() {
pushstreamPlaylist add
if [[ ${1: -4} == play ]]; then
@@ -232,6 +227,7 @@ stopRadio() {
if [[ -e $dirshm/radio ]]; then
systemctl stop radio dab
rm -f $dirshm/{radio,status}
+ sleep 1
fi
}
urldecode() { # for webradio url to filename
@@ -364,12 +360,6 @@ webRadioSampling() {
case ${args[0]} in
-addonsclose )
- script=${args[1]}
- alias=${args[2]}
- killall $script curl pacman &> /dev/null
- rm -f /var/lib/pacman/db.lck /srv/http/*.zip $diraddons/$alias /usr/local/bin/uninstall_$alias.sh
- ;;
addonslist )
addonsListGet ${args[1]}
bash=$( jq -r .push.bash $diraddons/addons-list.json ) # push bash
@@ -522,9 +512,6 @@ s|(path.*hsl).*|\1(${hsg}75%);}|
sed -i -E 's/\?v=.{10}/?v='$hash'/g' /srv/http/settings/camillagui/build/index.html
pushstream reload 1
;;
-count )
- count
- ;;
coverartget )
path=${args[1]}
coverartfile=$( ls -1X "$path"/coverart.* 2> /dev/null \
@@ -613,20 +600,6 @@ dabscan )
$dirbash/dab-scan.sh &> /dev/null &
pushstream mpdupdate '{"type":"dabradio"}'
;;
-dirpermissions )
- chmod 755 /srv /srv/http /srv/http/* /mnt /mnt/MPD /mnt/MPD/*/
- chown http:http /srv /srv/http /srv/http/* /mnt /mnt/MPD /mnt/MPD/*/
- chmod -R 755 /srv/http/{assets,bash,data,settings}
- chown -R http:http /srv/http/{assets,bash,data,settings}
- chown mpd:audio $dirmpd $dirmpd/mpd.db $dirplaylists 2> /dev/null
- if [[ $( readlink $dirshareddata ) == $dirdata ]]; then
- chmod 777 $filesharedip $dirshareddata/system/{display,order}
- readarray -t dirs <<< $( showmount --no-headers -e localhost | awk 'NF{NF-=1};1' )
- for dir in "${dirs[@]}"; do
- chmod 777 "$dir"
- done
- fi
- ;;
displaysave )
data=${args[1]}
pushstream display "$data"
@@ -873,12 +846,12 @@ mpcplayback )
command=play
fi
fi
+ stopRadio
if [[ $command == play ]]; then
mpc | grep -q '^\[paused\]' && pause=1
mpc -q $command $pos
[[ $( mpc | head -c 4 ) == cdda && ! $pause ]] && pushstreamNotifyBlink 'Audio CD' 'Start play ...' audiocd
else
- stopRadio
[[ -e $dirsystem/scrobble && $command == stop && $pos ]] && cp -f $dirshm/{status,scrobble}
mpc -q $command
killall cava &> /dev/null
@@ -989,84 +962,11 @@ mpcupdate )
[[ $path == rescan ]] && mpc -q rescan || mpc -q update "$path"
pushstream mpdupdate '{"type":"mpd"}'
;;
-mpdoledlogo )
- mpdoledLogo
- ;;
ordersave )
data=$( jq <<< ${args[1]} )
pushstream order "$data"
echo "$data" > $dirsystem/order
;;
-partexpand )
- dev=$( mount | awk '/ on \/ / {printf $1}' | head -c -2 )
- if (( $( sfdisk -F $dev | head -1 | awk '{print $6}' ) != 0 )); then
- echo -e "d\n\nn\n\n\n\n\nw" | fdisk $dev &>/dev/null
- partprobe $dev
- resize2fs ${dev}p2
- fi
- ;;
-pkgstatus )
- id=${args[1]}
- pkg=$id
- service=$id
- case $id in
- camilladsp )
- fileconf=$dircamilladsp/configs/camilladsp.yml
- ;;
- hostapd )
- conf="\
-
# cat /etc/hostapd/hostapd.conf
-$( cat /etc/hostapd/hostapd.conf )
-
-
# cat /etc/dnsmasq.conf"
- ;;
- localbrowser )
- pkg=chromium
- fileconf=$dirsystem/localbrowser.conf
- ;;
- nfs-server )
- pkg=nfs-utils
- systemctl -q is-active nfs-server && fileconf=/etc/exports
- ;;
- rtsp-simple-server )
- conf="\
-# rtl_test -t
-$( script -c "timeout 1 rtl_test -t" | grep -v ^Script )"
- ;;
- smb )
- pkg=samba
- fileconf=/etc/samba/smb.conf
- ;;
- snapclient|snapserver )
- pkg=snapcast
- [[ $id == snapclient ]] && fileconf=/etc/default/snapclient
- ;;
- * )
- fileconf=/etc/$id.conf
- ;;
- esac
- config="$( pacman -Q $pkg )
"
- if [[ $conf ]]; then
- config+="
-$conf"
- elif [[ -e $fileconf ]]; then
- config+="
-# cat $fileconf
-$( grep -v ^# $fileconf )"
- fi
- status=$( systemctl status $service \
- | sed -E '1 s|^.* (.*service) |\1
|' \
- | sed -E '/^\s*Active:/ s|( active \(.*\))|\1|; s|( inactive \(.*\))|\1|; s|(failed)|\1|ig' )
- if [[ $pkg == chromium ]]; then
- status=$( echo "$status" | grep -E -v 'Could not resolve keysym|Address family not supported by protocol|ERROR:chrome_browser_main_extra_parts_metrics' )
- elif [[ $pkg == nfs-utils ]]; then
- status=$( echo "$status" | grep -v 'Protocol not supported' )
- fi
- echo "\
-$config
-
-$status"
- ;;
playerstart )
player=${args[1]}
[[ $player == bluetooth ]] && volumeGet save
@@ -1174,15 +1074,6 @@ radiorestart )
sleep 1
rm $disshm/radiorestart
;;
-rebootlist )
- [[ -e $dirshm/reboot ]] && cat $dirshm/reboot \
- | sort -u \
- | tr '\n' ^ \
- | head -c -1
- ;;
-refreshbrowser )
- pushstream reload 1
- ;;
relaystimerreset )
killall relays-timer.sh &> /dev/null
$dirbash/settings/relays-timer.sh &> /dev/null &
diff --git a/srv/http/bash/settings/features.sh b/srv/http/bash/settings/features.sh
index 291f26f05..884f23e7a 100644
--- a/srv/http/bash/settings/features.sh
+++ b/srv/http/bash/settings/features.sh
@@ -278,6 +278,7 @@ EOF
nfsserver )
active=${args[1]}
readarray -t dirs <<< $( nfsShareList )
+ mpc -q clear
if [[ $active == true ]]; then
ip=$( ipGet )
options="${ip%.*}.0/24(rw,sync,no_subtree_check)"
@@ -298,15 +299,14 @@ nfsserver )
mv -f $dirmpd $dirbackup
mv -f $dirbackup/mpdnfs $dirdata/mpd
systemctl restart mpd
- action=update
else
rm -f $dirmpd/{listing,updating}
mkdir -p $dirbackup
cp -r $dirmpd $dirbackup
- action=rescan
+ systemctl restart mpd
+ $dirbash/cmd.sh mpcupdate$'\n'rescan
fi
systemctl enable --now nfs-server
- $dirbash/cmd.sh mpcupdate$'\n'$action
else
systemctl disable --now nfs-server
rm -f /mnt/MPD/.mpdignore \
@@ -324,7 +324,6 @@ nfsserver )
mv -f $dirbackup/mpd $dirdata
mv -f $dirbackup/{display,order} $dirsystem
systemctl restart mpd
- $dirbash/cmd.sh mpcupdate$'\n'update
fi
pushRefresh
pushstream refresh '{"page":"system","nfsserver":'$active'}'
diff --git a/srv/http/bash/settings/system-datareset.sh b/srv/http/bash/settings/system-datareset.sh
index 9c9d48422..e1db5ec26 100644
--- a/srv/http/bash/settings/system-datareset.sh
+++ b/srv/http/bash/settings/system-datareset.sh
@@ -146,7 +146,7 @@ sed -i -e -E '/^auto_update|^audio_buffer_size| #custom$/ d
quality "very high"\
}
' /etc/mpd.conf
-curl -L https://github.com/rern/rAudio-addons/raw/main/webradio/radioparadise.tar.xz | bsdtar xvf - -C / # webradio default
+curl -L https://github.com/rern/rAudio-addons/raw/main/webradio/radioparadise.tar.xz | bsdtar xvf - -C $dirwebradio # webradio default
if [[ ! -e $dirmpd/counts ]]; then
echo '{
"playlists" : '$( ls -1 $dirplaylists | wc -l )'
@@ -160,7 +160,7 @@ usermod -a -G root http # add user http to group root to allow /dev/gpiomem acce
systemctl -q disable --now bluetooth hostapd shairport-sync smb snapserver spotifyd upmpdcli
# set ownership and permissions
-$dirbash/cmd.sh dirpermissions
+$dirbash/settings/system.sh dirpermissions
[[ $version ]] && exit
diff --git a/srv/http/bash/settings/system.sh b/srv/http/bash/settings/system.sh
index ca12d61e2..c8bf2f327 100644
--- a/srv/http/bash/settings/system.sh
+++ b/srv/http/bash/settings/system.sh
@@ -7,6 +7,20 @@ filemodule=/etc/modules-load.d/raspberrypi.conf
# convert each line to each args
readarray -t args <<< "$1"
+dirPermissions() {
+ chmod 755 /srv /srv/http /srv/http/* /mnt /mnt/MPD /mnt/MPD/*/
+ chown http:http /srv /srv/http /srv/http/* /mnt /mnt/MPD /mnt/MPD/*/
+ chmod -R 755 /srv/http/{assets,bash,data,settings}
+ chown -R http:http /srv/http/{assets,bash,data,settings}
+ chown mpd:audio $dirmpd $dirmpd/mpd.db $dirplaylists 2> /dev/null
+ if [[ $( readlink $dirshareddata ) == $dirdata ]]; then
+ chmod 777 $filesharedip $dirshareddata/system/{display,order}
+ readarray -t dirs <<< $( showmount --no-headers -e localhost | awk 'NF{NF-=1};1' )
+ for dir in "${dirs[@]}"; do
+ chmod 777 "$dir"
+ done
+ fi
+}
pushReboot() {
pushRefresh
pushstreamNotify "${1//\"/\\\"}" 'Reboot required.' system 5000
@@ -77,7 +91,7 @@ sharedDataSet() {
systemctl restart mpd
sharedDataIPlist
pushRefresh
- pusrstream refresh '{"page":"features","shareddata":true}'
+ pushstream refresh '{"page":"features","shareddata":true}'
}
soundProfile() {
if [[ $1 == reset ]]; then
@@ -236,7 +250,7 @@ datarestore )
mv $dirdata/{webradiosimg,webradio/img}
fi
# temp 20220808 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
- $dirbash/cmd.sh dirpermissions
+ dirPermissions
[[ -e $dirsystem/color ]] && $dirbash/cmd.sh color
uuid1=$( head -1 /etc/fstab | cut -d' ' -f1 )
uuid2=${uuid1:0:-1}2
@@ -278,6 +292,9 @@ datarestore )
grep -q /mnt/MPD/SD /etc/exports && $dirbash/settings/features.sh nfsserver$'\n'true
$dirbash/cmd.sh power$'\n'reboot
;;
+dirpermissions )
+ dirPermissions
+ ;;
hddinfo )
dev=${args[1]}
echo -n "\
@@ -495,6 +512,7 @@ mirrorlist )
}'
;;
mount )
+ ['mount', 'cifs', 'data', '192.168.1.9', 'data', '', '', '', true]
protocol=${args[1]}
mountpoint="/mnt/MPD/NAS/${args[2]}"
ip=${args[3]}
@@ -502,17 +520,14 @@ mount )
user=${args[5]}
password=${args[6]}
extraoptions=${args[7]}
- update=${args[8]}
- shareddata=${args[9]}
+ shareddata=${args[8]}
! ping -c 1 -w 1 $ip &> /dev/null && echo "IP address not found: $ip" && exit
- if [[ -e $mountpoint ]]; then
- [[ $( ls "$mountpoint" ) ]] && echo "Mount name $mountpoint
not empty." && exit
-
- else
- mkdir "$mountpoint"
- fi
+ [[ $( ls "$mountpoint" ) ]] && echo "Mount name $mountpoint
not empty." && exit
+
+ umount -ql "$mountpoint"
+ mkdir -p "$mountpoint"
chown mpd:audio "$mountpoint"
if [[ $protocol == cifs ]]; then
source="//$ip/$directory"
@@ -525,7 +540,7 @@ mount )
options+=,uid=$( id -u mpd ),gid=$( id -g mpd ),iocharset=utf8
else
source="$ip:$directory"
- options=defaults,noauto,bg,hard,intr,timeo=5
+ options=defaults,noauto,bg,soft,timeo=5
fi
[[ $extraoptions ]] && options+=,$extraoptions
fstab="\
@@ -548,7 +563,7 @@ ${source// /\\040} ${mountpoint// /\\040} $protocol ${options// /\\040} 0 0
sleep 1
mount | grep -q "$mountpoint" && break
done
- [[ $shareddata ]] && sharedDataSet || pushRefresh
+ [[ $shareddata == true ]] && sharedDataSet || pushRefresh
;;
mpdoleddisable )
rm $dirsystem/mpdoled
@@ -556,6 +571,11 @@ mpdoleddisable )
$dirbash/settings/player-conf.sh
pushRefresh
;;
+mpdoledlogo )
+ systemctl stop mpd_oled
+ type=$( grep mpd_oled /etc/systemd/system/mpd_oled.service | cut -d' ' -f3 )
+ mpd_oled -o $type -L
+ ;;
mpdoledset )
chip=${args[1]}
baud=${args[2]}
@@ -606,6 +626,68 @@ $description
fi
grep -B1 -A2 --no-group-separator "^${args[1],}" $filepackages
;;
+pkgstatus )
+ id=${args[1]}
+ pkg=$id
+ service=$id
+ case $id in
+ camilladsp )
+ fileconf=$dircamilladsp/configs/camilladsp.yml
+ ;;
+ hostapd )
+ conf="\
+# cat /etc/hostapd/hostapd.conf
+$( cat /etc/hostapd/hostapd.conf )
+
+# cat /etc/dnsmasq.conf"
+ ;;
+ localbrowser )
+ pkg=chromium
+ fileconf=$dirsystem/localbrowser.conf
+ ;;
+ nfs-server )
+ pkg=nfs-utils
+ systemctl -q is-active nfs-server && fileconf=/etc/exports
+ ;;
+ rtsp-simple-server )
+ conf="\
+# rtl_test -t
+$( script -c "timeout 1 rtl_test -t" | grep -v ^Script )"
+ ;;
+ smb )
+ pkg=samba
+ fileconf=/etc/samba/smb.conf
+ ;;
+ snapclient|snapserver )
+ pkg=snapcast
+ [[ $id == snapclient ]] && fileconf=/etc/default/snapclient
+ ;;
+ * )
+ fileconf=/etc/$id.conf
+ ;;
+ esac
+ config="$( pacman -Q $pkg )
"
+ if [[ $conf ]]; then
+ config+="
+$conf"
+ elif [[ -e $fileconf ]]; then
+ config+="
+# cat $fileconf
+$( grep -v ^# $fileconf )"
+ fi
+ status=$( systemctl status $service \
+ | sed -E '1 s|^.* (.*service) |\1
|' \
+ | sed -E '/^\s*Active:/ s|( active \(.*\))|\1|; s|( inactive \(.*\))|\1|; s|(failed)|\1|ig' )
+ if [[ $pkg == chromium ]]; then
+ status=$( echo "$status" | grep -E -v 'Could not resolve keysym|Address family not supported by protocol|ERROR:chrome_browser_main_extra_parts_metrics' )
+ elif [[ $pkg == nfs-utils ]]; then
+ status=$( echo "$status" | grep -v 'Protocol not supported' )
+ fi
+ echo "\
+$config
+
+$status"
+ ;;
powerbuttondisable )
if [[ -e $dirsystem/audiophonics ]]; then
rm $dirsystem/audiophonics
@@ -645,6 +727,10 @@ reserved=$reserved" > $dirsystem/powerbutton.conf
[[ $reserved != $prevreserved ]] && pushReboot 'Power Button'
fi
;;
+rebootlist )
+ killall networks-scan.sh &> /dev/null
+ [[ -e $dirshm/reboot ]] && cat $dirshm/reboot | sort -u
+ ;;
relaysdisable )
rm -f $dirsystem/relays
pushRefresh
@@ -729,8 +815,9 @@ shareddataconnect )
dir="/mnt/MPD/NAS/$( basename "$path" )"
[[ $( ls "$dir" ) ]] && echo "Directory not empty: $dir
" && exit
+ umount -ql "$dir"
done
- options="nfs defaults,noauto,bg,hard,intr,timeo=5 0 0"
+ options="nfs defaults,noauto,bg,soft,timeo=5 0 0"
fstab=$( cat /etc/fstab )
for path in "${paths[@]}"; do
dir="/mnt/MPD/NAS/$( basename "$path" )"
@@ -767,18 +854,23 @@ shareddatadisconnect )
rm -f $dirshareddata /mnt/MPD/NAS/.mpdignore
sed -i "/$( ipGet )/ d" $filesharedip
mpc -q clear
- ipserver=$( grep $dirshareddata /etc/fstab | cut -d: -f1 )
- readarray -t dirs <<< $( awk '/^'$ipserver'/ {print $2}' /etc/fstab | sed 's/\\040/ /g' )
+ if [[ $( readlink $dirshareddata ) == $dirdata ]]; then
+ ipserver=$( grep $dirshareddata /etc/fstab | cut -d: -f1 )
+ fstab=$( grep -v ^$ipserver /etc/fstab )
+ readarray -t dirs <<< $( awk '/^'$ipserver'/ {print $2}' /etc/fstab | sed 's/\\040/ /g' )
+ else
+ fstab=$( grep -v $dirshareddata /etc/fstab )
+ dirs=( $dirshareddata )
+ fi
for dir in "${dirs[@]}"; do
umount -l "$dir"
rmdir "$dir" &> /dev/null
done
- fstab=$( sed "/^$ipserver/ d" /etc/fstab )
echo "$fstab" | column -t > /etc/fstab
systemctl daemon-reload
systemctl restart mpd
pushRefresh
- pusrstream refresh '{"page":"features","shareddata":false}'
+ pushstream refresh '{"page":"features","shareddata":false}'
if [[ ! $disable ]]; then
echo $ipserver > $dirsystem/sharedipserver # for sshpass reconnect
pushstreamNotify 'Server rAudio' 'Offline ...' rserver
@@ -867,7 +959,10 @@ systemconfig )
$( cat /boot/cmdline.txt )
# cat /boot/config.txt
-$( cat /boot/config.txt )"
+$( cat /boot/config.txt )
+
+# bootloader and firmware
+$( pacman -Q firmware-raspberrypi linux-firmware raspberrypi-bootloader raspberrypi-firmware )"
file=/etc/modules-load.d/raspberrypi.conf
raspberrypiconf=$( cat $file )
if [[ $raspberrypiconf ]]; then
diff --git a/srv/http/bash/startup.sh b/srv/http/bash/startup.sh
index ad81c8043..9305d6c21 100644
--- a/srv/http/bash/startup.sh
+++ b/srv/http/bash/startup.sh
@@ -107,7 +107,7 @@ if [[ -e $dirsystem/lcdchar ]]; then
$dirbash/lcdcharinit.py
$dirbash/lcdchar.py logo
fi
-[[ -e $dirsystem/mpdoled ]] && $dirbash/cmd.sh mpdoledlogo
+[[ -e $dirsystem/mpdoled ]] && $dirbash/settings/system.sh mpdoledlogo
[[ -e $dirsystem/soundprofile ]] && $dirbash/settings/system.sh soundprofile
diff --git a/srv/http/bash/status-push.sh b/srv/http/bash/status-push.sh
index b697ee552..a8f57e2ac 100644
--- a/srv/http/bash/status-push.sh
+++ b/srv/http/bash/status-push.sh
@@ -91,6 +91,9 @@ fi
[[ -e $dirsystem/librandom && $webradio == false ]] && $dirbash/cmd.sh mpcaddrandom
+[[ $state == play ]] && playing=true || playing=false
+pushstream refresh '{"page":"features","playing":'$playing'}'
+
[[ ! $scrobble ]] && exit # must be last for $statusprev - webradio and state
. <( echo "$statusprev" )
diff --git a/srv/http/bash/status.sh b/srv/http/bash/status.sh
index 60c8f8d5b..4de204ace 100644
--- a/srv/http/bash/status.sh
+++ b/srv/http/bash/status.sh
@@ -315,12 +315,15 @@ $radiosampling" > $dirshm/radio
[[ ! $displaycover ]] && coverart=
fi
elif [[ $Title && $displaycover ]]; then
- # split Artist - Title: Artist - Title (extra tag) or Artist: Title (extra tag)
- readarray -t radioname <<< $( echo $Title | sed -E 's/ - |: /\n/' )
- Artist=${radioname[0]}
- Title=${radioname[1]}
+ if [[ $Title == *" - "* ]]; then # split 'Artist - Title' or 'Artist: Title' (extra tag)
+ readarray -t radioname <<< $( echo $Title | sed -E 's/ - |: /\n/' )
+ Artist=${radioname[0]}
+ Title=${radioname[1]}
+ else
+ Artist=$station
+ fi
# fetched coverart
- covername=$( echo "$Artist${Title/ (*}" | tr -d ' "`?/#&'"'" ) # remove ' (extra tag)'
+ covername=$( echo "$Artist${Title/ (*}" | tr -d ' "`?/#&'"'" ) # remove '... (extra tag)'
coverfile=$( ls $dirshm/webradio/$covername.* 2> /dev/null | head -1 )
if [[ $coverfile ]]; then
coverart=${coverfile:9}
@@ -331,10 +334,17 @@ $radiosampling" > $dirshm/radio
if [[ $displaycover ]]; then
filenoext=/data/webradio/img/$urlname
pathnoext=/srv/http$filenoext
- if [[ -e $pathnoext.gif ]]; then
- stationcover=$filenoext.$date.gif
- elif [[ -e $pathnoext.jpg ]]; then
- stationcover=$filenoext.$date.jpg
+ if [[ -e $pathnoext.jpg ]]; then
+ type=jpg
+ elif [[ -e $pathnoext.gif ]]; then
+ type=gif
+ fi
+ if [[ $type ]]; then
+ if [[ $urlname == *\?* ]]; then # cannot bust: url with ?param=...
+ stationcover=${filenoext//\?/%3F}.$type?v=$date
+ else
+ stationcover=$filenoext.$date.$type
+ fi
fi
fi
status=$( grep -E -v '^, *"state"|^, *"webradio".*true|^, *"webradio".*false' <<< "$status" )
diff --git a/srv/http/index-body.php b/srv/http/index-body.php
index 448a25483..617e08582 100644
--- a/srv/http/index-body.php
+++ b/srv/http/index-body.php
@@ -47,51 +47,6 @@
exit;
}
-
-// library home blocks
-$modes = [ 'Album', 'Artist', 'Album Artist', 'Composer', 'Conductor', 'Date', 'Genre', 'Latest', 'NAS', 'SD', 'USB', 'Playlists', 'Web Radio', 'DAB Radio' ];
-$htmlmode = '';
-foreach( $modes as $mode ) {
- $lipath = str_replace( ' ', '', $mode );
- $modeLC = strtolower( $lipath );
- $htmlmode.=
- '';
-}
-// bookmarks
-$dir = '/srv/http/data/bookmarks';
-$files = array_slice( scandir( $dir ), 2 ); // remove ., ..
-if ( count( $files ) ) {
- foreach( $files as $name ) {
- $data = file( $dir.'/'.str_replace( '|', '/', $name ), FILE_IGNORE_NEW_LINES );
- $bkpath = $data[ 0 ];
- $coverart = $data[ 1 ] ?? '';
- if ( $coverart ) {
- $coverart = substr( $coverart, 0, -3 ).time().substr( $coverart, -4 );
- $icon = '';
- } else {
- $icon = ''.$name.'';
- }
- $htmlmode.=
- '';
- }
-}
-if ( $_POST[ 'modelist' ] ) { // for refresh on page visible
- echo $htmlmode;
- exit;
-}
-
// context menus
function menucommon( $add, $replace ) {
$htmlcommon = 'Add';
@@ -365,7 +320,7 @@ function htmlmenu( $menulist, $mode ) {
-
diff --git a/srv/http/mpdlibrary.php b/srv/http/mpdlibrary.php
index f314587f4..e6b9a8a49 100644
--- a/srv/http/mpdlibrary.php
+++ b/srv/http/mpdlibrary.php
@@ -88,6 +88,47 @@
htmlFind( $lists, $f );
}
break;
+case 'home':
+ $modes = [ 'Album', 'Artist', 'Album Artist', 'Composer', 'Conductor', 'Date', 'Genre', 'Latest', 'NAS', 'SD', 'USB', 'Playlists', 'Web Radio', 'DAB Radio' ];
+ $htmlmode = '';
+ foreach( $modes as $mode ) {
+ $lipath = str_replace( ' ', '', $mode );
+ $modeLC = strtolower( $lipath );
+ $htmlmode.=
+ '
';
+ }
+ // bookmarks
+ $dir = '/srv/http/data/bookmarks';
+ $files = array_slice( scandir( $dir ), 2 ); // remove ., ..
+ if ( count( $files ) ) {
+ foreach( $files as $name ) {
+ $data = file( $dir.'/'.str_replace( '|', '/', $name ), FILE_IGNORE_NEW_LINES );
+ $bkpath = $data[ 0 ];
+ $coverart = $data[ 1 ] ?? '';
+ if ( $coverart ) {
+ $coverart = substr( $coverart, 0, -3 ).time().substr( $coverart, -4 );
+ $icon = '
';
+ } else {
+ $icon = '
'.$name.'';
+ }
+ $htmlmode.=
+ '
';
+ }
+ }
+ echo $htmlmode;
+ break;
case 'list':
$filemode = '/srv/http/data/mpd/'.$mode;
if ( $mode === 'album' && exec( 'grep "albumbyartist.*true" /srv/http/data/system/display' ) ) $filemode.= 'byartist';
@@ -424,13 +465,15 @@ function htmlRadio( $subdirs, $files, $dir ) {
usort( $array, function( $a, $b ) {
return strnatcasecmp( $a->sort, $b->sort );
} );
+ $time = time();
foreach( $array as $each ) {
$index = strtoupper( mb_substr( $each->sort, 0, 1, 'UTF-8' ) );
$indexes[] = $index;
$datacharset = $each->charset ? ' data-charset="'.$each->charset.'"' : '';
$url = $each->url;
$urlname = str_replace( '/', '|', $url );
- $thumbsrc = rawurlencode( '/data/'.$gmode.'/img/'.$urlname.'-thumb.'.time().'.jpg' );
+ $thumbsrc = '/data/'.$gmode.'/img/'.rawurlencode( $urlname ).'-thumb.';
+ $thumbsrc.= strpos( $urlname, '?' ) ? 'jpg?v='.$time : $time.'.jpg';
$liname = $each->name;
$name = $searchmode ? preg_replace( "/($string)/i", '
$1', $liname ) : $liname;
$html.= '
diff --git a/srv/http/mpdplaylist.php b/srv/http/mpdplaylist.php
index d896639dc..ecaa73a90 100644
--- a/srv/http/mpdplaylist.php
+++ b/srv/http/mpdplaylist.php
@@ -35,7 +35,7 @@
htmlSavedPlaylist();
break;
case 'load': // load saved playlist to current
- if ( $_POST[ 'replace' ] ) exec( 'mpc clear' );
+ if ( $_POST[ 'replace' ] ) exec( 'mpc -q clear' );
$name = $_POST[ 'name' ] ?? $argv[ 2 ]; // $argv - by import playlists
exec( 'mpc -q load "'.$name.'"' );
@@ -181,7 +181,7 @@ function htmlTrack( $lists, $plname = '' ) {
$class = 'file';
$discid = '';
$path = pathinfo( $file, PATHINFO_DIRNAME );
- $thumbsrc = '/mnt/MPD/'.rawurlencode( $path ).'/thumb.jpg' ; // replaced with icon on load error(faster than existing check)
+ $thumbsrc = '/mnt/MPD/'.rawurlencode( $path ).'/thumb.'.$time.'.jpg' ; // replaced with icon on load error(faster than existing check)
$icon = 'music';
$htmlicon = '';
} else {
@@ -228,7 +228,9 @@ function htmlTrack( $lists, $plname = '' ) {
}
if ( $stationname !== '' ) {
$notsaved = 0;
- $icon = '';
+ $thumbsrc = '/data/'.$type.'/img/'.rawurlencode( $urlname ).'-thumb.';
+ $thumbsrc.= strpos( $urlname, '?' ) ? 'jpg?v='.$time : $time.'.jpg';
+ $icon = '';
} else {
$notsaved = 1;
$icon = '';
diff --git a/srv/http/settings/features.php b/srv/http/settings/features.php
index 3a8bb661d..eb56eaca6 100644
--- a/srv/http/settings/features.php
+++ b/srv/http/settings/features.php
@@ -288,9 +288,11 @@
- Must be set to static IP address which should be set on router.
- Existing list in | I^library^I | I^usb^I USB | will display in | I^networks^I NAS | once update finished.
- On reboot / power off, Shared Data on clients will be temporarily disabled > re-enabled once the server is back online.
+
• rAudio Shared Data clients:
- | I^system^I System | Settings and Data | Shared Data I^networks^I | • rAudio
- Automatically setup: discover, connect shared files and data
+
• Windows NFS clients:
- Windows Features > Services for NFS > Client for NFS - Enable
- $fileexplorer
diff --git a/srv/http/settings/system.php b/srv/http/settings/system.php
index c3a2dad62..7cc91269e 100644
--- a/srv/http/settings/system.php
+++ b/srv/http/settings/system.php
@@ -92,15 +92,16 @@
] );
?>
- Icon context menu: Unmount / Re-mount / Forget / Info / Share
+
Context menu:
+
| | Info
+
| | Unmount, Re-mount, Forget (Hidden if Shared Data is enabled)
USB drives:
• Will be found and mounted automatically.
Network shares:
• Must be manually configured.
- • If mount failed, try in SSH terminal:
- (replace
YELLOW with actual values)
+ • If mount failed, try in SSH terminal: (replace
YELLOW with actual values)
mkdir -p "/mnt/MPD/NAS/NAME"
# CIFS: (no user - username=guest, no password - password="")
@@ -113,7 +114,7 @@
'HDD Sleep'
+ 'label' => 'Hard Drive Sleep'
, 'id' => 'hddsleep'
, 'icon' => 'screenoff'
, 'disabled' => 'HDD not support sleep'
@@ -124,7 +125,7 @@
htmlSetting( [
'label' => 'Hotplug Update'
, 'id' => 'usbautoupdate'
- , 'sublabel' => 'USB drives data'
+ , 'sublabel' => 'data on USB'
, 'icon' => 'refresh-library'
, 'setting' => false
, 'disabled' => $disabledusbautoupdate
@@ -203,7 +204,7 @@
, 'help' => <<< HTML
LCD module - display playback data
• Support 16x2 and 20x4 LCD modules.
-Iarning yl^I LCD with I²C backpack must be modified: 5V to 3.3V I²C and 5V LCD
+I^warning yl^I LCD with I²C backpack must be modified: 5V to 3.3V I²C and 5V LCD
HTML
]
, [
@@ -295,7 +296,7 @@
, 'help' => <<< HTML
I^gear^I
• NTP server: For time sync
- • Package mirror server: For system upgrade pacman -Syu
+ • Package mirror server
HTML
]
, [
@@ -349,10 +350,12 @@
- Data - Audio CD, bookmarks, lyrics, saved playlists and Web Radio
- Show / hide items
- Display order of Library home
- • rAudio as server:
+
+ • rAudio as server: (Alternative 1)
Server: | I^features^I Features | Server rAudio I^rserver^I |
Clients: | Shared Data I^networks^I | • rAudio |
- • Other servers:
+
+ • Other servers: (Alternative 2)
Server: Create a share for data with full permissions
- Linux: NFS 777, CIFS/SMB read only = no
- Windows: Everyone - Full Control (Sharing + Security)