-
${ artistname + ico( 'close close-root closebio' ) }
-
${ ico( 'genre i-lg' ) } ${ genre }${ backhtml }
+
${ ico( 'close close-root closebio' ) + name }
+
${ backhtml + ico( 'genre i-lg' ) +' '+ genre }
${ similarhtml }
${ content }
@@ -66,29 +65,36 @@ function bio( artist, getsimilar ) {
.scrollTop( 0 );
$.get( 'https://webservice.fanart.tv/v3/music/'+ data.mbid +'?api_key='+ V.apikeyfanart ).done( data => {
if ( 'error message' in data ) {
- loaderHide();
+ bioImageSet();
return
}
if ( 'musicbanner' in data && data.musicbanner[ 0 ].url ) $( '#biocontent' ).before( '
' )
+ var imageshtml = '';
if ( 'artistthumb' in data && data.artistthumb[ 0 ].url ) {
- var imageshtml = '';
data.artistthumb.forEach( el => imageshtml += '
' );
- $( '#biocontent .artist' )
- .before( '
'+ imageshtml +'
' )
- .prepend( '
' );
- bioTitleSet();
}
- loaderHide();
+ bioImageSet( imageshtml )
$( '#bio' ).scrollTop( 0 );
} ).fail( function() { // 404 not found
- loaderHide();
+ bioImageSet();
} );
} );
} );
}
-function bioTitleSet() {
+function bioImageSet( imageshtml ) {
var $artist = $( '#biocontent .artist' );
+ if ( ! imageshtml ) {
+ if ( $artist.text() !== S.Artist || ! S.coverart ) {
+ loaderHide();
+ return
+ }
+
+ imageshtml = '
';
+ }
+ $artist
+ .before( '
'+ imageshtml +'
' )
+ .prepend( '
' );
var titleafter = $artist.prev().prop('id') === 'bioimg';
if ( 'observer' in V ) V.observer.disconnect();
if ( V.wW < 481 ) {
@@ -102,6 +108,7 @@ function bioTitleSet() {
}
V.observer = new IntersectionObserver( entries => $( '#biotitleimg' ).toggleClass( 'hide', entries[ 0 ].isIntersecting ), options );
V.observer.observe( $( '#bioimg' )[ 0 ] );
+ loaderHide();
}
function blinkDot() {
if ( ! localhost ) return
@@ -295,14 +302,14 @@ function contextmenuLibrary( $li, $target ) {
$li.addClass( 'active' );
return
}
- var filemode = [ 'nas', 'sd', 'usb', 'dabradio', 'webradio' ].includes( V.mode );
+ var filemode = [ 'album', 'nas', 'sd', 'usb', 'dabradio', 'webradio' ].includes( V.mode );
$menu.find( '.playnext, .replace' ).toggleClass( 'hide', ! S.pllength );
$menu.find( '.replace' ).next().toggleClass( 'hide', ! S.pllength );
$menu.find( '.refresh-library' ).toggleClass( 'hide', ! ( 'updating_db' in S ) );
- $( '#menu-folder a:not(.sub)' ).toggleClass( 'hide', V.list.licover && ! filemode && V.mode !== 'album' );
+ $( '#menu-folder a:not(.sub)' ).toggleClass( 'hide', V.list.licover && ! filemode );
$menu.find( '.bookmark, .exclude, .update, .thumb' ).toggleClass( 'hide', ! filemode );
$menu.find( '.directory' ).toggleClass( 'hide', filemode );
- $menu.find( '.tag' ).toggleClass( 'hide', ! V.librarytrack || ! filemode );
+ $menu.find( '.tag' ).toggleClass( 'hide', ! V.librarytrack || ( ! filemode ) );
$menu.find( '.wredit' ).toggleClass( 'hide', V.mode !== 'webradio' );
$menu.find( '.wrdirrename' ).toggleClass( 'hide', V.mode.slice( -5 ) !== 'radio' );
$li.addClass( 'active' );
@@ -668,6 +675,12 @@ function infoLibraryOption() {
keys.forEach( ( k, i ) => $el[ k ] = $( '#infoContent input' ).eq( i ) );
$( '#infoContent tr' ).css( 'height', '36px' );
$( '#infoContent td' ).css( 'width', '294px' );
+ $el.fixedcover.prop( 'disabled', D.hidecover );
+ $el.albumbyartist.on( 'click', function() {
+ var enable = $( this ).prop( 'checked' );
+ if ( ! enable ) $el.albumyear.prop( 'checked', false );
+ $el.albumyear.prop( 'disabled', ! enable )
+ } );
$el.tapaddplay.on( 'click', function() {
if ( $( this ).prop( 'checked' ) ) $el.tapreplaceplay.prop( 'checked', false );
} );
@@ -678,9 +691,8 @@ function infoLibraryOption() {
var enable = $( this ).prop( 'checked' ) ? false : true;
$el.fixedcover
.prop( 'disabled', ! enable )
- .prop( 'checked', false );
+ .prop( 'checked', enable );
} );
- $el.fixedcover.prop( 'disabled', D.hidecover );
}
, ok : displaySave
} );
@@ -1148,10 +1160,9 @@ function renderLibrary() { // library home
renderLibraryCounts();
}
function renderLibraryCounts() {
- $( '.mode gr' ).toggleClass( 'hide', ! D.count );
var songs = C.song ? C.song.toLocaleString() + ico( 'music' ) : '';
$( '#li-count' ).html( songs );
- $.each( C, ( k, v ) => $( '#mode-'+ k ).find( 'gr' ).text( v ? v.toLocaleString() : '' ) );
+ $.each( C, ( k, v ) => $( '#mode-'+ k ).find( 'gr' ).html( v ? ' '+ v.toLocaleString() : '' ) );
}
function renderLibraryList( data ) { // V.librarylist
if ( V.librarylist && data.html === V.librarylisthtml ) {
@@ -1210,11 +1221,10 @@ function renderLibraryList( data ) { // V.librarylist
var hash = versionHash();
var html = data.html.replace( /\^\^\^/g, hash );
$( '#lib-mode-list' ).after( html ).promise().done( () => {
+ V.librarytrack = $( '#lib-list .li-icon' ).hasClass( 'i-music' );
if ( $( '.licover' ).length ) { // V.librarytrack
- V.librarytrack = true;
if ( $( '#liimg' ).attr( 'src' ).slice( 0, 16 ) === '/data/shm/online' ) $( '.licoverimg ' ).append( V.icoversave );
} else {
- V.librarytrack = false;
imageLoad( 'lib-list' );
}
$( '.liinfopath' ).toggleClass( 'hide', [ 'sd', 'nas', 'usb', 'webradio' ].includes( V.mode ) );
@@ -2038,11 +2048,15 @@ function volumeColorUnmute() {
$( '#mi-mute, #ti-mute' ).addClass( 'hide' );
}
function volumeUpDown( up ) {
- var vol = S.volume;
- up ? vol++ : vol--;
- if ( vol < 0 || vol > 100 ) return
+ up ? S.volume++ : S.volume--;
+ if ( S.volume < 0 || S.volume > 100 ) return
- $volumeRS.setValue( vol );
+ if ( D.volume ) {
+ $volumeRS.setValue( S.volume );
+ } else {
+ $( '#volume-text' ).text( S.volume );
+ $( '#volume-bar' ).css( 'width', S.volume +'%' );
+ }
var cmd = 'volumeupdn';
if ( S.btreceiver ) {
cmd += 'bt';
diff --git a/srv/http/assets/js/main.js b/srv/http/assets/js/main.js
index 2c21ecebd..6209ebb82 100644
--- a/srv/http/assets/js/main.js
+++ b/srv/http/assets/js/main.js
@@ -84,11 +84,11 @@ var chkdisplay = {
, label : 'Label'
}
, liboption : {
- albumbyartist : ico( 'album' ) +'
Album - Sort by artists'
+ albumbyartist : ico( 'album' ) +'
Album - Sort by artist'
+ , albumyear : ico( 'album' ) +'Sort by artist > year'
, tapaddplay : 'Select track
= '+ ico( 'play-plus infomenusub' ) +'
Add + Play'
, tapreplaceplay : 'Select track
= '+ ico( 'play-replace infomenusub' ) +'
Replace + Play'
, playbackswitch : 'Switch to Playback
on '+ ico( 'play-plus infomenusub' ) +'or '+ ico( 'play-replace infomenusub' )
- , '-' : ''
, backonleft : ico( 'arrow-left bl' ) +'Back button on left side'
, hidecover : 'Hide coverart band in tracks view'
, fixedcover : 'Fix coverart band on large screen'
@@ -397,8 +397,8 @@ $( '#displayplaylist' ).on( 'click', function() {
}
if ( 'coverTL' in V ) $( '#coverTL' ).trigger( 'click' );
var keys = Object.keys( chkplaylist );
- var values = [];
- keys.forEach( k => values.push( D[ k ] ) );
+ var values = {};
+ keys.forEach( k => values[ k ] = D[ k ] );
info( {
icon : 'playlist'
, title : 'Playlist'
@@ -680,24 +680,22 @@ $( '#volmute, #volM' ).on( 'click', function() {
$( '#voldn, #volup, #volT, #volB, #volL, #volR, #volume-band-dn, #volume-band-up' ).on( 'click', function( e ) {
local();
volumeUpDown( $( e.currentTarget ).hasClass( 'up' ) );
- if ( [ 'volume-band-dn', 'volume-band-up' ].includes( e.currentTarget.id ) ) $( '#volume-text, #volume-bar' ).removeClass( 'hide' );
+ if ( $( e.currentTarget ).hasClass( 'band' ) ) $( '#volume-text, #volume-bar' ).removeClass( 'hide' );
} ).on( 'touchend mouseup', function( e ) {
clearInterval( V.interval.volume );
- if ( ! $( '#volume-bar' ).hasClass( 'hide' ) ) {
+ if ( D.volume ) {
+ $( '#volume-text' ).text( S.volume );
+ $( '#volume-bar' ).css( 'width', S.volume +'%' );
+ } else {
+ $volumeRS.setValue( S.volume );
clearTimeout( V.volumebar );
V.volumebar = setTimeout( volumeBarHide, 3000 );
}
} ).press( function( e ) {
+ clearTimeout( V.volumebar );
+ if ( ! D.volume ) $( '#volume-bar, #volume-text' ).removeClass( 'hide' );
var up = $( e.currentTarget ).hasClass( 'up' );
- V.interval.volume = setInterval( () => {
- volumeUpDown( up );
- if ( $( e.currentTarget ).hasClass( 'band' ) ) {
- clearTimeout( V.volumebar );
- $( '#volume-bar, #volume-text' ).removeClass( 'hide' );
- $( '#volume-text' ).text( vol );
- $( '#volume-bar' ).css( 'width', vol +'%' );
- }
- }, 100 );
+ V.interval.volume = setInterval( () => volumeUpDown( up ), 100 );
} );
$( '#volume-text' ).on( 'click', function() { // mute / unmute
clearTimeout( V.volumebar );
@@ -1185,27 +1183,28 @@ $( '#lib-mode-list' ).on( 'click', function( e ) {
if ( V.mode === 'bookmark' ) return
if ( ! C[ V.mode ] && V.mode.slice( -5 ) !== 'radio' ) {
+ var json = {
+ icon : 'library'
+ , title : 'Library Database'
+ }
if ( V.mode === 'playlists' ) {
- var message = 'No saved playlists found.';
+ json.message = 'No saved playlists found.';
} else if ( V.mode === 'latest' ) {
- var message = 'No new albums added since last update.';
+ json.message = 'No new albums added since last update.';
} else {
- var message = 'Database not yet available in this mode.'
- +'
If music files already in SD, NAS or USB,'
- +'
import them to database:'
- +''
- }
- info( {
- icon : 'library'
- , title : 'Library Database'
- , message : message
- , okno : true
- , beforeshow : () => {
+ json.message = 'Database not yet available in this mode.'
+ +'
If music files already in SD, NAS or USB,'
+ +'
import them to database:'
+ +'';
+ json.okno = true;
+ json.beforeshow = () => {
$( '#infoContent' ).on( 'click', '.submenu', function() {
$( '#update' ).trigger( 'click' );
} );
}
- } );
+ }
+ info( json );
return
}
@@ -1433,7 +1432,7 @@ $( '#page-library' ).on( 'click', '#lib-list .coverart', function() {
list( query, function( html ) {
var data = {
html : html
- , modetitle : $this.find( D.albumbyartist ? '.coverart2' : '.coverart1' ).text()
+ , modetitle : $this.find( '.liname' ).text()
, path : 'ALBUM'
}
renderLibraryList( data );
diff --git a/srv/http/assets/js/networks.js b/srv/http/assets/js/networks.js
index e2c605452..aa36adde1 100644
--- a/srv/http/assets/js/networks.js
+++ b/srv/http/assets/js/networks.js
@@ -141,16 +141,21 @@ $( '.disconnect' ).on( 'click', function() {
var ssid = V.li.data( 'ssid' );
var icon = 'wifi';
- info( {
- icon : icon
- , title : ssid
- , message : ( S.listeth ? '' : iconwarning +'No network connections after this.
' ) +'Disconnect?'
- , okcolor : orange
- , ok : () => {
- notify( icon, ssid, 'Disconnect ...' );
- bash( [ 'disconnect' ] )
- }
- } );
+ if ( S.ipeth ) {
+ notify( icon, ssid, 'Disconnect ...' );
+ bash( [ 'disconnect' ] )
+ } else {
+ info( {
+ icon : icon
+ , title : ssid
+ , message : ( S.listeth ? '' : iconwarning +'No network connections after this.
' ) +'Disconnect?'
+ , okcolor : orange
+ , ok : () => {
+ notify( icon, ssid, 'Disconnect ...' );
+ bash( [ 'disconnect' ] )
+ }
+ } );
+ }
} );
$( '.edit' ).on( 'click', function() {
V.listid === 'listwl' ? infoWiFiGet() : infoLan();
diff --git a/srv/http/assets/js/passive.js b/srv/http/assets/js/passive.js
index bda47d4e3..a1e510611 100644
--- a/srv/http/assets/js/passive.js
+++ b/srv/http/assets/js/passive.js
@@ -129,6 +129,8 @@ function psDisplay( data ) {
return
}
+ var albumlistchanged = D.albumbyartist !== data.albumbyartist || D.albumyear !== data.albumyear;
+ var hidecoverchanged = D.hidecover !== data.hidecover;
$.each( data, ( k, v ) => { D[ k ] = v } ); // need braces
V.coverdefault = ! D.covervu && ! D.vumeter ? V.coverart : V.covervu;
if ( ! D.covervu && ! D.vumeter ) {
@@ -144,22 +146,24 @@ function psDisplay( data ) {
} else if ( V.library ) {
if ( ! V.librarylist ) {
renderLibrary();
- } else if ( $( '.li-icon' ).eq( 0 ).hasClass( 'i-music' ) ) {
- if ( D.hidecover ) {
- $( '.licover' ).remove();
- } else {
- var query = V.query.slice( -1 )[ 0 ];
- list( query, function( html ) {
- var data = {
- html : html
- , modetitle : query.modetitle
- , path : query.path
- }
- renderLibraryList( data );
- } );
+ } else {
+ $( '#button-lib-back' ).toggleClass( 'back-left', D.backonleft );
+ if ( V.librarytrack ) {
+ if ( hidecoverchanged ) {
+ var query = V.query.slice( -1 )[ 0 ];
+ list( query, function( html ) {
+ var data = {
+ html : html
+ , modetitle : query.modetitle
+ , path : query.path
+ }
+ renderLibraryList( data );
+ } );
+ }
+ } else if ( V.mode === 'album' ) {
+ if ( albumlistchanged ) $( '#mode-album' ).trigger( 'click' );
}
}
- $( '#button-lib-back' ).toggleClass( 'back-left', D.backonleft );
}
}
function psEqualizer( data ) {
diff --git a/srv/http/assets/js/system.js b/srv/http/assets/js/system.js
index 3e0b11530..07d57f5ad 100644
--- a/srv/http/assets/js/system.js
+++ b/srv/http/assets/js/system.js
@@ -452,7 +452,7 @@ $( '#setting-tft' ).on( 'click', function() {
, 'Waveshare (B) Rev 2.0' : 'waveshare35b-v2'
, 'Waveshare (C)' : 'waveshare35c'
}
- , values : S.tftconf || 'tft35a'
+ , values : { MODEL: S.tftconf || 'tft35a' }
, checkchanged : S.tft
, boxwidth : 190
, buttonlabel : ! buttoncalibrate ? '' : 'Calibrate'
diff --git a/srv/http/bash/cmd-list.sh b/srv/http/bash/cmd-list.sh
index fd3c543aa..32fabf7e8 100644
--- a/srv/http/bash/cmd-list.sh
+++ b/srv/http/bash/cmd-list.sh
@@ -33,7 +33,7 @@ touch $dirmpd/listing
##### normal list #############################################
listAll() {
- mpc -f '%album%^^[%albumartist%|%artist%]^^%file%' listall 2> /dev/null \
+ mpc -f '[%albumartist%|%artist%]^^%date%^^%album%^^%file%' listall 2> /dev/null \
| awk -F'/[^/]*$' 'NF && !/^\^/ {print $1}' \
| sort -u
# -F'/[^/]*$' - truncate %file% to path without filename
@@ -71,7 +71,7 @@ if [[ ! $album_artist_file ]]; then # very large database
fi
if [[ $albums ]]; then
for album in "${albums[@]}"; do
- album_artist_file+=$( mpc -f '%album%^^[%albumartist%|%artist%]^^%file%' find album "$album" \
+ album_artist_file+=$( mpc -f '[%albumartist%|%artist%]^^%date^^%album%^^%file%' find album "$album" \
| awk -F'/[^/]*$' 'NF && !/^\^/ && !a[$0]++ {print $1}' \
| sort -u )$'\n'
done
@@ -103,7 +103,7 @@ fi
filealbum=$dirmpd/album
filealbumprev=$dirmpd/albumprev
-if [[ $( awk NF $dirmpd/album ) && $( getContent $dirmpd/updating ) != rescan ]]; then
+if [[ -s $filealbum && $( getContent $dirmpd/updating ) != rescan ]]; then
cp -f $filealbum{,prev}
else
> $dirmpd/latest
@@ -113,6 +113,7 @@ fi
for mode in album albumartist artist composer conductor genre date; do
filemode=$dirmpd/$mode
if [[ $mode == album ]]; then
+ filemode+=byartist-year
album=$( awk NF <<< $album_artist_file | sort -uf )
if [[ -e $dirmpd/albumignore ]]; then
readarray -t albumignore < $dirmpd/albumignore
@@ -120,7 +121,7 @@ for mode in album albumartist artist composer conductor genre date; do
album=$( sed "/^$line^/ d" <<< $album )
done
fi
- album=$( awk NF <<< $album | tee $filealbum | wc -l )
+ album=$( awk NF <<< $album | tee $filemode | wc -l )
else
printf -v $mode '%s' $( mpc list $mode | awk NF | awk '{$1=$1};1' | tee $filemode | wc -l )
fi
@@ -139,7 +140,7 @@ if [[ -e $filealbumprev ]]; then # latest
mv -f $dirmpd/latest{new,}
fi
fi
- [[ -e $dirmpd/latest ]] && latest=$( wc -l < $dirmpd/latest ) || latest=0
+ latest=$( wc -l < $dirmpd/latest )
fi
##### count #############################################
dabradio=$( find -L $dirdata/dabradio -type f ! -path '*/img/*' 2> /dev/null | wc -l ) # no $dirdabradio if dab not installed
diff --git a/srv/http/bash/cmd-listsort.php b/srv/http/bash/cmd-listsort.php
index 325b4004b..5fa5aede5 100644
--- a/srv/http/bash/cmd-listsort.php
+++ b/srv/http/bash/cmd-listsort.php
@@ -16,7 +16,7 @@ function stripSort( $str ) {
);
if ( !preg_match( '/[\x80-\xff]/', $string ) ) return $string;
- // strip accents
+ // strip accents: https://stackoverflow.com/a/10790734
$chars = array(
// Decompositions for Latin-1 Supplement
chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
@@ -26,27 +26,30 @@ function stripSort( $str ) {
chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
- chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
+ chr(195).chr(143) => 'I',
+ chr(195).chr(145) => 'N',
chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
- chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
- chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
- chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
- chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
- chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
+ chr(195).chr(156) => 'U',
+ chr(195).chr(157) => 'Y',
+ chr(195).chr(159) => 's',
+ chr(195).chr(160) => 'a', chr(195).chr(161) => 'a',
+ chr(195).chr(162) => 'a', chr(195).chr(163) => 'a',
+ chr(195).chr(164) => 'a', chr(195).chr(165) => 'a',
+ chr(195).chr(167) => 'c',
chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
- chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
- chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
- chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
- chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
- chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
- chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
- chr(195).chr(191) => 'y',
+ chr(195).chr(177) => 'n',
+ chr(195).chr(178) => 'o', chr(195).chr(179) => 'o',
+ chr(195).chr(180) => 'o', chr(195).chr(181) => 'o',
+ chr(195).chr(182) => 'o', chr(195).chr(182) => 'o',
+ chr(195).chr(185) => 'u', chr(195).chr(186) => 'u',
+ chr(195).chr(187) => 'u', chr(195).chr(188) => 'u',
+ chr(195).chr(189) => 'y', chr(195).chr(191) => 'y',
// Decompositions for Latin Extended-A
chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
@@ -90,12 +93,12 @@ function stripSort( $str ) {
chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
- chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
- chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
- chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
- chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
- chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
- chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
+ chr(197).chr(148) => 'R', chr(197).chr(149) => 'r',
+ chr(197).chr(150) => 'R', chr(197).chr(151) => 'r',
+ chr(197).chr(152) => 'R', chr(197).chr(153) => 'r',
+ chr(197).chr(154) => 'S', chr(197).chr(155) => 's',
+ chr(197).chr(156) => 'S', chr(197).chr(157) => 's',
+ chr(197).chr(158) => 'S', chr(197).chr(159) => 's',
chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
@@ -113,41 +116,53 @@ function stripSort( $str ) {
chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
chr(197).chr(190) => 'z', chr(197).chr(191) => 's'
);
- return strtr( $string, $chars );
+ $string = strtr($string, $chars);
+
+ return $string;
}
if ( isset( $argv[ 1 ] ) ) {
- $file = $argv[ 1 ];
+ $file = $argv[ 1 ];
$lines = file( $file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
- $sort = [];
- if ( $file === '/srv/http/data/mpd/album' ) {
- $sort1 = [];
+ $sort = [];
+ if ( $file === '/srv/http/data/mpd/albumbyartist-year' ) {
+ $byalbumsort = [];
+ $byartistsort = [];
foreach( $lines as $line ) {
if ( substr( $line, -4 ) === '.cue' ) $line = dirname( $line );
- $sort[] = stripSort( $line ).'^x^'.$line;
- $data1 = explode( '^^', $line );
- $line1 = $data1[ 1 ].'^^'.$data1[ 0 ].'^^'.$data1[ 2 ];
- $sort1[] = stripSort( $line1 ).'^x^'.$line1;
+ $sort[] = stripSort( $line ).'^x^'.$line;
+ $data = explode( '^^', $line ); // artist date album file
+ $byalbumline = $data[ 2 ].'^^'.$data[ 0 ].'^^'.$data[ 3 ];
+ $byalbumsort[] = stripSort( $byalbumline ).'^x^'.$byalbumline;
+ $byartistline = $data[ 0 ].'^^'.$data[ 2 ].'^^'.$data[ 3 ];
+ $byartistsort[] = stripSort( $byartistline ).'^x^'.$byartistline;
}
- usort( $sort1, function( $a, $b ) {
+ usort( $byalbumsort, function( $a, $b ) {
return strnatcasecmp( $a, $b );
} );
- $array1 = [];
- foreach( $sort1 as $line ) {
- $index = mb_substr( $line, 0, 1, 'UTF-8' );
- $array1[] = $index.'^^'.explode( '^x^', $line )[ 1 ];
+ $byalbum = [];
+ foreach( $byalbumsort as $line ) {
+ $index = mb_substr( $line, 0, 1, 'UTF-8' );
+ $byalbum[] = $index.'^^'.explode( '^x^', $line )[ 1 ];
}
- file_put_contents( $file.'byartist', implode( "\n", $array1 ) );
- } else {
- foreach( $lines as $line ) {
- $sort[] = stripSort( $line ).'^x^'.$line;
+ file_put_contents( '/srv/http/data/mpd/album', implode( "\n", $byalbum ) );
+ usort( $byartistsort, function( $a, $b ) {
+ return strnatcasecmp( $a, $b );
+ } );
+ $byartist = [];
+ foreach( $byartistsort as $line ) {
+ $index = mb_substr( $line, 0, 1, 'UTF-8' );
+ $byartist[] = $index.'^^'.explode( '^x^', $line )[ 1 ];
}
+ file_put_contents( '/srv/http/data/mpd/albumbyartist', implode( "\n", $byartist ) );
+ } else {
+ foreach( $lines as $line ) $sort[] = stripSort( $line ).'^x^'.$line;
}
usort( $sort, function( $a, $b ) {
return strnatcasecmp( $a, $b );
} );
$array = [];
foreach( $sort as $line ) {
- $index = mb_substr( $line, 0, 1, 'UTF-8' );
+ $index = mb_substr( $line, 0, 1, 'UTF-8' );
$array[] = $index.'^^'.explode( '^x^', $line )[ 1 ];
}
file_put_contents( $file, implode( "\n", $array ) );
diff --git a/srv/http/bash/cmd.sh b/srv/http/bash/cmd.sh
index 9d1087d2e..a82523718 100644
--- a/srv/http/bash/cmd.sh
+++ b/srv/http/bash/cmd.sh
@@ -71,18 +71,12 @@ pushstreamVolume() {
pushstream volume '{ "type": "'$1'", "val": '$2' }'
}
rotateSplash() {
- local degree rotate
+ local rotate
rotate=$( getVar rotate $dirsystem/localbrowser.conf )
- case $rotate in
- NORMAL ) degree=0;;
- CCW ) degree=-90;;
- CW ) degree=90;;
- UD ) degree=180;;
- esac
convert \
-density 48 \
-background none $dirimg/icon.svg \
- -rotate $degree \
+ -rotate $rotate \
-gravity center \
-background '#000' \
-extent 1920x1080 \
@@ -331,6 +325,11 @@ dabscan )
;;
display )
pushstream display $( < $dirsystem/display.json )
+ # temp
+ if grep -q albumyear.*true $dirsystem/display.json && [[ ! -e $dirmpd/albumbyartist-year ]]; then
+ pushstream mpdupdate '{ "type": "mpd" }'
+ $dirbash/cmd-list.sh &> /dev/null &
+ fi
[[ -e $dirsystem/vumeter ]] && prevvumeter=1
grep -q -m1 vumeter.*true $dirsystem/display.json && touch $dirsystem/vumeter && vumeter=1
[[ $prevvumeter == $vumeter ]] && exit
@@ -910,7 +909,7 @@ wrdirdelete )
wrdirnew )
[[ $DIR ]] && path="$dirwebradio/$DIR/$SUB" || path="$dirwebradio/$SUB"
mkdir -p "$path"
- chown http:http "$path"
+ chown -h http:http "$path"
chmod 755 "$path"
pushstreamRadioList
;;
diff --git a/srv/http/bash/common.sh b/srv/http/bash/common.sh
index 223cd6ee7..1827fa6a8 100644
--- a/srv/http/bash/common.sh
+++ b/srv/http/bash/common.sh
@@ -222,6 +222,18 @@ packageActive() {
(( i++ ))
done
}
+package() {
+ file=$( dialog --colors --no-shadow --no-collapse --output-fd 1 --nocancel --menu "
+Package:
+" 8 0 0 \
+1 Build \
+2 'Update repo' )
+ case $file in
+ 1 ) file=pkgbuild;;
+ 2 ) file=repoupdate;;
+ esac
+ bash <( curl -L https://github.com/rern/rern.github.io/raw/main/$file.sh )
+}
pushRefresh() {
local page push
[[ $1 ]] && page=$1 || page=$( basename $0 .sh )
diff --git a/srv/http/bash/settings/features-data.sh b/srv/http/bash/settings/features-data.sh
index 309673a7b..472946333 100644
--- a/srv/http/bash/settings/features-data.sh
+++ b/srv/http/bash/settings/features-data.sh
@@ -65,9 +65,7 @@ fi
, "upmpdcli" : '$upmpdcli'
, "upmpdcliconf" : { "OWNQUEUE": '$( grep -q -m1 'ownqueue = 1' /etc/upmpdcli.conf && echo true || echo false )' }'
if [[ -e /etc/systemd/system/localbrowser.service ]]; then
- if [[ ! -e /tmp/localbrowser.conf ]]; then
- [[ -e $dirsystem/localbrowser.conf ]] && cp $dirsystem/localbrowser.conf /tmp || touch /tmp/localbrowser.conf
- fi
+ [[ ! -e /tmp/localbrowser.conf && -e $dirsystem/localbrowser.conf ]] && cp $dirsystem/localbrowser.conf /tmp
data+='
, "brightness" : '$( getContent /sys/class/backlight/rpi_backlight/brightness )'
, "localbrowser" : '$localbrowser'
diff --git a/srv/http/bash/settings/features.sh b/srv/http/bash/settings/features.sh
index 118716d7b..a347f4431 100644
--- a/srv/http/bash/settings/features.sh
+++ b/srv/http/bash/settings/features.sh
@@ -25,7 +25,7 @@ localbrowserXset() {
local off
. $dirsystem/localbrowser.conf
export DISPLAY=:0
- off=$(( $SCREENOFF * 60 ))
+ off=$(( $screenoff * 60 ))
xset s off
xset dpms $off $off $off
if [[ $off == 0 ]]; then
@@ -139,14 +139,6 @@ lastfmkey )
;;
localbrowser )
if [[ $ON ]]; then
- file=$dirsystem/localbrowser.conf
- diff=$( grep -Fxvf $file /tmp/localbrowser.conf )
- if [[ $diff ]]; then
- for k in cursor rotate screenoff zoom; do
- grep -q -m1 ^$k <<< $diff && printf -v diff$k '%s' 1
- done
- [[ $diffcursor || $diffzoom ]] && restart=1
- fi
if ! grep -q console=tty3 /boot/cmdline.txt; then
sed -i -E 's/(console=).*/\1tty3 quiet loglevel=0 logo.nologo vt.global_cursor_default=0/' /boot/cmdline.txt
systemctl disable --now getty@tty1
@@ -164,31 +156,42 @@ localbrowser )
sed -i '/hdmi_force_hotplug=1/ d' /boot/config.txt
pushstream refresh '{ "page": "system", "hdmi": false }'
fi
- if [[ $diffrotate ]]; then
- case $ROTATE in
- NORMAL ) degree=0;;
- CCW ) degree=270 && matrix='0 1 0 -1 0 1 0 0 1';;
- CW ) degree=90 && matrix='0 -1 1 1 0 0 0 0 1';;
- UD ) degree=180 && matrix='-1 0 1 0 -1 1 0 0 1';;
- esac
- $dirbash/cmd.sh rotatesplash
- if grep -E -q 'waveshare|tft35a' /boot/config.txt; then
- sed -i -E '/waveshare|tft35a/ s/(rotate=).*/\1'$degree'/' /boot/config.txt
- cp -f /etc/X11/{lcd$degree,xorg.conf.d/99-calibration.conf}
- pushRefresh
- if ! grep -q rotate=$ROTATE /tmp/localbrowser.conf; then
- echo Rotate GPIO LCD screen >> $dirshm/reboot
- notify lcd 'Rotate GPIO LCD screen' 'Reboot required.' 5000
- exit
- fi
+ if [[ -e /tmp/localbrowser.conf ]]; then
+ diff=$( grep -Fxvf $dirsystem/localbrowser.conf /tmp/localbrowser.conf )
+ if [[ $diff ]]; then
+ for k in cursor rotate screenoff zoom; do
+ grep -q -m1 ^$k <<< $diff && printf -v diff$k '%s' 1
+ done
+ [[ $diffcursor || $diffzoom ]] && restart=1
fi
-
+ else
restart=1
+ fi
+ if grep -E -q 'waveshare|tft35a' /boot/config.txt; then # tft
+ sed -i -E '/waveshare|tft35a/ s/(rotate=).*/\1'$ROTATE'/' /boot/config.txt
+ cp -f /etc/X11/{lcd$ROTATE,xorg.conf.d/99-calibration.conf}
+ if [[ ! -e /tmp/localbrowser.conf || $diffrotate ]]; then
+ echo Rotate GPIO LCD screen >> $dirshm/reboot
+ notify lcd 'Rotate GPIO LCD screen' 'Reboot required.' 5000
+ exit
+
+ fi
+ else # hdmi
rotateconf=/etc/X11/xorg.conf.d/99-raspi-rotate.conf
- if [[ $matrix ]]; then
- sed 's/ROTATION_SETTING/'$ROTATE'/; s/MATRIX_SETTING/'$matrix'/' /etc/X11/xinit/rotateconf > $rotateconf
- else
- rm -f $rotateconf
+ [[ -e $rotateconf ]] && rotateprev=$( awk '/rotate/ {print $NF}' $rotateconf | tr -d '"' )
+ case $ROTATE in
+ 0 ) rotate=NORMAL;;
+ 270 ) rotate=CCW && matrix='0 1 0 -1 0 1 0 0 1';;
+ 90) rotate=CW && matrix='0 -1 1 1 0 0 0 0 1';;
+ 180) rotate=UD && matrix='-1 0 1 0 -1 1 0 0 1';;
+ esac
+ if [[ $rotateprev != $rotate ]]; then
+ if [[ $ROTATE == 0 ]]; then
+ rm -f $rotateconf
+ else
+ sed "s/ROTATION_SETTING/$rotate/; s/MATRIX_SETTING/$matrix/" /etc/X11/xinit/rotateconf > $rotateconf
+ fi
+ $dirbash/cmd.sh rotatesplash
fi
fi
if [[ $diffscreenoff ]]; then
@@ -197,13 +200,13 @@ localbrowser )
fi
if [[ $restart ]] || ! systemctl -q is-active localbrowser; then
restartlocalbrowser=1
- systemctl restart bootsplash localbrowser
+ systemctl restart bootsplash localbrowser &> /dev/null
fi
else
localbrowserDisable
fi
- pushRefresh
if [[ $restartlocalbrowser ]]; then
+ sleep 2
if systemctl -q is-active localbrowser; then
systemctl enable bootsplash localbrowser
systemctl stop bluetoothbutton
@@ -213,6 +216,7 @@ localbrowser )
localbrowserDisable
fi
fi
+ pushRefresh
;;
localbrowserreload )
pushstream reload 1
diff --git a/srv/http/bash/settings/networks-data.sh b/srv/http/bash/settings/networks-data.sh
index eeab0baa6..a2d0488fe 100644
--- a/srv/http/bash/settings/networks-data.sh
+++ b/srv/http/bash/settings/networks-data.sh
@@ -71,7 +71,7 @@ if [[ $1 == pushwl ]]; then
fi
# bluetooth
-rfkill | grep -q -m1 bluetooth && systemctl -q is-active bluetooth && activebt=1
+rfkill | grep -q -m1 bluetooth && systemctl -q is-active bluetooth && activebt=true
[[ $activebt ]] && listbt=$( listBluetooth )
# wlan
@@ -81,11 +81,10 @@ rfkill | grep -q -m1 bluetooth && systemctl -q is-active bluetooth && activebt=1
ifconfiglan=$( ifconfig | grep -A1 ^e )
[[ $ifconfiglan ]] && ipeth=$( grep inet <<< $ifconfiglan | awk '{print $2}' )
if [[ $ipeth ]]; then
- ipr=$( ip r | grep ^default.*$lan )
+ landev=$( grep ^e <<< $ifconfiglan | cut -d: -f1 )
+ ipr=$( ip r | grep ^default.*$landev )
static=$( [[ $ipr != *"dhcp src $ipeth "* ]] && echo true )
gateway=$( cut -d' ' -f3 <<< $ipr )
-# dns=$( sed -n '/^nameserver/ {s/.* //;p}' /etc/resolv.conf )
-# subnet=$( ifconfig $lan | awk '/netmask/ {print $4}' )
[[ ! $gateway ]] && gateway=$( ip r | awk '/^default/ {print $3;exit}' )
if [[ $ipeth ]]; then
hostname=$( avahi-resolve -a4 $ipeth | awk '{print $NF}' )
diff --git a/srv/http/bash/settings/player-conf.sh b/srv/http/bash/settings/player-conf.sh
index 76d008f64..8fe860ebf 100644
--- a/srv/http/bash/settings/player-conf.sh
+++ b/srv/http/bash/settings/player-conf.sh
@@ -147,9 +147,7 @@ if [[ -e $dirmpd/updating ]]; then
[[ $path == rescan ]] && mpc rescan || mpc update "$path"
fi
-if [[ -e $dirshm/btreceiver && -e $dirsystem/autoplay ]]; then
- grep -q bluetooth=true $dirsystem/autoplay.conf && mpc -q play
-fi
+[[ -e $dirshm/btreceiver ]] && grep -q bluetooth=true $dirsystem/autoplay.conf && mpc -q play
[[ $outputswitch ]] && notify output 'Audio Output' "$outputswitch"
diff --git a/srv/http/bash/settings/player-devices.sh b/srv/http/bash/settings/player-devices.sh
index e3e0983e8..bfe4d88d5 100644
--- a/srv/http/bash/settings/player-devices.sh
+++ b/srv/http/bash/settings/player-devices.sh
@@ -51,7 +51,12 @@ for line in "${aplay[@]}"; do
card=${cnd[0]}
aplayname=${cnd[1]}
device=${cnd[2]}
- [[ ${aplayname:0:8} == snd_rpi_ ]] && aplayname=$( tr _ - <<< ${aplayname:8} ) # some snd_rpi_xxx_yyy > xxx-yyy
+ if [[ ${aplayname:0:8} == snd_rpi_ ]]; then
+ aplayname=$( tr _ - <<< ${aplayname:8} ) # some snd_rpi_xxx_yyy > xxx-yyy
+ elif grep -q "aplayname.*$aplayname" <<< $devices; then # rpi4: hdmi1 + hdmi1 > hdmi1 + hdmi2
+ lastchar=${aplayname: -1}
+ [[ $lastchar =~ [0-9] ]] && aplayname=${aplayname:0:-1}$(( $lastchar + 1 ))
+ fi
if [[ $aplayname == Loopback ]]; then
device=; hwmixer=; mixers=; mixerdevices=; mixertype=; name=;
devices+=',{
diff --git a/srv/http/bash/settings/player.sh b/srv/http/bash/settings/player.sh
index 11d1b1b14..dc394609d 100644
--- a/srv/http/bash/settings/player.sh
+++ b/srv/http/bash/settings/player.sh
@@ -165,11 +165,10 @@ statusalbumignore )
statusbtreceiver )
mac=$( cut -d' ' -f1 $dirshm/btconnected )
echo "\
-# bluealsa-aplay -L
-$( bluealsa-aplay -L | grep -A2 $mac )
+$( pacman -Q bluealsa )
-# bluetoothctl info $mac
-$( bluetoothctl info $mac )"
+# bluealsa-aplay -L
+$( bluealsa-aplay -L | grep -A2 $mac )"
;;
statusmpdignore )
file=$dirmpd/mpdignorelist
diff --git a/srv/http/bash/settings/system-data.sh b/srv/http/bash/settings/system-data.sh
index 5e352342b..c573fc67e 100644
--- a/srv/http/bash/settings/system-data.sh
+++ b/srv/http/bash/settings/system-data.sh
@@ -57,6 +57,7 @@ else
if [[ $rpimodel == *BeagleBone* ]]; then
soc=AM3358
else
+ . $dirshm/cpuinfo
soc=BCM
case $C in
0 ) soc+=2835;; # 0, 1
@@ -242,7 +243,7 @@ data+='
, "rotaryencoder" : '$rotaryencoder'
, "rotaryencoderconf" : '$( conf2json rotaryencoder.conf )'
, "rpi01" : '$( exists /boot/kernel.img )'
-, "shareddata" : '$( [[ -L $dirmpd && ! $nfsserver ]] && echo true )'
+, "shareddata" : '$( [[ -L $dirmpd && $nfsserver == false ]] && echo true )'
, "soundprofile" : '$( exists $dirsystem/soundprofile )'
, "soundprofileconf" : '$soundprofileconf'
, "status" : "'$status'"
@@ -271,7 +272,7 @@ if [[ -e $dirshm/onboardwlan ]]; then
, "wlanconf" : '$wlanconf'
, "wlanconnected" : '$( ip r | grep -q -m1 "^default.*wlan0" && echo true )
discoverable=true
- if grep -q -m1 ^dtparam=krnbt=on /boot/config.txt; then
+ if ! grep -q ^dtoverlay=disable-bt /boot/config.txt; then
bluetoothon=true
bluetoothactive=$bluetooth
if [[ $bluetoothactive == true ]]; then
diff --git a/srv/http/bash/settings/system-datareset.sh b/srv/http/bash/settings/system-datareset.sh
index 6b328c2e6..f6e2749f8 100644
--- a/srv/http/bash/settings/system-datareset.sh
+++ b/srv/http/bash/settings/system-datareset.sh
@@ -49,8 +49,6 @@ initramfs initramfs-linux.img followkernel
disable_overscan=1
disable_splash=1
dtparam=audio=on"
- [[ $onboardwireless ]] && config+="
-dtparam=krnbt=on"
[[ -e /boot/kernel7.img && -e /usr/bin/firefox ]] && config+="
hdmi_force_hotplug=1"
[[ $rpi0 ]] && config+="
diff --git a/srv/http/bash/settings/system.sh b/srv/http/bash/settings/system.sh
index a25aa5856..8ab06748a 100644
--- a/srv/http/bash/settings/system.sh
+++ b/srv/http/bash/settings/system.sh
@@ -102,15 +102,11 @@ dtparam=audio=on"
configTxt
;;
bluetooth )
- config=$( grep -v dtparam=krnbt=on /boot/config.txt )
+ grep -q 'krnbt.*off' /boot/overlays/README && newkernel=1 # temp
+ config=$( grep -E -v 'disable-bt|krnbt=on' /boot/config.txt )
if [[ $ON ]]; then
- config+="
+ [[ ! $newkernel ]] && config+="
dtparam=krnbt=on"
- if ls -l /sys/class/bluetooth | grep -q -m1 serial; then
- systemctl start bluetooth
- ! grep -q 'device.*bluealsa' $dirmpdconf/output.conf && $dirsettings/player-conf.sh
- rfkill | grep -q -m1 bluetooth && pushstream refresh '{ "page": "networks", "activebt": true }'
- fi
if [[ $DISCOVERABLE ]]; then
yesno=yes
touch $dirsystem/btdiscoverable
@@ -118,11 +114,18 @@ dtparam=krnbt=on"
yesno=no
rm $dirsystem/btdiscoverable
fi
- bluetoothctl discoverable $yesno &> /dev/null
- [[ -e $dirsystem/btformat ]] && prevbtformat=true || prevbtformat=
- [[ $FORMAT ]] && touch $dirsystem/btformat || rm $dirsystem/btformat
+ if ls -l /sys/class/bluetooth 2> /dev/null | grep -q -m1 serial; then
+ systemctl start bluetooth
+ bluetoothctl discoverable $yesno &> /dev/null
+ ! grep -q 'device.*bluealsa' $dirmpdconf/output.conf && $dirsettings/player-conf.sh
+ rfkill | grep -q -m1 bluetooth && pushstream refresh '{ "page": "networks", "activebt": true }'
+ fi
+ [[ -e $dirsystem/btformat ]] && prevbtformat=true
+ [[ $FORMAT ]] && touch $dirsystem/btformat || rm -f $dirsystem/btformat
[[ $FORMAT != $prevbtformat ]] && $dirsettings/player-conf.sh
else
+ [[ $newkernel ]] && config+='
+dtoverlay=disable-bt'
if ! rfkill | grep -q -m1 bluetooth; then
systemctl stop bluetooth
rm -f $dirshm/{btdevice,btreceiver,btsender}
@@ -138,6 +141,18 @@ bluetoothstart )
bluetoothctl discoverable-timeout 0 &> /dev/null
bluetoothctl pairable yes &> /dev/null
;;
+cpuinfo )
+ hwrevision=$( grep ^Revision /proc/cpuinfo )
+ BB=${hwrevision: -3:2}
+ C=${hwrevision: -4:1}
+ data=BB=$BB$'\n'
+ data+=C=$C$'\n'
+ [[ $BB =~ ^(09|0c|12)$ ]] || data+=onboardsound=true$'\n' # not zero, zero w, zero 2w
+ [[ $BB =~ ^(00|01|02|03|04|09)$ ]] || data+=onboardwireless=true$'\n' # not zero, 1, 2
+ [[ $BB =~ ^(09|0c)$ ]] && data+=rpi0=true$'\n' # zero
+ [[ $BB == 0d ]] && data+=rpi3bplus=true$'\n' # 3B+
+ echo "$data" > $dirshm/cpuinfo
+ ;;
hddinfo )
echo -n "\
# hdparm -I $DEV
@@ -546,9 +561,10 @@ tft )
if [[ $ON ]]; then
[[ $MODEL != tft35a ]] && echo $MODEL > $dirsystem/lcdmodel || rm $dirsystem/lcdmodel
sed -i '1 s/$/ fbcon=map:10 fbcon=font:ProFont6x11/' /boot/cmdline.txt
+ rotate=$( getVar rotate $dirsystem/localbrowser.conf )
config+="
hdmi_force_hotplug=1
-dtoverlay=$MODEL:rotate=0"
+dtoverlay=$MODEL:rotate=$rotate"
calibrationconf=/etc/X11/xorg.conf.d/99-calibration.conf
[[ ! -e $calibrationconf ]] && cp /etc/X11/lcd0 $calibrationconf
sed -i 's/fb0/fb1/' /etc/X11/xorg.conf.d/99-fbturbo.conf
@@ -560,8 +576,8 @@ dtoverlay=$MODEL:rotate=0"
configTxt
;;
tftcalibrate )
- degree=$( grep rotate /boot/config.txt | cut -d= -f3 )
- cp -f /etc/X11/{lcd$degree,xorg.conf.d/99-calibration.conf}
+ rotate=$( grep rotate /boot/config.txt | cut -d= -f3 )
+ cp -f /etc/X11/{lcd$rotate,xorg.conf.d/99-calibration.conf}
systemctl stop localbrowser
value=$( DISPLAY=:0 xinput_calibrator | grep Calibration | cut -d'"' -f4 )
if [[ $value ]]; then
diff --git a/srv/http/bash/startup.sh b/srv/http/bash/startup.sh
index 5aadeef55..9d8df845d 100644
--- a/srv/http/bash/startup.sh
+++ b/srv/http/bash/startup.sh
@@ -2,16 +2,7 @@
. /srv/http/bash/common.sh
-hwrevision=$( grep ^Revision /proc/cpuinfo )
-BB=${hwrevision: -3:2}
-C=${hwrevision: -4:1}
- data=BB=$BB$'\n'
- data+=C=$C$'\n'
-[[ $BB =~ ^(09|0c|12)$ ]] || data+=onboardsound=true$'\n' # not zero, zero w, zero 2w
-[[ $BB =~ ^(00|01|02|03|04|09)$ ]] || data+=onboardwireless=true$'\n' # not zero, 1, 2
-[[ $BB =~ ^(09|0c)$ ]] && data+=rpi0=true$'\n' # zero
-[[ $BB == 0d ]] && data+=rpi3bplus=true$'\n' # 3B+
-echo "$data" > $dirshm/cpuinfo
+$dirsettings/system.sh cpuinfo
# wifi - on-board or usb
wlandev=$( $dirsettings/networks.sh wlandevice )
@@ -26,7 +17,6 @@ if [[ -e /boot/expand ]]; then # run once
partprobe $dev
resize2fs $partition
fi
- ! grep -q onboardwireless=true $dirshm/cpuinfo && sed -i '/dtparam=krnbt=on/ d' /boot/config.txt
fi
if [[ -e /boot/backup.gz ]]; then
diff --git a/srv/http/bash/xinitrc b/srv/http/bash/xinitrc
index 7e46a1712..ef9a00246 100644
--- a/srv/http/bash/xinitrc
+++ b/srv/http/bash/xinitrc
@@ -22,10 +22,10 @@ matchbox-window-manager -use_cursor $cursor &
scale=$( awk 'BEGIN { printf "%.2f", '$zoom/100' }' )
if [[ -e /usr/bin/firefox ]]; then
- dirfirefox=/root/.mozilla/firefox
- [[ ! -e $dirfirefox ]] && timeout 1 firefox --headless &> dev/null
- profile=$( grep -m1 ^Default $dirfirefox/profiles.ini | cut -d= -f2 )
- fileuserjs=$dirfirefox/$profile/user.js
+ rm -rf /root/.mozilla
+ timeout 1 firefox --headless &> dev/null
+ profile=$( grep -m1 ^Default /root/.mozilla/firefox/profiles.ini | cut -d= -f2 )
+ fileuserjs=/root/.mozilla/firefox/$profile/user.js
if [[ $scale == 1.00 ]]; then
rm -f $fileuserjs
else
diff --git a/srv/http/mpdlibrary.php b/srv/http/mpdlibrary.php
index 1f2b13073..174b3101f 100644
--- a/srv/http/mpdlibrary.php
+++ b/srv/http/mpdlibrary.php
@@ -3,8 +3,8 @@
find, list, ls, search, track, webradio
Album
- /srv/http/data/mpd/album: album-artist^-file
- /srv/http/data/mpd/albumbyartist: artist-album-file
+ /srv/http/data/mpd/album: album-artist-file
+ /srv/http/data/mpd/albumbyartist: artist-date-album-file
track list: mpc ls -f %*% $path
Artist
mpc list artist > /srv/http/data/mpd/artist
@@ -141,9 +141,13 @@
break;
case 'list':
$filemode = '/srv/http/data/mpd/'.$mode;
- if ( $mode === 'album' && exec( 'grep "albumbyartist.*true" /srv/http/data/system/display.json' ) ) $filemode.= 'byartist';
- $lists = file( $filemode, FILE_IGNORE_NEW_LINES );
- htmlList( $lists );
+ if ( $mode === 'album' ) {
+ $display = json_decode( file_get_contents( '/srv/http/data/system/display.json' ) );
+ if ( $display->albumbyartist ) $filemode.= 'byartist';
+ if ( $display->albumyear ) $filemode.= '-year';
+ }
+ $lists = file( $filemode, FILE_IGNORE_NEW_LINES );
+ if ( count( $lists ) ) htmlList( $lists );
break;
case 'ls':
if ( $mode !== 'album' ) {
@@ -201,11 +205,9 @@
$files = [];
$indexes = [];
if ( $mode === 'search' ) {
- $searchmode = 1;
exec( "grep -ril --exclude-dir=img '".$string."' ".$dir." | sed 's|^".$dir."||'"
, $files );
} else {
- $searchmode = 0;
$dir.= $string;
exec( 'ls -1 "'.$dir.'" | grep -E -v "^img|\.jpg$|\.gif$"'
, $lists );
@@ -273,8 +275,7 @@ function escape( $string ) { // for passing bash arguments
return preg_replace( '/(["`])/', '\\\\\1', $string );
}
function htmlDirectory( $lists ) {
- global $gmode;
- global $html;
+ global $gmode, $html;
foreach( $lists as $list ) {
$dir = basename( $list );
$each = ( object )[];
@@ -314,9 +315,7 @@ function htmlDirectory( $lists ) {
function htmlFind( $lists, $f ) { // non-file 'find' command
if ( ! count( $lists ) ) exit;
- global $mode;
- global $gmode;
- global $html;
+ global $mode, $gmode, $html;
$fL = count( $f );
foreach( $lists as $list ) {
if ( $list === '' ) continue;
@@ -368,13 +367,8 @@ function htmlFind( $lists, $f ) { // non-file 'find' command
echo $html;
}
function htmlList( $lists ) { // non-file 'list' command
- if ( ! count( $lists ) ) exit;
-
- global $mode;
- global $gmode;
- global $html;
- if ( $mode === 'latest' ) $mode = 'album';
- if ( $mode !== 'album' ) {
+ global $mode, $gmode, $html;
+ if ( $mode !== 'album' && $mode !== 'latest' ) {
foreach( $lists as $list ) {
$data = explode( '^^', $list );
$index = strtoupper( $data[ 0 ] );
@@ -387,19 +381,31 @@ function htmlList( $lists ) { // non-file 'list' command
';
}
} else {
+ global $display;
foreach( $lists as $list ) {
$data = explode( '^^', $list );
$index = strtoupper( $data[ 0 ] );
$indexes[] = $index;
- $path = $data[ 3 ];
+ $path = end( $data );
if ( substr( $path, -4 ) === '.cue' ) $path = dirname( $path );
$coverfile = rawurlencode( '/mnt/MPD/'.$path.'/coverart.jpg' ); // replaced with icon on load error(faster than existing check)
+ $l1 = $data[ 1 ];
+ $l2 = $data[ 2 ];
+ $name = $l1;
+ if ( $display->albumyear ) {
+ $name = $data[ 3 ];
+ $l2 = $l2 ? ( strlen( $l2 ) < 5 ? $l2 : date( 'Y', strtotime( $l2 ) ) ) : '...';
+ $l2 .= '
'.$name;
+ } else if ( $display->albumbyartist ) {
+ $name = $l2;
+ }
$html .=
'';
}
}
@@ -411,9 +417,8 @@ function htmlList( $lists ) { // non-file 'list' command
echo $html;
}
function htmlRadio( $subdirs, $files, $dir ) {
- global $mode;
- global $gmode;
- global $html;
+ global $mode, $gmode, $html;
+ $searchmode = $mode === 'search';
if ( count( $subdirs ) ) {
foreach( $subdirs as $subdir ) {
$each = ( object )[];
@@ -496,9 +501,7 @@ function htmlRadio( $subdirs, $files, $dir ) {
function htmlTrack( $lists, $f, $filemode = '', $string = '', $dirs = '' ) { // track list - no sort ($string: cuefile or search)
if ( ! count( $lists ) ) exit;
- global $mode;
- global $gmode;
- global $html;
+ global $mode, $gmode, $html;
$fL = count( $f );
foreach( $lists as $list ) {
if ( $list === '' ) continue;
diff --git a/srv/http/mpdplaylist.php b/srv/http/mpdplaylist.php
index 169447b09..502ad355e 100644
--- a/srv/http/mpdplaylist.php
+++ b/srv/http/mpdplaylist.php
@@ -134,8 +134,7 @@ function htmlSavedPlaylist() {
], JSON_NUMERIC_CHECK );
}
function htmlTrack( $lists, $plname = '' ) {
- global $headers;
- global $add;
+ global $headers, $add;
$count = count( $lists );
if ( ! $count ) exit( '-1' );
diff --git a/srv/http/settings.php b/srv/http/settings.php
index 945e45603..40672bcda 100644
--- a/srv/http/settings.php
+++ b/srv/http/settings.php
@@ -124,8 +124,7 @@ function htmlSetting( $data ) {
return;
}
- global $page;
- global $id_data;
+ global $page, $id_data;
$id = $data[ 'id' ];
$iddata = $id_data[ $id ];
$name = $iddata[ 'name' ];
diff --git a/srv/http/settings/player.php b/srv/http/settings/player.php
index 74fbedb0c..3c0c736b5 100644
--- a/srv/http/settings/player.php
+++ b/srv/http/settings/player.php
@@ -3,7 +3,7 @@
$id_data = [
'audiooutput' => [ 'name' => 'Device', 'setting' => 'none' ]
, 'autoupdate' => [ 'name' => 'Library Auto Update', 'sub' => 'auto_update', 'setting' => false ]
- , 'btreceiver' => [ 'name' => 'Bluetooth', 'sub' => 'bluetoothctl', 'setting' => 'custom', 'status' => true ]
+ , 'btreceiver' => [ 'name' => 'Bluetooth', 'sub' => 'bluealsa', 'setting' => 'custom', 'status' => true ]
, 'buffer' => [ 'name' => 'Buffer - Audio', 'sub' => 'audio_buffer' ]
, 'crossfade' => [ 'name' => 'Cross-Fading', 'sub' => 'crossfade' ]
, 'custom' => [ 'name' => "User's Configurations", 'sub' => 'custom' ]
diff --git a/srv/http/settings/system.php b/srv/http/settings/system.php
index b083f8f31..2a2f60ac0 100644
--- a/srv/http/settings/system.php
+++ b/srv/http/settings/system.php
@@ -8,7 +8,7 @@
, 'backup' => [ 'name' => 'Backup', 'setting' => 'none' ]
, 'bluetooth' => [ 'name' => 'Bluetooth', 'sub' => 'bluez', 'status' => true ]
, 'hddsleep' => [ 'name' => 'Hard Drive Sleep' ]
- , 'hdmi' => [ 'name' => 'HDMI', 'setting' => false ]
+ , 'hdmi' => [ 'name' => 'HDMI', 'sub' => 'hot plug', 'setting' => false ]
, 'hostname' => [ 'name' => 'Player Name', 'setting' => 'none' ]
, 'lcdchar' => [ 'name' => 'Character LCD', 'sub' => 'HD44780' ]
, 'mpdoled' => [ 'name' => 'Spectrum OLED' ]