mirror of
				https://github.com/SuperBFG7/ympd
				synced 2025-10-31 05:43:01 +00:00 
			
		
		
		
	Merge pull request #66 from jcorporation/devel
Merge devel into master for 4.3.1 release
This commit is contained in:
		| @@ -4,7 +4,7 @@ project (mympd C) | |||||||
| set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/") | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/") | ||||||
| set(CPACK_PACKAGE_VERSION_MAJOR "4") | set(CPACK_PACKAGE_VERSION_MAJOR "4") | ||||||
| set(CPACK_PACKAGE_VERSION_MINOR "3") | set(CPACK_PACKAGE_VERSION_MINOR "3") | ||||||
| set(CPACK_PACKAGE_VERSION_PATCH "0") | set(CPACK_PACKAGE_VERSION_PATCH "1") | ||||||
|  |  | ||||||
| if(CMAKE_BUILD_TYPE MATCHES RELEASE) | if(CMAKE_BUILD_TYPE MATCHES RELEASE) | ||||||
|     set(ASSETS_PATH "/usr/share/${PROJECT_NAME}/htdocs") |     set(ASSETS_PATH "/usr/share/${PROJECT_NAME}/htdocs") | ||||||
| @@ -31,6 +31,7 @@ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS NS_ENABLE_SSL) | |||||||
| set(SOURCES | set(SOURCES | ||||||
|     src/mympd.c |     src/mympd.c | ||||||
|     src/mpd_client.c |     src/mpd_client.c | ||||||
|  |     src/list.c | ||||||
|     dist/src/mongoose/mongoose.c |     dist/src/mongoose/mongoose.c | ||||||
|     dist/src/frozen/frozen.c |     dist/src/frozen/frozen.c | ||||||
|     dist/src/inih/ini.c |     dist/src/inih/ini.c | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								PKGBUILD
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								PKGBUILD
									
									
									
									
									
								
							| @@ -4,9 +4,9 @@ | |||||||
|  |  | ||||||
| pkgname=mympd | pkgname=mympd | ||||||
| _pkgname=myMPD | _pkgname=myMPD | ||||||
| pkgver=4.3.0 | pkgver=4.3.1 | ||||||
| pkgrel=1 | pkgrel=1 | ||||||
| pkgdesc="A standalone MPD Web GUI based on YMPD - Default port set to 80" | pkgdesc="myMPD is a standalone and mobile friendly web mpdclient." | ||||||
| arch=('x86_64' 'armv7h' 'aarch64') | arch=('x86_64' 'armv7h' 'aarch64') | ||||||
| url="http://github.org/jcorporation/myMPD" | url="http://github.org/jcorporation/myMPD" | ||||||
| license=('GPL') | license=('GPL') | ||||||
|   | |||||||
| @@ -10,10 +10,6 @@ post_upgrade() { | |||||||
|   getent passwd mympd > /dev/null |   getent passwd mympd > /dev/null | ||||||
|   [ "$?" = "2" ] && useradd --system -d /var/lib/mympd -s /usr/sbin/nologin -g mympd mympd |   [ "$?" = "2" ] && useradd --system -d /var/lib/mympd -s /usr/sbin/nologin -g mympd mympd | ||||||
|  |  | ||||||
|   # fix ownership of /var/lib/mympd |  | ||||||
|   echo "INFO: Fixing ownership of /var/lib/mympd" |  | ||||||
|   chown -R mympd.mympd /var/lib/mympd |  | ||||||
|  |  | ||||||
|   # link music directory to mympd if not already exising  |   # link music directory to mympd if not already exising  | ||||||
|   echo "INFO: Trying to link musicdir to library" |   echo "INFO: Trying to link musicdir to library" | ||||||
|   if [ -f /etc/mpd.conf ] |   if [ -f /etc/mpd.conf ] | ||||||
| @@ -64,6 +60,17 @@ post_upgrade() { | |||||||
|     fi |     fi | ||||||
|   done |   done | ||||||
|  |  | ||||||
|  |   #default state files | ||||||
|  |   [ -f /var/lib/mympd/state/jukeboxMode ] || echo -n "0" > /var/lib/mympd/state/jukeboxMode | ||||||
|  |   [ -f /var/lib/mympd/state/jukeboxPlaylist ] || echo -n "Database" > /var/lib/mympd/state/jukeboxPlaylist | ||||||
|  |   [ -f /var/lib/mympd/state/jukeboxQueueLength ] || echo -n "1" > /var/lib/mympd/state/jukeboxQueueLength | ||||||
|  |   [ -f /var/lib/mympd/state/notificationPage ] || echo -n "true" > /var/lib/mympd/state/notificationPage | ||||||
|  |   [ -f /var/lib/mympd/state/notificationWeb ] || echo -n "false" > /var/lib/mympd/state/notificationWeb | ||||||
|  |  | ||||||
|  |   # fix ownership of /var/lib/mympd | ||||||
|  |   echo "INFO: Fixing ownership of /var/lib/mympd" | ||||||
|  |   chown -R mympd.mympd /var/lib/mympd | ||||||
|  |  | ||||||
|   # move config into place unless already existing |   # move config into place unless already existing | ||||||
|   if [ ! -f /etc/mympd/mympd.conf ] |   if [ ! -f /etc/mympd/mympd.conf ] | ||||||
|   then  |   then  | ||||||
|   | |||||||
| @@ -4,13 +4,13 @@ | |||||||
| # (c) 2018 Juergen Mang <mail@jcgames.de> | # (c) 2018 Juergen Mang <mail@jcgames.de> | ||||||
|  |  | ||||||
| Name:           myMPD | Name:           myMPD | ||||||
| Version:        4.3.0 | Version:        4.3.1 | ||||||
| Release:        0  | Release:        0  | ||||||
| License:        GPL-2.0  | License:        GPL-2.0  | ||||||
| Group:          Productivity/Multimedia/Sound/Players | Group:          Productivity/Multimedia/Sound/Players | ||||||
| Summary:        Standalone webclient for mpd | Summary:        Standalone webclient for mpd | ||||||
| Url:            https://github.com/jcorporation/myMPD | Url:            https://github.com/jcorporation/myMPD | ||||||
| Source:         https://github.com/jcorporation/myMPD/archive/v4.3.0.zip | Source:         https://github.com/jcorporation/myMPD/archive/v%{version}.zip | ||||||
| BuildRequires:  gcc | BuildRequires:  gcc | ||||||
| BuildRequires:  cmake | BuildRequires:  cmake | ||||||
| BuildRequires:  unzip | BuildRequires:  unzip | ||||||
| @@ -44,9 +44,6 @@ getent group mympd > /dev/null | |||||||
| getent passwd mympd > /dev/null | getent passwd mympd > /dev/null | ||||||
| [ "$?" = "2" ] && useradd -r mympd -g mympd -d /var/lib/mympd -s /usr/sbin/nologin | [ "$?" = "2" ] && useradd -r mympd -g mympd -d /var/lib/mympd -s /usr/sbin/nologin | ||||||
|  |  | ||||||
| echo "Fixing ownership of /var/lib/mympd" |  | ||||||
| chown -R mympd.mympd /var/lib/mympd |  | ||||||
|  |  | ||||||
| if [ -d /etc/systemd ] | if [ -d /etc/systemd ] | ||||||
| then | then | ||||||
|   [ -d /usr/lib/systemd/system ] || mkdir -p /usr/lib/systemd/system  |   [ -d /usr/lib/systemd/system ] || mkdir -p /usr/lib/systemd/system  | ||||||
| @@ -78,6 +75,16 @@ do | |||||||
|   fi |   fi | ||||||
| done | done | ||||||
|  |  | ||||||
|  | #default state files | ||||||
|  | [ -f /var/lib/mympd/state/jukeboxMode ] || echo -n "0" > /var/lib/mympd/state/jukeboxMode | ||||||
|  | [ -f /var/lib/mympd/state/jukeboxPlaylist ] || echo -n "Database" > /var/lib/mympd/state/jukeboxPlaylist | ||||||
|  | [ -f /var/lib/mympd/state/jukeboxQueueLength ] || echo -n "1" > /var/lib/mympd/state/jukeboxQueueLength | ||||||
|  | [ -f /var/lib/mympd/state/notificationPage ] || echo -n "true" > /var/lib/mympd/state/notificationPage | ||||||
|  | [ -f /var/lib/mympd/state/notificationWeb ] || echo -n "false" > /var/lib/mympd/state/notificationWeb | ||||||
|  |  | ||||||
|  | echo "Fixing ownership of /var/lib/mympd" | ||||||
|  | chown -R mympd.mympd /var/lib/mympd | ||||||
|  |  | ||||||
| # move config into place unless already existing | # move config into place unless already existing | ||||||
| if [ ! -f /etc/mympd/mympd.conf ] | if [ ! -f /etc/mympd/mympd.conf ] | ||||||
| then  | then  | ||||||
|   | |||||||
| @@ -1,18 +1,18 @@ | |||||||
| .\" Manpage for myMPD. | .\" Manpage for myMPD. | ||||||
| .\" Contact mail@jcgames.de to correct errors or typos. | .\" Contact mail@jcgames.de to correct errors or typos. | ||||||
| .TH man 1 "22 Aug 2018" "4.0.0" "myMPD man page" | .TH man 1 "02 Oct 2018" "4.3.1" "myMPD man page" | ||||||
| .SH NAME | .SH NAME | ||||||
| myMPD \- Standalone MPD Web GUI written in C, utilizing Websockets and Bootstrap/JS | myMPD \- myMPD is a standalone and mobile friendly web mpdclient  | ||||||
| .SH SYNOPSIS | .SH SYNOPSIS | ||||||
| mympd /path/to/mympd.conf | mympd /path/to/mympd.conf | ||||||
| .SH DESCRIPTION | .SH DESCRIPTION | ||||||
| myMPD is a lightweight MPD web client that runs without a dedicated webserver or interpreter.  | myMPD is a lightweight MPD web client that runs without a dedicated webserver or interpreter. It's tuned for minimal resource usage and requires only very litte dependencies. | ||||||
| It's tuned for minimal resource usage and requires only very litte dependencies.  | myMPD is a fork of ympd (https://github.com/notandy/ympd). | ||||||
| myMPD is a fork of ympd. | This fork provides a reworked ui based on Bootstrap 4, a modernized backend and many new features while having the same small footprint as ympd. | ||||||
|  |  | ||||||
| .SH BUGS | .SH BUGS | ||||||
| No known bugs. | No known bugs. | ||||||
| .SH AUTHOR | .SH AUTHOR | ||||||
| Juergen Mang (mail@jcgames.de) | Juergen Mang (mail@jcgames.de) | ||||||
|  |  | ||||||
| https://github.com/jcorporation/mympd | https://github.com/jcorporation/mympd | ||||||
|   | |||||||
| @@ -33,7 +33,6 @@ mixramp = false | |||||||
| stickers = true | stickers = true | ||||||
|  |  | ||||||
| #List of tags in myMPD gui | #List of tags in myMPD gui | ||||||
| #Supported tags: Artist,Album,AlbumArtist,Title,Track,Genre,Date,Composer,Performer |  | ||||||
| taglist = Artist,Album,AlbumArtist,Title,Track,Genre,Date,Composer,Performer | taglist = Artist,Album,AlbumArtist,Title,Track,Genre,Date,Composer,Performer | ||||||
|  |  | ||||||
| #Enable smart playlists | #Enable smart playlists | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							| @@ -1,5 +1,5 @@ | |||||||
| mympd (4.3.0-1) stable; urgency=medium | mympd (4.3.1-1) stable; urgency=medium | ||||||
|  |  | ||||||
|   * Release from master |   * Release from master | ||||||
|  |  | ||||||
|  -- Juergen Mang <mail@jcgames.de>  Tue, 25 Sep 2018 00:35:00 +0200 |  -- Juergen Mang <mail@jcgames.de>  Mon, 02 Oct 2018 00:04:00 +0200 | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								debian/postinst
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								debian/postinst
									
									
									
									
										vendored
									
									
								
							| @@ -6,8 +6,7 @@ getent group mympd > /dev/null | |||||||
| getent passwd mympd > /dev/null | getent passwd mympd > /dev/null | ||||||
| [ "$?" = "2" ] && useradd -r mympd -g mympd -d /var/lib/mympd -s /usr/sbin/nologin | [ "$?" = "2" ] && useradd -r mympd -g mympd -d /var/lib/mympd -s /usr/sbin/nologin | ||||||
|  |  | ||||||
| echo "Fixing ownership of /var/lib/mympd" |  | ||||||
| chown -R mympd.mympd /var/lib/mympd |  | ||||||
|  |  | ||||||
| echo "Trying to link musicdir to library" | echo "Trying to link musicdir to library" | ||||||
| if [ -f /etc/mpd.conf ] | if [ -f /etc/mpd.conf ] | ||||||
| @@ -48,7 +47,6 @@ do | |||||||
|   fi |   fi | ||||||
| done | done | ||||||
|  |  | ||||||
|  |  | ||||||
| # move config into place unless already existing | # move config into place unless already existing | ||||||
| if [ ! -f /etc/mympd/mympd.conf ] | if [ ! -f /etc/mympd/mympd.conf ] | ||||||
| then  | then  | ||||||
| @@ -57,6 +55,16 @@ else | |||||||
|   echo "mympd.conf installed as mympd.conf.dist" |   echo "mympd.conf installed as mympd.conf.dist" | ||||||
| fi | fi | ||||||
|  |  | ||||||
|  | #default state files | ||||||
|  | [ -f /var/lib/mympd/state/jukeboxMode ] || echo -n "0" > /var/lib/mympd/state/jukeboxMode | ||||||
|  | [ -f /var/lib/mympd/state/jukeboxPlaylist ] || echo -n "Database" > /var/lib/mympd/state/jukeboxPlaylist | ||||||
|  | [ -f /var/lib/mympd/state/jukeboxQueueLength ] || echo -n "1" > /var/lib/mympd/state/jukeboxQueueLength | ||||||
|  | [ -f /var/lib/mympd/state/notificationPage ] || echo -n "true" > /var/lib/mympd/state/notificationPage | ||||||
|  | [ -f /var/lib/mympd/state/notificationWeb ] || echo -n "false" > /var/lib/mympd/state/notificationWeb | ||||||
|  |  | ||||||
|  | echo "Fixing ownership of /var/lib/mympd" | ||||||
|  | chown -R mympd.mympd /var/lib/mympd | ||||||
|  |  | ||||||
| if [ -d /etc/mympd/ssl ] | if [ -d /etc/mympd/ssl ] | ||||||
| then | then | ||||||
|   echo "Certificates already created" |   echo "Certificates already created" | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								dist/htdocs/index.html
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/htdocs/index.html
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										30
									
								
								dist/htdocs/js/mympd.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								dist/htdocs/js/mympd.min.js
									
									
									
									
										vendored
									
									
								
							| @@ -42,9 +42,10 @@ showAddToPlaylist(app.current.search))},!1);document.getElementById("searchAddAl | |||||||
| ("Add all to queue"==a.target.innerText?addAllFromBrowseDatabasePlist("queue"):"Add all to playlist"==a.target.innerText&&showAddToPlaylist("DATABASE"))},!1);document.getElementById("searchtags").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,app.current.view,"0/"+a.target.getAttribute("data-tag")+"/"+app.current.search)},!1);document.getElementById("searchqueuestr").addEventListener("keyup",function(a){appGoto(app.current.app,app.current.tab, | ("Add all to queue"==a.target.innerText?addAllFromBrowseDatabasePlist("queue"):"Add all to playlist"==a.target.innerText&&showAddToPlaylist("DATABASE"))},!1);document.getElementById("searchtags").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,app.current.view,"0/"+a.target.getAttribute("data-tag")+"/"+app.current.search)},!1);document.getElementById("searchqueuestr").addEventListener("keyup",function(a){appGoto(app.current.app,app.current.tab, | ||||||
| app.current.view,"0/"+app.current.filter+"/"+this.value)},!1);document.getElementById("searchqueuetag").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,app.current.view,app.current.page+"/"+a.target.getAttribute("data-tag")+"/"+app.current.search)},!1);document.getElementById("search").addEventListener("submit",function(){return!1},!1);document.getElementById("searchqueue").addEventListener("submit",function(){return!1},!1);document.getElementById("searchstr").addEventListener("keyup", | app.current.view,"0/"+app.current.filter+"/"+this.value)},!1);document.getElementById("searchqueuetag").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,app.current.view,app.current.page+"/"+a.target.getAttribute("data-tag")+"/"+app.current.search)},!1);document.getElementById("search").addEventListener("submit",function(){return!1},!1);document.getElementById("searchqueue").addEventListener("submit",function(){return!1},!1);document.getElementById("searchstr").addEventListener("keyup", | ||||||
| function(a){appGoto("Search",void 0,void 0,"0/"+app.current.filter+"/"+this.value)},!1);document.getElementById("BrowseDatabaseByTagDropdown").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,a.target.getAttribute("data-tag"),"0/"+app.current.filter+"/"+app.current.search)},!1);document.getElementsByTagName("body")[0].addEventListener("click",function(a){hideMenu()},!1);dragAndDropTable("QueueList");dragAndDropTable("BrowsePlaylistsDetailList"); | function(a){appGoto("Search",void 0,void 0,"0/"+app.current.filter+"/"+this.value)},!1);document.getElementById("BrowseDatabaseByTagDropdown").addEventListener("click",function(a){"BUTTON"==a.target.nodeName&&appGoto(app.current.app,app.current.tab,a.target.getAttribute("data-tag"),"0/"+app.current.filter+"/"+app.current.search)},!1);document.getElementsByTagName("body")[0].addEventListener("click",function(a){hideMenu()},!1);dragAndDropTable("QueueList");dragAndDropTable("BrowsePlaylistsDetailList"); | ||||||
| window.addEventListener("hashchange",appRoute,!1);window.addEventListener("focus",function(){sendAPI({cmd:"MPD_API_PLAYER_STATE"},parseState)},!1);document.addEventListener("keydown",function(a){if("INPUT"!=a.target.tagName){switch(a.which){case 37:clickPrev();break;case 39:clickNext();break;case 32:clickPlay();break;default:return}a.preventDefault()}},!1);"serviceWorker"in navigator&&"https"==document.URL.substring(0,5)&&window.addEventListener("load",function(){navigator.serviceWorker.register("/sw.min.js", | window.addEventListener("hashchange",appRoute,!1);window.addEventListener("focus",function(){sendAPI({cmd:"MPD_API_PLAYER_STATE"},parseState)},!1);document.addEventListener("keydown",function(a){if("INPUT"!=a.target.tagName&&"SELECT"!=a.target.tagName){if(a.shiftKey)switch(a.which){case 83:sendAPI({cmd:"MPD_API_QUEUE_SHUFFLE"});break;case 67:sendAPI({cmd:"MPD_API_QUEUE_CROP"});break;default:return}else switch(a.which){case 37:clickPrev();break;case 39:clickNext();break;case 32:clickPlay();break;case 83:clickStop(); | ||||||
| {scope:"/"}).then(function(a){console.log("ServiceWorker registration successful with scope: ",a.scope);a.update()},function(a){console.log("ServiceWorker registration failed: ",a)})});window.addEventListener("beforeinstallprompt",function(a){a.preventDefault();deferredPrompt=a});window.addEventListener("beforeinstallprompt",function(a){a.preventDefault();deferredPrompt=a;domCache.btnAdd.classList.remove("hide")});domCache.btnAdd.addEventListener("click",function(a){domCache.btnAdd.classList.add("hide"); | break;case 173:chVolume(-5);break;case 171:chVolume(5);break;case 67:sendAPI({cmd:"MPD_API_QUEUE_CLEAR"});break;default:return}a.preventDefault()}},!1);"serviceWorker"in navigator&&"https"==document.URL.substring(0,5)&&window.addEventListener("load",function(){navigator.serviceWorker.register("/sw.min.js",{scope:"/"}).then(function(a){console.log("ServiceWorker registration successful with scope: ",a.scope);a.update()},function(a){console.log("ServiceWorker registration failed: ",a)})});window.addEventListener("beforeinstallprompt", | ||||||
| deferredPrompt.prompt();deferredPrompt.userChoice.then(function(a){"accepted"===a.outcome?console.log("User accepted the A2HS prompt"):console.log("User dismissed the A2HS prompt");deferredPrompt=null})});window.addEventListener("appinstalled",function(a){console.log("myMPD installed as app")})} | function(a){a.preventDefault();deferredPrompt=a});window.addEventListener("beforeinstallprompt",function(a){a.preventDefault();deferredPrompt=a;domCache.btnAdd.classList.remove("hide")});domCache.btnAdd.addEventListener("click",function(a){domCache.btnAdd.classList.add("hide");deferredPrompt.prompt();deferredPrompt.userChoice.then(function(a){"accepted"===a.outcome?console.log("User accepted the A2HS prompt"):console.log("User dismissed the A2HS prompt");deferredPrompt=null})});window.addEventListener("appinstalled", | ||||||
|  | function(a){console.log("myMPD installed as app")})} | ||||||
| function dragAndDropTable(a){var b=document.getElementById(a).getElementsByTagName("tbody")[0];b.addEventListener("dragstart",function(a){"TR"==a.target.nodeName&&(a.target.classList.add("opacity05"),a.dataTransfer.setDragImage(a.target,0,0),a.dataTransfer.effectAllowed="move",a.dataTransfer.setData("Text",a.target.getAttribute("id")),dragEl=a.target.cloneNode(!0))},!1);b.addEventListener("dragleave",function(a){a.preventDefault();var b=a.target;"TD"==a.target.nodeName&&(b=a.target.parentNode);"TR"== | function dragAndDropTable(a){var b=document.getElementById(a).getElementsByTagName("tbody")[0];b.addEventListener("dragstart",function(a){"TR"==a.target.nodeName&&(a.target.classList.add("opacity05"),a.dataTransfer.setDragImage(a.target,0,0),a.dataTransfer.effectAllowed="move",a.dataTransfer.setData("Text",a.target.getAttribute("id")),dragEl=a.target.cloneNode(!0))},!1);b.addEventListener("dragleave",function(a){a.preventDefault();var b=a.target;"TD"==a.target.nodeName&&(b=a.target.parentNode);"TR"== | ||||||
| b.nodeName&&b.classList.remove("dragover")},!1);b.addEventListener("dragover",function(a){a.preventDefault();for(var c=b.getElementsByClassName("dragover"),e=c.length,f=0;f<e;f++)c[f].classList.remove("dragover");c=a.target;"TD"==a.target.nodeName&&(c=a.target.parentNode);"TR"==c.nodeName&&c.classList.add("dragover");a.dataTransfer.dropEffect="move"},!1);b.addEventListener("dragend",function(a){for(var c=b.getElementsByClassName("dragover"),e=c.length,f=0;f<e;f++)c[f].classList.remove("dragover"); | b.nodeName&&b.classList.remove("dragover")},!1);b.addEventListener("dragover",function(a){a.preventDefault();for(var c=b.getElementsByClassName("dragover"),e=c.length,f=0;f<e;f++)c[f].classList.remove("dragover");c=a.target;"TD"==a.target.nodeName&&(c=a.target.parentNode);"TR"==c.nodeName&&c.classList.add("dragover");a.dataTransfer.dropEffect="move"},!1);b.addEventListener("dragend",function(a){for(var c=b.getElementsByClassName("dragover"),e=c.length,f=0;f<e;f++)c[f].classList.remove("dragover"); | ||||||
| document.getElementById(a.dataTransfer.getData("Text"))&&document.getElementById(a.dataTransfer.getData("Text")).classList.remove("opacity05")},!1);b.addEventListener("drop",function(c){c.stopPropagation();c.preventDefault();var d=c.target;"TD"==c.target.nodeName&&(d=c.target.parentNode);var e=document.getElementById(c.dataTransfer.getData("Text")).getAttribute("data-songpos"),f=d.getAttribute("data-songpos");document.getElementById(c.dataTransfer.getData("Text")).remove();dragEl.classList.remove("opacity05"); | document.getElementById(a.dataTransfer.getData("Text"))&&document.getElementById(a.dataTransfer.getData("Text")).classList.remove("opacity05")},!1);b.addEventListener("drop",function(c){c.stopPropagation();c.preventDefault();var d=c.target;"TD"==c.target.nodeName&&(d=c.target.parentNode);var e=document.getElementById(c.dataTransfer.getData("Text")).getAttribute("data-songpos"),f=d.getAttribute("data-songpos");document.getElementById(c.dataTransfer.getData("Text")).remove();dragEl.classList.remove("opacity05"); | ||||||
| @@ -66,8 +67,8 @@ function setCounter(a,b,c){currentSong.totalTime=b;currentSong.elapsedTime=c;cur | |||||||
| c.getAttribute("data-songpos"),c.classList.remove("font-weight-bold"));if(c=document.getElementById("queueTrackId"+a))d=c.getElementsByTagName("td"),d[4].innerText=b,d[0].classList.add("material-icons"),d[0].innerText="play_arrow",c.classList.add("font-weight-bold");progressTimer&&clearTimeout(progressTimer);"play"==playstate&&(progressTimer=setTimeout(function(){currentSong.elapsedTime++;setCounter(currentSong.currentSongId,currentSong.totalTime,currentSong.elapsedTime)},1E3))} | c.getAttribute("data-songpos"),c.classList.remove("font-weight-bold"));if(c=document.getElementById("queueTrackId"+a))d=c.getElementsByTagName("td"),d[4].innerText=b,d[0].classList.add("material-icons"),d[0].innerText="play_arrow",c.classList.add("font-weight-bold");progressTimer&&clearTimeout(progressTimer);"play"==playstate&&(progressTimer=setTimeout(function(){currentSong.elapsedTime++;setCounter(currentSong.currentSongId,currentSong.totalTime,currentSong.elapsedTime)},1E3))} | ||||||
| function parseState(a){if(JSON.stringify(a)!==JSON.stringify(lastState)){if(1==a.data.state){for(var b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].innerText="play_arrow";playstate="stop"}else if(2==a.data.state){for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].innerText="pause";playstate="play"}else{for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].innerText="play_arrow";playstate="pause"}-1==a.data.nextSongPos&&0==settings.jukeboxMode?domCache.btnNext.setAttribute("disabled","disabled"): | function parseState(a){if(JSON.stringify(a)!==JSON.stringify(lastState)){if(1==a.data.state){for(var b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].innerText="play_arrow";playstate="stop"}else if(2==a.data.state){for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].innerText="pause";playstate="play"}else{for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].innerText="play_arrow";playstate="pause"}-1==a.data.nextSongPos&&0==settings.jukeboxMode?domCache.btnNext.setAttribute("disabled","disabled"): | ||||||
| domCache.btnNext.removeAttribute("disabled");0>=a.data.songPos?domCache.btnPrev.setAttribute("disabled","disabled"):domCache.btnPrev.removeAttribute("disabled");if(0==a.data.queueLength)for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].setAttribute("disabled","disabled");else for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].removeAttribute("disabled");-1==a.data.volume?(domCache.volumePrct.innerText="Volumecontrol disabled",domCache.volumeControl.classList.add("hide")):(domCache.volumeControl.classList.remove("hide"), | domCache.btnNext.removeAttribute("disabled");0>=a.data.songPos?domCache.btnPrev.setAttribute("disabled","disabled"):domCache.btnPrev.removeAttribute("disabled");if(0==a.data.queueLength)for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].setAttribute("disabled","disabled");else for(b=0;b<domCache.btnsPlayLen;b++)domCache.btnsPlay[b].removeAttribute("disabled");-1==a.data.volume?(domCache.volumePrct.innerText="Volumecontrol disabled",domCache.volumeControl.classList.add("hide")):(domCache.volumeControl.classList.remove("hide"), | ||||||
| domCache.volumePrct.innerText=a.data.volume+" %",domCache.volumeIcon.innerText=0==a.data.volume?"volume_off":50>a.data.volume?"volume_down":"volume_up");domCache.volumeBar.value=a.data.volume;setCounter(a.data.currentSongId,a.data.totalTime,a.data.elapsedTime);sendAPI({cmd:"MPD_API_PLAYER_CURRENT_SONG"},songChange);"-1"==a.data.songPos&&(domCache.currentTrack.innerText="Not playing",domCache.currentAlbum.innerText="",domCache.currentArtist.innerText="",domCache.currentCover.style.backgroundImage= | domCache.volumePrct.innerText=a.data.volume+" %",domCache.volumeIcon.innerText=0==a.data.volume?"volume_off":50>a.data.volume?"volume_down":"volume_up");domCache.volumeBar.value=a.data.volume;setCounter(a.data.currentSongId,a.data.totalTime,a.data.elapsedTime);lastState&&lastState.data.currentSongId!=a.data.currentSongId&&sendAPI({cmd:"MPD_API_PLAYER_CURRENT_SONG"},songChange);"-1"==a.data.songPos&&(domCache.currentTrack.innerText="Not playing",domCache.currentAlbum.innerText="",domCache.currentArtist.innerText= | ||||||
| "");lastState=a}}function getQueue(){2<=app.current.search.length?sendAPI({cmd:"MPD_API_QUEUE_SEARCH",data:{filter:app.current.filter,offset:app.current.page,searchstr:app.current.search}},parseQueue):sendAPI({cmd:"MPD_API_QUEUE_LIST",data:{offset:app.current.page}},parseQueue)} | "",domCache.currentCover.style.backgroundImage="");lastState=a}}function getQueue(){2<=app.current.search.length?sendAPI({cmd:"MPD_API_QUEUE_SEARCH",data:{filter:app.current.filter,offset:app.current.page,searchstr:app.current.search}},parseQueue):sendAPI({cmd:"MPD_API_QUEUE_LIST",data:{offset:app.current.page}},parseQueue)} | ||||||
| function parseQueue(a){if("Queue"===app.current.app){0<a.totalTime&&a.totalEntities<=settings.maxElementsPerPage?document.getElementById("panel-heading-queue").innerText=a.totalEntities+" "+(1<a.totalEntities?"Songs":"Song")+" \u2013 "+beautifyDuration(a.totalTime):0<a.totalEntities?document.getElementById("panel-heading-queue").innerText=a.totalEntities+" "+(1<a.totalEntities?"Songs":"Song"):document.getElementById("panel-heading-queue").innerText="";var b=a.data.length,c=document.getElementById(app.current.app+ | function parseQueue(a){if("Queue"===app.current.app){0<a.totalTime&&a.totalEntities<=settings.maxElementsPerPage?document.getElementById("panel-heading-queue").innerText=a.totalEntities+" "+(1<a.totalEntities?"Songs":"Song")+" \u2013 "+beautifyDuration(a.totalTime):0<a.totalEntities?document.getElementById("panel-heading-queue").innerText=a.totalEntities+" "+(1<a.totalEntities?"Songs":"Song"):document.getElementById("panel-heading-queue").innerText="";var b=a.data.length,c=document.getElementById(app.current.app+ | ||||||
| "List");c.setAttribute("data-version",a.queueVersion);c=c.getElementsByTagName("tbody")[0];for(var d=c.getElementsByTagName("tr"),e=0;e<b;e++)if(!d[e]||d[e].getAttribute("data-trackid")!=a.data[e].id||d[e].getAttribute("data-songpos")!=a.data[e].pos+1){var f=Math.floor(a.data[e].duration/60),g=a.data[e].duration-60*f;f=f+":"+(10>g?"0":"")+g;g=document.createElement("tr");g.setAttribute("draggable","true");g.setAttribute("data-trackid",a.data[e].id);g.setAttribute("id","queueTrackId"+a.data[e].id); | "List");c.setAttribute("data-version",a.queueVersion);c=c.getElementsByTagName("tbody")[0];for(var d=c.getElementsByTagName("tr"),e=0;e<b;e++)if(!d[e]||d[e].getAttribute("data-trackid")!=a.data[e].id||d[e].getAttribute("data-songpos")!=a.data[e].pos+1){var f=Math.floor(a.data[e].duration/60),g=a.data[e].duration-60*f;f=f+":"+(10>g?"0":"")+g;g=document.createElement("tr");g.setAttribute("draggable","true");g.setAttribute("data-trackid",a.data[e].id);g.setAttribute("id","queueTrackId"+a.data[e].id); | ||||||
| g.setAttribute("data-songpos",a.data[e].pos+1);g.setAttribute("data-duration",f);g.setAttribute("data-uri",a.data[e].uri);g.innerHTML="<td>"+(a.data[e].pos+1)+"</td><td>"+a.data[e].title+"</td><td>"+a.data[e].artist+"</td><td>"+a.data[e].album+"</td><td>"+f+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';e<d.length?d[e].replaceWith(g):c.append(g)}for(e=d.length-1;e>=b;e--)d[e].remove();"queuesearch"==a.type&&0==b?c.innerHTML='<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">No results, please refine your search!</td></tr>': | g.setAttribute("data-songpos",a.data[e].pos+1);g.setAttribute("data-duration",f);g.setAttribute("data-uri",a.data[e].uri);g.innerHTML="<td>"+(a.data[e].pos+1)+"</td><td>"+a.data[e].title+"</td><td>"+a.data[e].artist+"</td><td>"+a.data[e].album+"</td><td>"+f+'</td><td><a href="#" class="material-icons color-darkgrey">playlist_add</a></td>';e<d.length?d[e].replaceWith(g):c.append(g)}for(e=d.length-1;e>=b;e--)d[e].remove();"queuesearch"==a.type&&0==b?c.innerHTML='<tr><td><span class="material-icons">error_outline</span></td><td colspan="5">No results, please refine your search!</td></tr>': | ||||||
| @@ -97,9 +98,9 @@ document.getElementById(c+"ButtonsBottom").classList.add("hide"));0<app.current. | |||||||
| function appendQueue(a,b,c){switch(a){case "song":case "dir":sendAPI({cmd:"MPD_API_QUEUE_ADD_TRACK",data:{uri:b}});showNotification('"'+c+'" added',"","","success");break;case "plist":sendAPI({cmd:"MPD_API_QUEUE_ADD_PLAYLIST",data:{plist:b}}),showNotification('"'+c+'" added',"","","success")}}function appendAfterQueue(a,b,c,d){switch(a){case "song":sendAPI({cmd:"MPD_API_QUEUE_ADD_TRACK_AFTER",data:{uri:b,to:c}}),showNotification('"'+d+'" added to pos '+c,"","","success")}} | function appendQueue(a,b,c){switch(a){case "song":case "dir":sendAPI({cmd:"MPD_API_QUEUE_ADD_TRACK",data:{uri:b}});showNotification('"'+c+'" added',"","","success");break;case "plist":sendAPI({cmd:"MPD_API_QUEUE_ADD_PLAYLIST",data:{plist:b}}),showNotification('"'+c+'" added',"","","success")}}function appendAfterQueue(a,b,c,d){switch(a){case "song":sendAPI({cmd:"MPD_API_QUEUE_ADD_TRACK_AFTER",data:{uri:b,to:c}}),showNotification('"'+d+'" added to pos '+c,"","","success")}} | ||||||
| function replaceQueue(a,b,c){switch(a){case "song":case "dir":sendAPI({cmd:"MPD_API_QUEUE_REPLACE_TRACK",data:{uri:b}});showNotification('"'+c+'" replaced',"","","success");break;case "plist":sendAPI({cmd:"MPD_API_QUEUE_REPLACE_PLAYLIST",data:{plist:b}}),showNotification('"'+c+'" replaced',"","","success")}}function songClick(){var a=domCache.currentTrack.getAttribute("data-uri");""!=a&&songDetails(a)} | function replaceQueue(a,b,c){switch(a){case "song":case "dir":sendAPI({cmd:"MPD_API_QUEUE_REPLACE_TRACK",data:{uri:b}});showNotification('"'+c+'" replaced',"","","success");break;case "plist":sendAPI({cmd:"MPD_API_QUEUE_REPLACE_PLAYLIST",data:{plist:b}}),showNotification('"'+c+'" replaced',"","","success")}}function songClick(){var a=domCache.currentTrack.getAttribute("data-uri");""!=a&&songDetails(a)} | ||||||
| function artistClick(){var a=domCache.currentArtist.getAttribute("data-albumartist");""!=a&&appGoto("Browse","Database","AlbumArtist","0/-/"+a)}function albumClick(){var a=domCache.currentAlbum.getAttribute("data-album");""!=a&&appGoto("Browse","Database","Album","0/-/"+a)}function songDetails(a){sendAPI({cmd:"MPD_API_DATABASE_SONGDETAILS",data:{uri:a}},parseSongDetails);modalSongDetails.show()} | function artistClick(){var a=domCache.currentArtist.getAttribute("data-albumartist");""!=a&&appGoto("Browse","Database","AlbumArtist","0/-/"+a)}function albumClick(){var a=domCache.currentAlbum.getAttribute("data-album");""!=a&&appGoto("Browse","Database","Album","0/-/"+a)}function songDetails(a){sendAPI({cmd:"MPD_API_DATABASE_SONGDETAILS",data:{uri:a}},parseSongDetails);modalSongDetails.show()} | ||||||
| function parseSongDetails(a){var b=document.getElementById("modalSongDetails");b.getElementsByClassName("album-cover")[0].style.backgroundImage='url("'+a.data.cover+'")';b.getElementsByTagName("h1")[0].innerText=a.data.title;var c="";for(f in settings.tags)if(1==settings.tags[f]){var d=a.data[f.toLowerCase()];if("duration"==f){var e=Math.floor(d/60);d-=60*e;d=e+":"+(10>d?"0":"")+d}c+="<tr><th>"+f+"</th><td>"+d+"</td></tr>"}c+='<tr><th>Uri</th><td><a class="text-success" href="/library/'+a.data.uri+ | function parseSongDetails(a){var b=document.getElementById("modalSongDetails");b.getElementsByClassName("album-cover")[0].style.backgroundImage='url("'+a.data.cover+'")';b.getElementsByTagName("h1")[0].innerText=a.data.title;for(var c="",d=0;d<settings.tags.length;d++){var e=a.data[settings.tags[d].toLowerCase()];if("duration"==settings.tags[d]){var f=Math.floor(e/60);e-=60*f;e=f+":"+(10>e?"0":"")+e}c+="<tr><th>"+settings.tags[d]+"</th><td>"+e+"</td></tr>"}c+='<tr><th>Uri</th><td><a class="text-success" href="/library/'+ | ||||||
| '">'+a.data.uri+"</a></td></tr>";if(1==settings.stickers){var f="not voted";0==a.data.like?f='<span class="material-icons">thumb_down_alt</span>':2==a.data.like&&(f='<span class="material-icons">thumb_up_alt</span>');c+='<tr><th colspan="2">Statistics</th></tr><tr><th>Play count</th><td>'+a.data.playCount+"</td></tr><tr><th>Skip count</th><td>"+a.data.skipCount+"</td></tr><tr><th>Last played</th><td>"+(0==a.data.lastPlayed?"never":(new Date(1E3*a.data.lastPlayed)).toUTCString())+"</td></tr><tr><th>Like</th><td>"+ | a.data.uri+'">'+a.data.uri+"</a></td></tr>";1==settings.stickers&&(d="not voted",0==a.data.like?d='<span class="material-icons">thumb_down_alt</span>':2==a.data.like&&(d='<span class="material-icons">thumb_up_alt</span>'),c+='<tr><th colspan="2">Statistics</th></tr><tr><th>Play count</th><td>'+a.data.playCount+"</td></tr><tr><th>Skip count</th><td>"+a.data.skipCount+"</td></tr><tr><th>Last played</th><td>"+(0==a.data.lastPlayed?"never":(new Date(1E3*a.data.lastPlayed)).toUTCString())+"</td></tr><tr><th>Like</th><td>"+ | ||||||
| f+"</td></tr>"}b.getElementsByTagName("tbody")[0].innerHTML=c}function playlistDetails(a){document.getElementById("BrowsePlaylistsAllList").classList.add("opacity05");appGoto("Browse","Playlists","Detail","0/-/"+a)} | d+"</td></tr>");b.getElementsByTagName("tbody")[0].innerHTML=c}function playlistDetails(a){document.getElementById("BrowsePlaylistsAllList").classList.add("opacity05");appGoto("Browse","Playlists","Detail","0/-/"+a)} | ||||||
| function removeFromPlaylist(a,b){b--;sendAPI({cmd:"MPD_API_PLAYLIST_RM_TRACK",data:{uri:a,track:b}});document.getElementById("BrowsePlaylistsDetailList").classList.add("opacity05");sendAPI({cmd:"MPD_API_PLAYLIST_CONTENT_LIST",data:{offset:app.current.page,filter:app.current.filter,uri:app.current.search}},parsePlaylists)} | function removeFromPlaylist(a,b){b--;sendAPI({cmd:"MPD_API_PLAYLIST_RM_TRACK",data:{uri:a,track:b}});document.getElementById("BrowsePlaylistsDetailList").classList.add("opacity05");sendAPI({cmd:"MPD_API_PLAYLIST_CONTENT_LIST",data:{offset:app.current.page,filter:app.current.filter,uri:app.current.search}},parsePlaylists)} | ||||||
| function playlistClear(){var a=document.getElementById("BrowsePlaylistsDetailList").getAttribute("data-uri");sendAPI({cmd:"MPD_API_PLAYLIST_CLEAR",data:{uri:a}});document.getElementById("BrowsePlaylistsDetailList").classList.add("opacity05");sendAPI({cmd:"MPD_API_PLAYLIST_CONTENT_LIST",data:{offset:app.current.page,filter:app.current.filter,uri:app.current.search}},parsePlaylists)} | function playlistClear(){var a=document.getElementById("BrowsePlaylistsDetailList").getAttribute("data-uri");sendAPI({cmd:"MPD_API_PLAYLIST_CLEAR",data:{uri:a}});document.getElementById("BrowsePlaylistsDetailList").classList.add("opacity05");sendAPI({cmd:"MPD_API_PLAYLIST_CONTENT_LIST",data:{offset:app.current.page,filter:app.current.filter,uri:app.current.search}},parsePlaylists)} | ||||||
| function getAllPlaylists(a){var b=a.data.length,c="";0==a.offset&&("addToPlaylistPlaylist"==playlistEl?c="<option></option><option>New Playlist</option>":"selectJukeboxPlaylist"==playlistEl&&(c="<option>Database</option>"));for(var d=0;d<b;d++)c+="<option","selectJukeboxPlaylist"==playlistEl&&a.data[d].uri==settings.jukeboxPlaylist&&(c+=" selected"),c+=">"+a.data[d].uri+"</option>";0==a.offset?document.getElementById(playlistEl).innerHTML=c:document.getElementById(playlistEl).innerHTML+=c;a.totalEntities> | function getAllPlaylists(a){var b=a.data.length,c="";0==a.offset&&("addToPlaylistPlaylist"==playlistEl?c="<option></option><option>New Playlist</option>":"selectJukeboxPlaylist"==playlistEl&&(c="<option>Database</option>"));for(var d=0;d<b;d++)c+="<option","selectJukeboxPlaylist"==playlistEl&&a.data[d].uri==settings.jukeboxPlaylist&&(c+=" selected"),c+=">"+a.data[d].uri+"</option>";0==a.offset?document.getElementById(playlistEl).innerHTML=c:document.getElementById(playlistEl).innerHTML+=c;a.totalEntities> | ||||||
| @@ -110,12 +111,12 @@ function setVoteSongBtns(a,b){""==b||0==b.indexOf("http://")||0==b.indexOf("http | |||||||
| function toggleAddToPlaylistFrm(){var a=document.getElementById("toggleAddToPlaylistBtn");toggleBtn("toggleAddToPlaylistBtn");a.classList.contains("active")?(document.getElementById("addToPlaylistFrm").classList.remove("hide"),document.getElementById("addStreamFooter").classList.add("hide"),document.getElementById("addToPlaylistFooter").classList.remove("hide")):(document.getElementById("addToPlaylistFrm").classList.add("hide"),document.getElementById("addStreamFooter").classList.remove("hide"),document.getElementById("addToPlaylistFooter").classList.add("hide"))} | function toggleAddToPlaylistFrm(){var a=document.getElementById("toggleAddToPlaylistBtn");toggleBtn("toggleAddToPlaylistBtn");a.classList.contains("active")?(document.getElementById("addToPlaylistFrm").classList.remove("hide"),document.getElementById("addStreamFooter").classList.add("hide"),document.getElementById("addToPlaylistFooter").classList.remove("hide")):(document.getElementById("addToPlaylistFrm").classList.add("hide"),document.getElementById("addStreamFooter").classList.remove("hide"),document.getElementById("addToPlaylistFooter").classList.add("hide"))} | ||||||
| function saveSearchAsSmartPlaylist(){parseSmartPlaylist({type:"smartpls",data:{playlist:"",type:"search",tag:app.current.filter,searchstr:app.current.search}})} | function saveSearchAsSmartPlaylist(){parseSmartPlaylist({type:"smartpls",data:{playlist:"",type:"search",tag:app.current.filter,searchstr:app.current.search}})} | ||||||
| function parseSmartPlaylist(a){var b=document.getElementById("saveSmartPlaylistName");b.value=a.data.playlist;b.classList.remove("is-invalid");document.getElementById("saveSmartPlaylistType").value=a.data.type;document.getElementById("saveSmartPlaylistFrm").classList.remove("was-validated");document.getElementById("saveSmartPlaylistSearch").classList.add("hide");document.getElementById("saveSmartPlaylistSticker").classList.add("hide");document.getElementById("saveSmartPlaylistNewest").classList.add("hide"); | function parseSmartPlaylist(a){var b=document.getElementById("saveSmartPlaylistName");b.value=a.data.playlist;b.classList.remove("is-invalid");document.getElementById("saveSmartPlaylistType").value=a.data.type;document.getElementById("saveSmartPlaylistFrm").classList.remove("was-validated");document.getElementById("saveSmartPlaylistSearch").classList.add("hide");document.getElementById("saveSmartPlaylistSticker").classList.add("hide");document.getElementById("saveSmartPlaylistNewest").classList.add("hide"); | ||||||
| var c='<option value="any">Any Tag</option>',d;for(d in settings.tags)1==settings.tags[d]&&"Track"!=d&&(c+='<option value="'+d+'">'+d+"</option>");document.getElementById("selectSaveSmartPlaylistTag").innerHTML=c;"search"==a.data.type?(document.getElementById("saveSmartPlaylistSearch").classList.remove("hide"),document.getElementById("selectSaveSmartPlaylistTag").value=a.data.tag,document.getElementById("inputSaveSmartPlaylistSearchstr").value=a.data.searchstr):"sticker"==a.data.type?(document.getElementById("saveSmartPlaylistSticker").classList.remove("hide"), | for(var c='<option value="any">Any Tag</option>',d=0;d<settings.tags.length;d++)"Track"!=settings.tags[d]&&(c+='<option value="'+settings.tags[d]+'">'+settings.tags[d]+"</option>");document.getElementById("selectSaveSmartPlaylistTag").innerHTML=c;"search"==a.data.type?(document.getElementById("saveSmartPlaylistSearch").classList.remove("hide"),document.getElementById("selectSaveSmartPlaylistTag").value=a.data.tag,document.getElementById("inputSaveSmartPlaylistSearchstr").value=a.data.searchstr):"sticker"== | ||||||
| document.getElementById("selectSaveSmartPlaylistSticker").value=a.data.sticker,document.getElementById("inputSaveSmartPlaylistStickerMaxentries").value=a.data.maxentries):"newest"==a.data.type&&(document.getElementById("saveSmartPlaylistNewest").classList.remove("hide"),c=a.data.timerange/24/60/60,document.getElementById("inputSaveSmartPlaylistNewestTimerange").value=c,document.getElementById("inputSaveSmartPlaylistNewestMaxentries").value=a.data.maxentries);modalSaveSmartPlaylist.show();b.focus()} | a.data.type?(document.getElementById("saveSmartPlaylistSticker").classList.remove("hide"),document.getElementById("selectSaveSmartPlaylistSticker").value=a.data.sticker,document.getElementById("inputSaveSmartPlaylistStickerMaxentries").value=a.data.maxentries):"newest"==a.data.type&&(document.getElementById("saveSmartPlaylistNewest").classList.remove("hide"),a=a.data.timerange/24/60/60,document.getElementById("inputSaveSmartPlaylistNewestTimerange").value=a);modalSaveSmartPlaylist.show();b.focus()} | ||||||
| function chkInt(a,b){if(""!=a.value.replace(/\d/g,""))return a.classList.add("is-invalid"),b.classList.add("was-validated"),!1;a.classList.remove("is-invalid");return!0} | function chkInt(a,b){if(""!=a.value.replace(/\d/g,""))return a.classList.add("is-invalid"),b.classList.add("was-validated"),!1;a.classList.remove("is-invalid");return!0} | ||||||
| function saveSmartPlaylist(){var a=document.getElementById("saveSmartPlaylistName").value,b=document.getElementById("saveSmartPlaylistType").value,c=a.replace(/[\w\-]/g,""),d=document.getElementById("saveSmartPlaylistFrm");if(""!=a&&""==c){if("search"==b)d=document.getElementById("selectSaveSmartPlaylistTag"),d=d.options[d.selectedIndex].value,c=document.getElementById("inputSaveSmartPlaylistSearchstr").value,sendAPI({cmd:"MPD_API_SMARTPLS_SAVE",data:{type:b,playlist:a,tag:d,searchstr:c}});else if("sticker"== | function saveSmartPlaylist(){var a=document.getElementById("saveSmartPlaylistName").value,b=document.getElementById("saveSmartPlaylistType").value,c=a.replace(/[\w\-]/g,""),d=document.getElementById("saveSmartPlaylistFrm");if(""!=a&&""==c){if("search"==b)d=document.getElementById("selectSaveSmartPlaylistTag"),d=d.options[d.selectedIndex].value,c=document.getElementById("inputSaveSmartPlaylistSearchstr").value,sendAPI({cmd:"MPD_API_SMARTPLS_SAVE",data:{type:b,playlist:a,tag:d,searchstr:c}});else if("sticker"== | ||||||
| b){c=document.getElementById("selectSaveSmartPlaylistSticker");c=c.options[c.selectedIndex].value;var e=document.getElementById("inputSaveSmartPlaylistStickerMaxentries");if(!chkInt(e,d))return;d=e.value;sendAPI({cmd:"MPD_API_SMARTPLS_SAVE",data:{type:b,playlist:a,sticker:c,maxentries:d}})}else if("newest"==b){c=document.getElementById("inputSaveSmartPlaylistNewestTimerange");if(!chkInt(c,d))return;c=86400*parseInt(c.value);e=document.getElementById("inputSaveSmartPlaylistNewestMaxentries");if(!chkInt(e, | b){c=document.getElementById("selectSaveSmartPlaylistSticker");c=c.options[c.selectedIndex].value;var e=document.getElementById("inputSaveSmartPlaylistStickerMaxentries");if(!chkInt(e,d))return;sendAPI({cmd:"MPD_API_SMARTPLS_SAVE",data:{type:b,playlist:a,sticker:c,maxentries:e.value}})}else if("newest"==b){c=document.getElementById("inputSaveSmartPlaylistNewestTimerange");if(!chkInt(c,d))return;d=86400*parseInt(c.value);sendAPI({cmd:"MPD_API_SMARTPLS_SAVE",data:{type:b,playlist:a,timerange:d}})}else{document.getElementById("saveSmartPlaylistType").classList.add("is-invalid"); | ||||||
| d))return;d=e.value;sendAPI({cmd:"MPD_API_SMARTPLS_SAVE",data:{type:b,playlist:a,timerange:c,maxentries:d}})}else{document.getElementById("saveSmartPlaylistType").classList.add("is-invalid");return}modalSaveSmartPlaylist.hide();showNotification("Saved smart playlist "+a,"","","success")}else document.getElementById("saveSmartPlaylistName").classList.add("is-invalid"),d.classList.add("was-validated")} | return}modalSaveSmartPlaylist.hide();showNotification("Saved smart playlist "+a,"","","success")}else document.getElementById("saveSmartPlaylistName").classList.add("is-invalid"),d.classList.add("was-validated")} | ||||||
| function showAddToPlaylist(a){document.getElementById("addToPlaylistUri").value=a;document.getElementById("addToPlaylistPlaylist").innerHTML="";document.getElementById("addToPlaylistNewPlaylist").value="";document.getElementById("addToPlaylistNewPlaylistDiv").classList.add("hide");document.getElementById("addToPlaylistFrm").classList.remove("was-validated");document.getElementById("addToPlaylistNewPlaylist").classList.remove("is-invalid");toggleBtn("toggleAddToPlaylistBtn",0);var b=document.getElementById("streamUrl"); | function showAddToPlaylist(a){document.getElementById("addToPlaylistUri").value=a;document.getElementById("addToPlaylistPlaylist").innerHTML="";document.getElementById("addToPlaylistNewPlaylist").value="";document.getElementById("addToPlaylistNewPlaylistDiv").classList.add("hide");document.getElementById("addToPlaylistFrm").classList.remove("was-validated");document.getElementById("addToPlaylistNewPlaylist").classList.remove("is-invalid");toggleBtn("toggleAddToPlaylistBtn",0);var b=document.getElementById("streamUrl"); | ||||||
| b.focus();b.value="";b.classList.remove("is-invalid");document.getElementById("addStreamFrm").classList.remove("was-validated");"stream"!=a?(document.getElementById("addStreamFooter").classList.add("hide"),document.getElementById("addStreamFrm").classList.add("hide"),document.getElementById("addToPlaylistFooter").classList.remove("hide"),document.getElementById("addToPlaylistFrm").classList.remove("hide"),document.getElementById("addToPlaylistLabel").innerText="Add to playlist"):(document.getElementById("addStreamFooter").classList.remove("hide"), | b.focus();b.value="";b.classList.remove("is-invalid");document.getElementById("addStreamFrm").classList.remove("was-validated");"stream"!=a?(document.getElementById("addStreamFooter").classList.add("hide"),document.getElementById("addStreamFrm").classList.add("hide"),document.getElementById("addToPlaylistFooter").classList.remove("hide"),document.getElementById("addToPlaylistFrm").classList.remove("hide"),document.getElementById("addToPlaylistLabel").innerText="Add to playlist"):(document.getElementById("addStreamFooter").classList.remove("hide"), | ||||||
| document.getElementById("addStreamFrm").classList.remove("hide"),document.getElementById("addToPlaylistFooter").classList.add("hide"),document.getElementById("addToPlaylistFrm").classList.add("hide"),document.getElementById("addToPlaylistLabel").innerText="Add Stream");modalAddToPlaylist.show();playlistEl="addToPlaylistPlaylist";sendAPI({cmd:"MPD_API_PLAYLIST_LIST",data:{offset:0,filter:"-"}},getAllPlaylists)} | document.getElementById("addStreamFrm").classList.remove("hide"),document.getElementById("addToPlaylistFooter").classList.add("hide"),document.getElementById("addToPlaylistFrm").classList.add("hide"),document.getElementById("addToPlaylistLabel").innerText="Add Stream");modalAddToPlaylist.show();playlistEl="addToPlaylistPlaylist";sendAPI({cmd:"MPD_API_PLAYLIST_LIST",data:{offset:0,filter:"-"}},getAllPlaylists)} | ||||||
| @@ -158,5 +159,6 @@ domCache.currentArtist.innerText="";"undefined"!=typeof a.data.album&&0<a.data.a | |||||||
| function doSetFilterLetter(a){var b=document.getElementById(a+"Letters").getElementsByClassName("active")[0];b&&b.classList.remove("active");b=app.current.filter;"0"==b&&(b="#");document.getElementById(a).innerText="Filter"+("-"!=b?": "+b:"");if("-"!=b){a=document.getElementById(a+"Letters").getElementsByTagName("button");for(var c=a.length,d=0;d<c;d++)if(a[d].innerText==b){a[d].classList.add("active");break}}} | function doSetFilterLetter(a){var b=document.getElementById(a+"Letters").getElementsByClassName("active")[0];b&&b.classList.remove("active");b=app.current.filter;"0"==b&&(b="#");document.getElementById(a).innerText="Filter"+("-"!=b?": "+b:"");if("-"!=b){a=document.getElementById(a+"Letters").getElementsByTagName("button");for(var c=a.length,d=0;d<c;d++)if(a[d].innerText==b){a[d].classList.add("active");break}}} | ||||||
| function addFilterLetter(a){for(var b='<button class="mr-1 mb-1 btn btn-sm btn-secondary material-icons material-icons-small">delete</button><button class="mr-1 mb-1 btn btn-sm btn-secondary">#</button>',c=65;90>=c;c++)b+='<button class="mr-1 mb-1 btn-sm btn btn-secondary">'+String.fromCharCode(c)+"</button>";a=document.getElementById(a);a.innerHTML=b;a.addEventListener("click",function(a){switch(a.target.innerText){case "delete":b="-";break;case "#":b="0";break;default:b=a.target.innerText}appGoto(app.current.app, | function addFilterLetter(a){for(var b='<button class="mr-1 mb-1 btn btn-sm btn-secondary material-icons material-icons-small">delete</button><button class="mr-1 mb-1 btn btn-sm btn-secondary">#</button>',c=65;90>=c;c++)b+='<button class="mr-1 mb-1 btn-sm btn btn-secondary">'+String.fromCharCode(c)+"</button>";a=document.getElementById(a);a.innerHTML=b;a.addEventListener("click",function(a){switch(a.target.innerText){case "delete":b="-";break;case "#":b="0";break;default:b=a.target.innerText}appGoto(app.current.app, | ||||||
| app.current.tab,app.current.view,"0/"+b+"/"+app.current.search)},!1)}function selectTag(a,b,c){a=document.getElementById(a);var d=a.querySelector(".active");d&&d.classList.remove("active");if(d=a.querySelector("[data-tag="+c+"]"))d.classList.add("active"),document.getElementById(b).innerText=d.innerText} | app.current.tab,app.current.view,"0/"+b+"/"+app.current.search)},!1)}function selectTag(a,b,c){a=document.getElementById(a);var d=a.querySelector(".active");d&&d.classList.remove("active");if(d=a.querySelector("[data-tag="+c+"]"))d.classList.add("active"),document.getElementById(b).innerText=d.innerText} | ||||||
| function addTagList(a,b){var c="";1==b&&(c+='<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="any">Any Tag</button>');for(var d in settings.tags)1==settings.tags[d]&&"Track"!=d&&(c+='<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="'+d+'">'+d+"</button>");document.getElementById(a).innerHTML=c}function gotoTagList(){appGoto(app.current.app,app.current.tab,app.current.view,"0/-/")} | function addTagList(a,b){var c="",d="Title MUSICBRAINZ_TRACKID Count Disc Comment Name".split(" ");1==b&&(c+='<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="any">Any Tag</button>');for(var e=0;e<settings.tags.length;e++)"Track"!=settings.tags[e]&&(0==b&&-1<d.indexOf(settings.tags[e])||(c+='<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="'+settings.tags[e]+'">'+settings.tags[e]+"</button>"));document.getElementById(a).innerHTML=c} | ||||||
| function chVolume(a){a=parseInt(domCache.volumeBar.value)+a;0>a?a=0:100<a&&(a=100);domCache.volumeBar.value=a;sendAPI({cmd:"MPD_API_PLAYER_VOLUME",data:{volume:a}})}function beautifyDuration(a){var b=Math.floor(a/86400),c=Math.floor(a/3600)-24*b,d=Math.floor(a/60)-60*c-1440*b;a=a-86400*b-3600*c-60*d;return(0<b?b+"\u2009d ":"")+(0<c?c+"\u2009h "+(10>d?"0":""):"")+d+"\u2009m "+(10>a?"0":"")+a+"\u2009s"}function genId(a){return"id"+a.replace(/[^\w\-]/g,"")}appInit(); | function gotoTagList(){appGoto(app.current.app,app.current.tab,app.current.view,"0/-/")}function chVolume(a){a=parseInt(domCache.volumeBar.value)+a;0>a?a=0:100<a&&(a=100);domCache.volumeBar.value=a;sendAPI({cmd:"MPD_API_PLAYER_VOLUME",data:{volume:a}})}function beautifyDuration(a){var b=Math.floor(a/86400),c=Math.floor(a/3600)-24*b,d=Math.floor(a/60)-60*c-1440*b;a=a-86400*b-3600*c-60*d;return(0<b?b+"\u2009d ":"")+(0<c?c+"\u2009h "+(10>d?"0":""):"")+d+"\u2009m "+(10>a?"0":"")+a+"\u2009s"} | ||||||
|  | function genId(a){return"id"+a.replace(/[^\w\-]/g,"")}appInit(); | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								dist/htdocs/sw.min.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/htdocs/sw.min.js
									
									
									
									
										vendored
									
									
								
							| @@ -10,5 +10,5 @@ function(){function a(a){return function(d){c||(c=!0,a.call(b,d))}}var b=this,c= | |||||||
| void 0;try{d=a.then}catch(h){this.reject_(h);return}"function"==typeof d?this.settleSameAsThenable_(d,a):this.fulfill_(a)};c.prototype.reject_=function(a){this.settle_(2,a)};c.prototype.fulfill_=function(a){this.settle_(1,a)};c.prototype.settle_=function(a,b){if(0!=this.state_)throw Error("Cannot settle("+a+", "+b+"): Promise already settled in state"+this.state_);this.state_=a;this.result_=b;this.executeOnSettledCallbacks_()};c.prototype.executeOnSettledCallbacks_=function(){if(null!=this.onSettledCallbacks_){for(var a= | void 0;try{d=a.then}catch(h){this.reject_(h);return}"function"==typeof d?this.settleSameAsThenable_(d,a):this.fulfill_(a)};c.prototype.reject_=function(a){this.settle_(2,a)};c.prototype.fulfill_=function(a){this.settle_(1,a)};c.prototype.settle_=function(a,b){if(0!=this.state_)throw Error("Cannot settle("+a+", "+b+"): Promise already settled in state"+this.state_);this.state_=a;this.result_=b;this.executeOnSettledCallbacks_()};c.prototype.executeOnSettledCallbacks_=function(){if(null!=this.onSettledCallbacks_){for(var a= | ||||||
| 0;a<this.onSettledCallbacks_.length;++a)l.asyncExecute(this.onSettledCallbacks_[a]);this.onSettledCallbacks_=null}};var l=new b;c.prototype.settleSameAsPromise_=function(a){var b=this.createResolveAndReject_();a.callWhenSettled_(b.resolve,b.reject)};c.prototype.settleSameAsThenable_=function(a,b){var c=this.createResolveAndReject_();try{a.call(b,c.resolve,c.reject)}catch(k){c.reject(k)}};c.prototype.then=function(a,b){function d(a,b){return"function"==typeof a?function(b){try{f(a(b))}catch(m){e(m)}}: | 0;a<this.onSettledCallbacks_.length;++a)l.asyncExecute(this.onSettledCallbacks_[a]);this.onSettledCallbacks_=null}};var l=new b;c.prototype.settleSameAsPromise_=function(a){var b=this.createResolveAndReject_();a.callWhenSettled_(b.resolve,b.reject)};c.prototype.settleSameAsThenable_=function(a,b){var c=this.createResolveAndReject_();try{a.call(b,c.resolve,c.reject)}catch(k){c.reject(k)}};c.prototype.then=function(a,b){function d(a,b){return"function"==typeof a?function(b){try{f(a(b))}catch(m){e(m)}}: | ||||||
| b}var f,e,g=new c(function(a,b){f=a;e=b});this.callWhenSettled_(d(a,f),d(b,e));return g};c.prototype.catch=function(a){return this.then(void 0,a)};c.prototype.callWhenSettled_=function(a,b){function c(){switch(d.state_){case 1:a(d.result_);break;case 2:b(d.result_);break;default:throw Error("Unexpected state: "+d.state_);}}var d=this;null==this.onSettledCallbacks_?l.asyncExecute(c):this.onSettledCallbacks_.push(c)};c.resolve=f;c.reject=function(a){return new c(function(b,c){c(a)})};c.race=function(a){return new c(function(b, | b}var f,e,g=new c(function(a,b){f=a;e=b});this.callWhenSettled_(d(a,f),d(b,e));return g};c.prototype.catch=function(a){return this.then(void 0,a)};c.prototype.callWhenSettled_=function(a,b){function c(){switch(d.state_){case 1:a(d.result_);break;case 2:b(d.result_);break;default:throw Error("Unexpected state: "+d.state_);}}var d=this;null==this.onSettledCallbacks_?l.asyncExecute(c):this.onSettledCallbacks_.push(c)};c.resolve=f;c.reject=function(a){return new c(function(b,c){c(a)})};c.race=function(a){return new c(function(b, | ||||||
| c){for(var d=$jscomp.makeIterator(a),e=d.next();!e.done;e=d.next())f(e.value).callWhenSettled_(b,c)})};c.all=function(a){var b=$jscomp.makeIterator(a),d=b.next();return d.done?f([]):new c(function(a,c){function e(b){return function(c){g[b]=c;h--;0==h&&a(g)}}var g=[],h=0;do g.push(void 0),h++,f(d.value).callWhenSettled_(e(g.length-1),c),d=b.next();while(!d.done)})};return c},"es6","es3");var CACHE="myMPD-cache-v4.3.0",urlsToCache="/ /player.html /css/bootstrap.min.css /css/mympd.min.css /js/bootstrap-native-v4.min.js /js/mympd.min.js /js/player.min.js /assets/appicon-167.png /assets/appicon-192.png /assets/appicon-512.png /assets/coverimage-httpstream.png /assets/coverimage-notavailable.png /assets/favicon.ico /assets/MaterialIcons-Regular.eot /assets/MaterialIcons-Regular.ttf /assets/MaterialIcons-Regular.woff /assets/MaterialIcons-Regular.woff2".split(" "); | c){for(var d=$jscomp.makeIterator(a),e=d.next();!e.done;e=d.next())f(e.value).callWhenSettled_(b,c)})};c.all=function(a){var b=$jscomp.makeIterator(a),d=b.next();return d.done?f([]):new c(function(a,c){function e(b){return function(c){g[b]=c;h--;0==h&&a(g)}}var g=[],h=0;do g.push(void 0),h++,f(d.value).callWhenSettled_(e(g.length-1),c),d=b.next();while(!d.done)})};return c},"es6","es3");var CACHE="myMPD-cache-v4.3.1",urlsToCache="/ /player.html /css/bootstrap.min.css /css/mympd.min.css /js/bootstrap-native-v4.min.js /js/mympd.min.js /js/player.min.js /assets/appicon-167.png /assets/appicon-192.png /assets/appicon-512.png /assets/coverimage-httpstream.png /assets/coverimage-notavailable.png /assets/favicon.ico /assets/MaterialIcons-Regular.eot /assets/MaterialIcons-Regular.ttf /assets/MaterialIcons-Regular.woff /assets/MaterialIcons-Regular.woff2".split(" "); | ||||||
| self.addEventListener("install",function(a){a.waitUntil(caches.open(CACHE).then(function(a){return a.addAll(urlsToCache)}))});self.addEventListener("fetch",function(a){if(a.request.url.match("^http://"))return!1;a.respondWith(caches.match(a.request).then(function(b){return b?b:fetch(a.request)}))});self.addEventListener("activate",function(a){a.waitUntil(caches.keys().then(function(a){return Promise.all(a.map(function(a){if(a!=CACHE)return caches.delete(a)}))}))}); | self.addEventListener("install",function(a){a.waitUntil(caches.open(CACHE).then(function(a){return a.addAll(urlsToCache)}))});self.addEventListener("fetch",function(a){if(a.request.url.match("^http://"))return!1;a.respondWith(caches.match(a.request).then(function(b){return b?b:fetch(a.request)}))});self.addEventListener("activate",function(a){a.waitUntil(caches.keys().then(function(a){return Promise.all(a.map(function(a){if(a!=CACHE)return caches.delete(a)}))}))}); | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								dist/smartpls/myMPDsmart-newestSongs.dist
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/smartpls/myMPDsmart-newestSongs.dist
									
									
									
									
										vendored
									
									
								
							| @@ -1 +1 @@ | |||||||
| {"type": "newest", "timerange": 604800 , "maxentries": 200} | {"type": "newest", "timerange": 604800} | ||||||
|   | |||||||
| @@ -699,11 +699,6 @@ | |||||||
|                 <input type="text" class="form-control" id="inputSaveSmartPlaylistNewestTimerange"/> |                 <input type="text" class="form-control" id="inputSaveSmartPlaylistNewestTimerange"/> | ||||||
|                 <div class="invalid-feedback">Must be a number.</div> |                 <div class="invalid-feedback">Must be a number.</div> | ||||||
|               </div>             |               </div>             | ||||||
|               <div class="form-group col-md-6"> |  | ||||||
|                 <label for="inputSaveSmartPlaylistNewestMaxentries">Max. entries</label> |  | ||||||
|                 <input type="text" class="form-control" id="inputSaveSmartPlaylistNewestMaxentries"/> |  | ||||||
|                 <div class="invalid-feedback">Must be a number.</div> |  | ||||||
|               </div> |  | ||||||
|             </div>             |             </div>             | ||||||
|           </form> |           </form> | ||||||
|         </div> |         </div> | ||||||
|   | |||||||
| @@ -567,20 +567,46 @@ function appInit() { | |||||||
|     }, false); |     }, false); | ||||||
|      |      | ||||||
|     document.addEventListener('keydown', function(event) { |     document.addEventListener('keydown', function(event) { | ||||||
|         if (event.target.tagName == 'INPUT') |         if (event.target.tagName == 'INPUT' || event.target.tagName == 'SELECT') | ||||||
|             return; |             return; | ||||||
|         switch (event.which) { |         if (event.shiftKey) { | ||||||
|             case 37: //left |             switch (event.which) { | ||||||
|                 clickPrev(); |                 case 83: //S | ||||||
|                 break; |                     sendAPI({"cmd": "MPD_API_QUEUE_SHUFFLE"}); | ||||||
|             case 39: //right |                     break; | ||||||
|                 clickNext(); |                 case 67: //C | ||||||
|                 break; |                     sendAPI({"cmd": "MPD_API_QUEUE_CROP"}); | ||||||
|             case 32: //space |                     break; | ||||||
|                 clickPlay(); |                 default: | ||||||
|                 break; |                     return; | ||||||
|             default: |             } | ||||||
|                 return; |         } | ||||||
|  |         else { | ||||||
|  |             switch (event.which) { | ||||||
|  |                 case 37: //left | ||||||
|  |                     clickPrev(); | ||||||
|  |                     break; | ||||||
|  |                 case 39: //right | ||||||
|  |                     clickNext(); | ||||||
|  |                     break; | ||||||
|  |                 case 32: //space | ||||||
|  |                     clickPlay(); | ||||||
|  |                     break; | ||||||
|  |                 case 83: //s | ||||||
|  |                     clickStop(); | ||||||
|  |                     break; | ||||||
|  |                 case 173: //- | ||||||
|  |                     chVolume(-5); | ||||||
|  |                     break; | ||||||
|  |                 case 171: //+ | ||||||
|  |                     chVolume(5); | ||||||
|  |                     break; | ||||||
|  |                 case 67: //c | ||||||
|  |                     sendAPI({"cmd": "MPD_API_QUEUE_CLEAR"}); | ||||||
|  |                     break; | ||||||
|  |                 default: | ||||||
|  |                     return; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         event.preventDefault(); |         event.preventDefault(); | ||||||
|     }, false); |     }, false); | ||||||
| @@ -1029,7 +1055,8 @@ function parseState(obj) { | |||||||
|     setCounter(obj.data.currentSongId, obj.data.totalTime, obj.data.elapsedTime); |     setCounter(obj.data.currentSongId, obj.data.totalTime, obj.data.elapsedTime); | ||||||
|      |      | ||||||
|     //Get current song |     //Get current song | ||||||
|     sendAPI({"cmd": "MPD_API_PLAYER_CURRENT_SONG"}, songChange); |     if (lastState && lastState.data.currentSongId != obj.data.currentSongId) | ||||||
|  |         sendAPI({"cmd": "MPD_API_PLAYER_CURRENT_SONG"}, songChange); | ||||||
|     //clear playback card if not playing |     //clear playback card if not playing | ||||||
|     if (obj.data.songPos == '-1') { |     if (obj.data.songPos == '-1') { | ||||||
|         domCache.currentTrack.innerText = 'Not playing'; |         domCache.currentTrack.innerText = 'Not playing'; | ||||||
| @@ -1508,16 +1535,14 @@ function parseSongDetails(obj) { | |||||||
|     modal.getElementsByTagName('h1')[0].innerText = obj.data.title; |     modal.getElementsByTagName('h1')[0].innerText = obj.data.title; | ||||||
|      |      | ||||||
|     var songDetails = ''; |     var songDetails = ''; | ||||||
|     for (var key in settings.tags) { |     for (var i = 0; i < settings.tags.length; i++) { | ||||||
|         if (settings.tags[key] == true) { |         var value = obj.data[settings.tags[i].toLowerCase()]; | ||||||
|             var value = obj.data[key.toLowerCase()]; |         if (settings.tags[i] == 'duration') { | ||||||
|             if (key == 'duration') { |             var minutes = Math.floor(value / 60); | ||||||
|                 var minutes = Math.floor(value / 60); |             var seconds = value - minutes * 60; | ||||||
|                 var seconds = value - minutes * 60; |             value = minutes + ':' + (seconds < 10 ? '0' : '') + seconds;         | ||||||
|                 value = minutes + ':' + (seconds < 10 ? '0' : '') + seconds;         |  | ||||||
|             } |  | ||||||
|             songDetails += '<tr><th>' + key + '</th><td>' + value + '</td></tr>'; |  | ||||||
|         } |         } | ||||||
|  |         songDetails += '<tr><th>' + settings.tags[i] + '</th><td>' + value + '</td></tr>'; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     songDetails += '<tr><th>Uri</th><td><a class="text-success" href="/library/' + obj.data.uri + '">' + obj.data.uri + '</a></td></tr>'; |     songDetails += '<tr><th>Uri</th><td><a class="text-success" href="/library/' + obj.data.uri + '">' + obj.data.uri + '</a></td></tr>'; | ||||||
| @@ -1649,9 +1674,9 @@ function parseSmartPlaylist(obj) { | |||||||
|     document.getElementById('saveSmartPlaylistSticker').classList.add('hide'); |     document.getElementById('saveSmartPlaylistSticker').classList.add('hide'); | ||||||
|     document.getElementById('saveSmartPlaylistNewest').classList.add('hide'); |     document.getElementById('saveSmartPlaylistNewest').classList.add('hide'); | ||||||
|     var tagList = '<option value="any">Any Tag</option>'; |     var tagList = '<option value="any">Any Tag</option>'; | ||||||
|     for (var key in settings.tags) { |     for (var i = 0; i < settings.tags.length; i++) { | ||||||
|         if (settings.tags[key] == true && key != 'Track') { |         if (settings.tags[i] != 'Track') { | ||||||
|             tagList += '<option value="' + key + '">' + key + '</option>'; |             tagList += '<option value="' + settings.tags[i] + '">' + settings.tags[i] + '</option>'; | ||||||
|         } |         } | ||||||
|     }     |     }     | ||||||
|     document.getElementById('selectSaveSmartPlaylistTag').innerHTML = tagList; |     document.getElementById('selectSaveSmartPlaylistTag').innerHTML = tagList; | ||||||
| @@ -1669,7 +1694,6 @@ function parseSmartPlaylist(obj) { | |||||||
|         document.getElementById('saveSmartPlaylistNewest').classList.remove('hide'); |         document.getElementById('saveSmartPlaylistNewest').classList.remove('hide'); | ||||||
|         var timerange = obj.data.timerange / 24 / 60 / 60; |         var timerange = obj.data.timerange / 24 / 60 / 60; | ||||||
|         document.getElementById('inputSaveSmartPlaylistNewestTimerange').value = timerange; |         document.getElementById('inputSaveSmartPlaylistNewestTimerange').value = timerange; | ||||||
|         document.getElementById('inputSaveSmartPlaylistNewestMaxentries').value = obj.data.maxentries; |  | ||||||
|     } |     } | ||||||
|     modalSaveSmartPlaylist.show(); |     modalSaveSmartPlaylist.show(); | ||||||
|     nameEl.focus(); |     nameEl.focus(); | ||||||
| @@ -1711,11 +1735,7 @@ function saveSmartPlaylist() { | |||||||
|             if (!chkInt(timerangeEl, frm)) |             if (!chkInt(timerangeEl, frm)) | ||||||
|                 return; |                 return; | ||||||
|             var timerange = parseInt(timerangeEl.value) * 60 * 60 * 24; |             var timerange = parseInt(timerangeEl.value) * 60 * 60 * 24; | ||||||
|             var maxentriesEl = document.getElementById('inputSaveSmartPlaylistNewestMaxentries'); |             sendAPI({"cmd": "MPD_API_SMARTPLS_SAVE", "data": {"type": type, "playlist": name, "timerange": timerange}}); | ||||||
|             if (!chkInt(maxentriesEl, frm)) |  | ||||||
|                 return; |  | ||||||
|             var maxentries = maxentriesEl.value; |  | ||||||
|             sendAPI({"cmd": "MPD_API_SMARTPLS_SAVE", "data": {"type": type, "playlist": name, "timerange": timerange, "maxentries": maxentries}}); |  | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|             document.getElementById('saveSmartPlaylistType').classList.add('is-invalid'); |             document.getElementById('saveSmartPlaylistType').classList.add('is-invalid'); | ||||||
| @@ -2374,12 +2394,15 @@ function selectTag(btnsEl, desc, setTo) { | |||||||
|  |  | ||||||
| function addTagList(x, any) { | function addTagList(x, any) { | ||||||
|     var tagList = ''; |     var tagList = ''; | ||||||
|  |     var tagBlacklist = ["Title", "MUSICBRAINZ_TRACKID", "Count", "Disc", "Comment", "Name"]; | ||||||
|     if (any == true) |     if (any == true) | ||||||
|         tagList += '<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="any">Any Tag</button>'; |         tagList += '<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="any">Any Tag</button>'; | ||||||
|     for (var key in settings.tags) { |     for (var i = 0; i < settings.tags.length; i++) { | ||||||
|         if (settings.tags[key] == true && key != 'Track') { |         if (settings.tags[i] == 'Track') | ||||||
|             tagList += '<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="' + key + '">' + key + '</button>'; |             continue; | ||||||
|         } |         if (any == false && tagBlacklist.indexOf(settings.tags[i]) > -1) | ||||||
|  |             continue; | ||||||
|  |         tagList += '<button type="button" class="btn btn-secondary btn-sm btn-block" data-tag="' + settings.tags[i] + '">' + settings.tags[i] + '</button>'; | ||||||
|     } |     } | ||||||
|     var tagListEl = document.getElementById(x); |     var tagListEl = document.getElementById(x); | ||||||
|     tagListEl.innerHTML = tagList; |     tagListEl.innerHTML = tagList; | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| var CACHE = 'myMPD-cache-v4.3.0'; | var CACHE = 'myMPD-cache-v4.3.1'; | ||||||
| var urlsToCache = [ | var urlsToCache = [ | ||||||
|     '/', |     '/', | ||||||
|     '/player.html', |     '/player.html', | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								mkdebian.sh
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								mkdebian.sh
									
									
									
									
									
								
							| @@ -1,4 +1,15 @@ | |||||||
| #!/bin/bash | #!/bin/bash | ||||||
|  |  | ||||||
|  | VERSION=$(grep VERSION_ CMakeLists.txt | cut -d\" -f2 | tr '\n' '.') | ||||||
|  |  | ||||||
|  | cat > debian/changelog << EOL | ||||||
|  | mympd (${VERSION}-1) stable; urgency=medium | ||||||
|  |  | ||||||
|  |   * Release from master | ||||||
|  |  | ||||||
|  |  -- Juergen Mang <mail@jcgames.de>  $(date +"%a, %d %b %Y %H:%m:%S %z") | ||||||
|  | EOL | ||||||
|  |  | ||||||
| ./mkclean.sh | ./mkclean.sh | ||||||
| tar -czvf ../mympd_4.3.0.orig.tar.gz * | tar -czvf ../mympd_${VERSION}.orig.tar.gz * | ||||||
| dpkg-buildpackage -rfakeroot | dpkg-buildpackage -rfakeroot | ||||||
|   | |||||||
							
								
								
									
										124
									
								
								src/list.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								src/list.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | |||||||
|  | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <time.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include "list.h" | ||||||
|  |  | ||||||
|  | int list_init(struct list *l) { | ||||||
|  |     l->length = 0; | ||||||
|  |     l->list = NULL; | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int list_get_value(const struct list *l, char *data) { | ||||||
|  |     int value = 0; | ||||||
|  |     struct node *current = l->list; | ||||||
|  |     while (current != NULL) { | ||||||
|  |         if (strcmp(current->data, data) == 0) { | ||||||
|  |             value = current->value; | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         current = current->next; | ||||||
|  |     } | ||||||
|  |     return value; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | struct node *list_node_at(const struct list *l, unsigned index) { | ||||||
|  |     /* if there's no data in the list, fail */ | ||||||
|  |     if (l->list == NULL) { return NULL; } | ||||||
|  |     struct node * current = l->list; | ||||||
|  |     for (; index > 0; index--) { | ||||||
|  |         if (current->next == NULL) { return NULL; } | ||||||
|  |         current = current->next; | ||||||
|  |     } | ||||||
|  |     return current; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int list_swap_item(struct node *n1, struct node *n2) { | ||||||
|  |     if (n1 == n2) | ||||||
|  |         return 1; | ||||||
|  |          | ||||||
|  |     if (n1 == NULL || n2 == NULL) | ||||||
|  |         return 1; | ||||||
|  |          | ||||||
|  |     int value = n2->value; | ||||||
|  |     char *data = strdup(n2->data); | ||||||
|  |      | ||||||
|  |     n2->value = n1->value; | ||||||
|  |     n2->data = realloc(n2->data, strlen(n1->data) + 1); | ||||||
|  |     if (n2->data) | ||||||
|  |         strcpy(n2->data, n1->data); | ||||||
|  |      | ||||||
|  |     n1->value = value; | ||||||
|  |     n1->data = realloc(n1->data, strlen(data) + 1); | ||||||
|  |     if (n1->data) | ||||||
|  |         strcpy(n1->data, data); | ||||||
|  |      | ||||||
|  |     free(data); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int list_shuffle(struct list *l) { | ||||||
|  |     int pos; | ||||||
|  |     int n = 0; | ||||||
|  |  | ||||||
|  |     if (l->length < 2) | ||||||
|  |         return 1; | ||||||
|  |  | ||||||
|  |     srand((unsigned int)time(NULL)); | ||||||
|  |      | ||||||
|  |     struct node *current = l->list; | ||||||
|  |     while (current != NULL) { | ||||||
|  |         pos = rand() / (RAND_MAX / (l->length - n + 1) + 1); | ||||||
|  |         list_swap_item(current, list_node_at(l, pos)); | ||||||
|  |         n++; | ||||||
|  |         current = current->next; | ||||||
|  |     } | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int list_replace(struct list *l, int pos, char *data, int value) { | ||||||
|  |     int i = 0; | ||||||
|  |     struct node *current = l->list; | ||||||
|  |     while (current->next != NULL) { | ||||||
|  |         if (i == pos) | ||||||
|  |             break; | ||||||
|  |         current = current->next; | ||||||
|  |         i++; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     current->value = value; | ||||||
|  |     current->data = realloc(current->data, strlen(data) + 1); | ||||||
|  |     if (current->data) | ||||||
|  |         strcpy(current->data, data); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int list_push(struct list *l, char *data, int value) { | ||||||
|  |     struct node *n = malloc(sizeof(struct node)); | ||||||
|  |     n->value = value; | ||||||
|  |     n->data = strdup(data); | ||||||
|  |     n->next = NULL; | ||||||
|  |  | ||||||
|  |     struct node **next = &l->list; | ||||||
|  |     while (*next != NULL) { | ||||||
|  |         next = &(*next)->next; | ||||||
|  |     } | ||||||
|  |     *next = n; | ||||||
|  |     l->length++; | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int list_free(struct list *l) { | ||||||
|  |     struct node *current = l->list, *tmp = NULL; | ||||||
|  |     while (current != NULL) { | ||||||
|  |         free(current->data); | ||||||
|  |         tmp = current; | ||||||
|  |         current = current->next; | ||||||
|  |         free(tmp); | ||||||
|  |     } | ||||||
|  |     list_init(l); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								src/list.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/list.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | struct node { | ||||||
|  |     char *data; | ||||||
|  |     int value; | ||||||
|  |     struct node *next; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | struct list { | ||||||
|  |     unsigned length; | ||||||
|  |     struct node *list; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | int list_init(struct list *l); | ||||||
|  | int list_push(struct list *l, char *data, int value); | ||||||
|  | int list_replace(struct list *l, int pos, char *data, int value); | ||||||
|  | int list_free(struct list *l); | ||||||
|  | int list_get_value(const struct list *l, char *data); | ||||||
|  | int list_shuffle(struct list *l); | ||||||
|  | int list_swap_item(struct node *n1, struct node *n2); | ||||||
|  | struct node *list_node_at(const struct list * l, unsigned index); | ||||||
							
								
								
									
										472
									
								
								src/mpd_client.c
									
									
									
									
									
								
							
							
						
						
									
										472
									
								
								src/mpd_client.c
									
									
									
									
									
								
							| @@ -54,7 +54,7 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) { | |||||||
|     size_t n = 0; |     size_t n = 0; | ||||||
|     char *cmd; |     char *cmd; | ||||||
|     unsigned int uint_buf1, uint_buf2, uint_rc; |     unsigned int uint_buf1, uint_buf2, uint_rc; | ||||||
|     int je, int_buf1, int_buf2, int_rc;  |     int je, int_buf1, int_rc;  | ||||||
|     float float_buf; |     float float_buf; | ||||||
|     char *p_charbuf1, *p_charbuf2, *p_charbuf3, *p_charbuf4; |     char *p_charbuf1, *p_charbuf2, *p_charbuf3, *p_charbuf4; | ||||||
|     char p_char[4]; |     char p_char[4]; | ||||||
| @@ -210,8 +210,8 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) { | |||||||
|                     free(p_charbuf3); |                     free(p_charbuf3); | ||||||
|                 } |                 } | ||||||
|                 else if (strcmp(p_charbuf1, "newest") == 0) { |                 else if (strcmp(p_charbuf1, "newest") == 0) { | ||||||
|                     je = json_scanf(msg.p, msg.len, "{data: {playlist: %Q, timerange: %d, maxentries: %d}}", &p_charbuf2, &int_buf1, &int_buf2); |                     je = json_scanf(msg.p, msg.len, "{data: {playlist: %Q, timerange: %d}}", &p_charbuf2, &int_buf1); | ||||||
|                     n = mympd_smartpls_save(p_charbuf1, p_charbuf2, NULL, NULL, int_buf2, int_buf1); |                     n = mympd_smartpls_save(p_charbuf1, p_charbuf2, NULL, NULL, 0, int_buf1); | ||||||
|                     free(p_charbuf2); |                     free(p_charbuf2); | ||||||
|                 }             |                 }             | ||||||
|                 else if (strcmp(p_charbuf1, "search") == 0) { |                 else if (strcmp(p_charbuf1, "search") == 0) { | ||||||
| @@ -680,15 +680,6 @@ void mympd_mpd_features() { | |||||||
|  |  | ||||||
|     // Defaults |     // Defaults | ||||||
|     mpd.feat_sticker = false; |     mpd.feat_sticker = false; | ||||||
|     mpd.tag_artist = false; |  | ||||||
|     mpd.tag_album = false; |  | ||||||
|     mpd.tag_album_artist = false; |  | ||||||
|     mpd.tag_title = false; |  | ||||||
|     mpd.tag_track = false; |  | ||||||
|     mpd.tag_genre = false; |  | ||||||
|     mpd.tag_date = false; |  | ||||||
|     mpd.tag_composer = false; |  | ||||||
|     mpd.tag_performer = false; |  | ||||||
|  |  | ||||||
|     mpd_send_allowed_commands(mpd.conn); |     mpd_send_allowed_commands(mpd.conn); | ||||||
|     while ((pair = mpd_recv_command_pair(mpd.conn)) != NULL) { |     while ((pair = mpd_recv_command_pair(mpd.conn)) != NULL) { | ||||||
| @@ -708,69 +699,22 @@ void mympd_mpd_features() { | |||||||
|     } |     } | ||||||
|   |   | ||||||
|     printf("MPD supported tags: "); |     printf("MPD supported tags: "); | ||||||
|  |     list_free(&mpd_tags); | ||||||
|     mpd_send_list_tag_types(mpd.conn); |     mpd_send_list_tag_types(mpd.conn); | ||||||
|     while ((pair = mpd_recv_tag_type_pair(mpd.conn)) != NULL) { |     while ((pair = mpd_recv_tag_type_pair(mpd.conn)) != NULL) { | ||||||
|         printf("%s ", pair->value); |         printf("%s ", pair->value); | ||||||
|         if (strcmp(pair->value, "Artist") == 0) |         list_push(&mpd_tags, pair->value, 1); | ||||||
|             mpd.tag_artist = true; |  | ||||||
|         else if (strcmp(pair->value, "Album") == 0) |  | ||||||
|             mpd.tag_album = true; |  | ||||||
|         else if (strcmp(pair->value, "AlbumArtist") == 0) |  | ||||||
|             mpd.tag_album_artist = true; |  | ||||||
|         else if (strcmp(pair->value, "Title") == 0) |  | ||||||
|             mpd.tag_title = true; |  | ||||||
|         else if (strcmp(pair->value, "Track") == 0) |  | ||||||
|             mpd.tag_track = true; |  | ||||||
|         else if (strcmp(pair->value, "Genre") == 0) |  | ||||||
|             mpd.tag_genre = true; |  | ||||||
|         else if (strcmp(pair->value, "Date") == 0) |  | ||||||
|             mpd.tag_date = true; |  | ||||||
|         else if (strcmp(pair->value, "Composer") == 0) |  | ||||||
|             mpd.tag_composer = true; |  | ||||||
|         else if (strcmp(pair->value, "Performer") == 0) |  | ||||||
|             mpd.tag_performer = true; |  | ||||||
|         mpd_return_pair(mpd.conn, pair); |         mpd_return_pair(mpd.conn, pair); | ||||||
|     } |     } | ||||||
|     mpd_response_finish(mpd.conn); |     mpd_response_finish(mpd.conn); | ||||||
|     printf("\nmyMPD enabled tags: "); |     printf("\nmyMPD enabled tags: "); | ||||||
|  |  | ||||||
|  |     list_free(&mympd_tags); | ||||||
|     token = strtok(str, s); |     token = strtok(str, s); | ||||||
|     while (token != NULL) { |     while (token != NULL) { | ||||||
|         if (strcmp(token, "Artist") == 0) { |         if (list_get_value(&mpd_tags, token) == 1) { | ||||||
|             if (mpd.tag_artist == true) printf("%s ", token); |             list_push(&mympd_tags, token, 1); | ||||||
|             else mpd.tag_artist = false; |             printf("%s ", token); | ||||||
|         } |  | ||||||
|         else if (strcmp(token, "Album") == 0) { |  | ||||||
|             if (mpd.tag_album == true) printf("%s ", token); |  | ||||||
|             else mpd.tag_album = false; |  | ||||||
|         } |  | ||||||
|         else if (strcmp(token, "AlbumArtist") == 0) { |  | ||||||
|             if (mpd.tag_album_artist == true) printf("%s ", token); |  | ||||||
|             else mpd.tag_album_artist = false; |  | ||||||
|         } |  | ||||||
|         else if (strcmp(token, "Title") == 0) { |  | ||||||
|             if (mpd.tag_title == true) printf("%s ", token); |  | ||||||
|             else mpd.tag_title = false; |  | ||||||
|         } |  | ||||||
|         else if (strcmp(token, "Track") == 0) { |  | ||||||
|             if (mpd.tag_track == true) printf("%s ", token); |  | ||||||
|             else mpd.tag_track = false; |  | ||||||
|         } |  | ||||||
|         else if (strcmp(token, "Genre") == 0) { |  | ||||||
|             if (mpd.tag_genre == true) printf("%s ", token); |  | ||||||
|             else mpd.tag_genre = false; |  | ||||||
|         } |  | ||||||
|         else if (strcmp(token, "Date") == 0) { |  | ||||||
|             if (mpd.tag_date == true) printf("%s ", token); |  | ||||||
|             else mpd.tag_date = false; |  | ||||||
|         } |  | ||||||
|         else if (strcmp(token, "Composer") == 0) { |  | ||||||
|             if (mpd.tag_composer == true) printf("%s ", token); |  | ||||||
|             else mpd.tag_composer = false; |  | ||||||
|         } |  | ||||||
|         else if (strcmp(token, "Performer") == 0) { |  | ||||||
|             if (mpd.tag_performer == true) printf("%s ", token); |  | ||||||
|             else mpd.tag_performer = false; |  | ||||||
|         } |         } | ||||||
|         token = strtok(NULL, s); |         token = strtok(NULL, s); | ||||||
|    } |    } | ||||||
| @@ -1008,11 +952,12 @@ char* mympd_get_tag(struct mpd_song const *song, enum mpd_tag_type tag) { | |||||||
| void mympd_jukebox() { | void mympd_jukebox() { | ||||||
|     struct mpd_status *status; |     struct mpd_status *status; | ||||||
|     status = mpd_run_status(mpd.conn); |     status = mpd_run_status(mpd.conn); | ||||||
|     int queue_length, num_songs, rand_song, i, j, addSongs; |     int queue_length, addSongs, i; | ||||||
|     struct mpd_entity *entity; |     struct mpd_entity *entity; | ||||||
|     const struct mpd_song *song; |     const struct mpd_song *song; | ||||||
|     struct mpd_pair *pair; |     struct mpd_pair *pair; | ||||||
|     char *album; |     int lineno = 1; | ||||||
|  |     int nkeep = 0; | ||||||
|  |  | ||||||
|     if (!status) { |     if (!status) { | ||||||
|         LOG_ERROR_AND_RECOVER("mpd_run_status"); |         LOG_ERROR_AND_RECOVER("mpd_run_status"); | ||||||
| @@ -1022,116 +967,128 @@ void mympd_jukebox() { | |||||||
|     mpd_status_free(status); |     mpd_status_free(status); | ||||||
|     if (queue_length > mympd_state.jukeboxQueueLength) |     if (queue_length > mympd_state.jukeboxQueueLength) | ||||||
|         return; |         return; | ||||||
|          |  | ||||||
|     srand((unsigned int)time(NULL)); |  | ||||||
|     num_songs = 0; |  | ||||||
|  |  | ||||||
|     if (mympd_state.jukeboxMode == 1 && strcmp(mympd_state.jukeboxPlaylist, "Database") == 0) { |  | ||||||
|         struct mpd_stats *stats = mpd_run_stats(mpd.conn); |  | ||||||
|         if (stats == NULL) { |  | ||||||
|             LOG_ERROR_AND_RECOVER("mpd_run_stats"); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         num_songs = mpd_stats_get_number_of_songs(stats); |  | ||||||
|         mpd_stats_free(stats); |  | ||||||
|     } |  | ||||||
|     else if (mympd_state.jukeboxMode == 1) { |  | ||||||
|         if (!mpd_send_list_playlist(mpd.conn, mympd_state.jukeboxPlaylist)) { |  | ||||||
|             LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         while ((entity = mpd_recv_entity(mpd.conn)) != NULL) { |  | ||||||
|             num_songs++; |  | ||||||
|             mpd_entity_free(entity); |  | ||||||
|         }     |  | ||||||
|     } |  | ||||||
|     else if (mympd_state.jukeboxMode == 2) { |  | ||||||
|         if (!mpd_search_db_tags(mpd.conn, MPD_TAG_ALBUM)) { |  | ||||||
|             LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         if (!mpd_search_commit(mpd.conn)) { |  | ||||||
|             LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         while ((pair = mpd_recv_pair_tag(mpd.conn, MPD_TAG_ALBUM)) != NULL) { |  | ||||||
|             num_songs++; |  | ||||||
|             mpd_return_pair(mpd.conn, pair); |  | ||||||
|         } |  | ||||||
|         mpd_response_finish(mpd.conn);         |  | ||||||
|     } |  | ||||||
|     num_songs--; |  | ||||||
|     if (mympd_state.jukeboxMode == 1)  |     if (mympd_state.jukeboxMode == 1)  | ||||||
|         addSongs = mympd_state.jukeboxQueueLength - queue_length; |         addSongs = mympd_state.jukeboxQueueLength - queue_length; | ||||||
|     else |     else | ||||||
|         addSongs = 1; |         addSongs = 1; | ||||||
|     if (num_songs > 0) { |      | ||||||
|         for (j = 0; j < addSongs; j++) { |     if (addSongs < 1) | ||||||
|             rand_song = rand() % num_songs; |         return; | ||||||
|             if (mympd_state.jukeboxMode == 1) { |      | ||||||
|                 //add songs |     srand((unsigned int)time(NULL)); | ||||||
|                 if (strcmp(mympd_state.jukeboxPlaylist, "Database") == 0) { |  | ||||||
|                     if (!mpd_send_list_all(mpd.conn, "/")) { |     struct list add_list; | ||||||
|                         LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); |     list_init(&add_list); | ||||||
|                         return; |      | ||||||
|                     } |     if (mympd_state.jukeboxMode == 1) { | ||||||
|                 } |         //add songs | ||||||
|                 else { |         if (strcmp(mympd_state.jukeboxPlaylist, "Database") == 0) { | ||||||
|                     if (!mpd_send_list_playlist(mpd.conn, mympd_state.jukeboxPlaylist)) { |             if (!mpd_send_list_all(mpd.conn, "/")) { | ||||||
|                         LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); |                 LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); | ||||||
|                         return; |                 list_free(&add_list); | ||||||
|                     } |                 return; | ||||||
|                 } |  | ||||||
|                 i = 0; |  | ||||||
|                 while ((entity = mpd_recv_entity(mpd.conn)) != NULL) { |  | ||||||
|                     if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) { |  | ||||||
|                         if (i == rand_song) |  | ||||||
|                             break; |  | ||||||
|                         i++; |  | ||||||
|                     } |  | ||||||
|                     mpd_entity_free(entity); |  | ||||||
|                 } |  | ||||||
|                 mpd_response_finish(mpd.conn); |  | ||||||
|                 song = mpd_entity_get_song(entity);         |  | ||||||
|                 if (song != NULL) { |  | ||||||
|                     printf("Jukebox enabled, adding random song: %d/%d\n", rand_song, num_songs); |  | ||||||
|                     if (!mpd_run_add(mpd.conn, mpd_song_get_uri(song))) { |  | ||||||
|                         LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 mpd_entity_free(entity); |  | ||||||
|             } |  | ||||||
|             else if (mympd_state.jukeboxMode == 2) { |  | ||||||
|                 //add album |  | ||||||
|                 if (!mpd_search_db_tags(mpd.conn, MPD_TAG_ALBUM)) { |  | ||||||
|                     LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|                 if (!mpd_search_commit(mpd.conn)) { |  | ||||||
|                     LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|                 i = 0; |  | ||||||
|                 while ((pair = mpd_recv_pair_tag(mpd.conn, MPD_TAG_ALBUM )) != NULL)  { |  | ||||||
|                     if (i == rand_song) { |  | ||||||
|                         album = strdup(pair->value); |  | ||||||
|                         break; |  | ||||||
|                     } |  | ||||||
|                     i++; |  | ||||||
|                     mpd_return_pair(mpd.conn, pair); |  | ||||||
|                 } |  | ||||||
|                 mpd_return_pair(mpd.conn, pair);             |  | ||||||
|                 mpd_response_finish(mpd.conn); |  | ||||||
|                 printf("Jukebox enabled, adding random album %s: %d/%d\n", album, rand_song, num_songs); |  | ||||||
|                 if (!mpd_send_command(mpd.conn, "searchadd", "Album", album, NULL)) { |  | ||||||
|                     LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|                 mpd_response_finish(mpd.conn);                 |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         mpd_run_play(mpd.conn); |         else { | ||||||
|  |             if (!mpd_send_list_playlist(mpd.conn, mympd_state.jukeboxPlaylist)) { | ||||||
|  |                 LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); | ||||||
|  |                 list_free(&add_list); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         while ((entity = mpd_recv_entity(mpd.conn)) != NULL) { | ||||||
|  |             if (mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) { | ||||||
|  |                 if (randrange(lineno) < addSongs) { | ||||||
|  | 		    if (nkeep < addSongs) { | ||||||
|  | 		        song = mpd_entity_get_song(entity); | ||||||
|  | 		        list_push(&add_list, mpd_song_get_uri(song), lineno); | ||||||
|  | 		        nkeep++; | ||||||
|  |                     } | ||||||
|  |                     else { | ||||||
|  | 		        i = 0; | ||||||
|  | 		        if (addSongs > 1) | ||||||
|  | 		            i = randrange(addSongs); | ||||||
|  |                         if (addSongs == 1) { | ||||||
|  |                             song = mpd_entity_get_song(entity); | ||||||
|  |                             list_replace(&add_list, 0, mpd_song_get_uri(song), lineno); | ||||||
|  |                         } | ||||||
|  |                         else { | ||||||
|  |                             song = mpd_entity_get_song(entity); | ||||||
|  |                             list_replace(&add_list, i, mpd_song_get_uri(song), lineno); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 lineno++; | ||||||
|  |             } | ||||||
|  |             mpd_entity_free(entity); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |     else if (mympd_state.jukeboxMode == 2) { | ||||||
|  |         //add album | ||||||
|  |         if (!mpd_search_db_tags(mpd.conn, MPD_TAG_ALBUM)) { | ||||||
|  |             LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); | ||||||
|  |             list_free(&add_list); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         if (!mpd_search_commit(mpd.conn)) { | ||||||
|  |             LOG_ERROR_AND_RECOVER("mpd_send_list_playlist"); | ||||||
|  |             list_free(&add_list); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         while ((pair = mpd_recv_pair_tag(mpd.conn, MPD_TAG_ALBUM )) != NULL)  { | ||||||
|  |             if (randrange(lineno) < addSongs) { | ||||||
|  | 		if (nkeep < addSongs) { | ||||||
|  |                     list_push(&add_list, strdup(pair->value), lineno); | ||||||
|  |                     nkeep++; | ||||||
|  |                 } | ||||||
|  | 		else { | ||||||
|  | 		    i = 0; | ||||||
|  | 		    if (addSongs > 1) | ||||||
|  | 		        i = randrange(addSongs); | ||||||
|  |                     if (addSongs == 1) { | ||||||
|  |                         list_replace(&add_list, 0, strdup(pair->value), lineno); | ||||||
|  |                     } | ||||||
|  |                     else { | ||||||
|  |                         list_replace(&add_list, i, strdup(pair->value), lineno); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             lineno++; | ||||||
|  |             mpd_return_pair(mpd.conn, pair); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (nkeep < addSongs) { | ||||||
|  |         fprintf(stderr, "Warning: input didn't contain %d entries\n", addSongs); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     list_shuffle(&add_list); | ||||||
|  |  | ||||||
|  |     struct node *current = add_list.list; | ||||||
|  |     while (current != NULL) { | ||||||
|  |         if (mympd_state.jukeboxMode == 1) { | ||||||
|  | 	    printf("Jukebox adding song: %s\n", current->data); | ||||||
|  | 	    if (!mpd_run_add(mpd.conn, current->data)) { | ||||||
|  |                 LOG_ERROR_AND_RECOVER("mpd_run_add"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             printf("Jukebox adding album: %s\n", current->data); | ||||||
|  |             if (!mpd_send_command(mpd.conn, "searchadd", "Album", current->data, NULL)) { | ||||||
|  |                 LOG_ERROR_AND_RECOVER("mpd_send_command"); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             mpd_response_finish(mpd.conn); | ||||||
|  |         } | ||||||
|  |         current = current->next; | ||||||
|  |     } | ||||||
|  |     list_free(&add_list); | ||||||
|  |     mpd_run_play(mpd.conn); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int randrange(int n) { | ||||||
|  |     return rand() / (RAND_MAX / (n + 1) + 1); | ||||||
| } | } | ||||||
|  |  | ||||||
| int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, int *last_song_id, unsigned *queue_version, unsigned *queue_length) { | int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, int *last_song_id, unsigned *queue_version, unsigned *queue_length) { | ||||||
| @@ -1207,7 +1164,7 @@ bool mympd_state_get(char *name, char *value) { | |||||||
|     snprintf(cfgfile, 400, "%s/state/%s", config.varlibdir, name); |     snprintf(cfgfile, 400, "%s/state/%s", config.varlibdir, name); | ||||||
|     FILE *fp = fopen(cfgfile, "r"); |     FILE *fp = fopen(cfgfile, "r"); | ||||||
|     if (fp == NULL) { |     if (fp == NULL) { | ||||||
|         printf("Error opening %s", cfgfile); |         printf("Error opening %s\n", cfgfile); | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|     read = getline(&line, &n, fp); |     read = getline(&line, &n, fp); | ||||||
| @@ -1230,7 +1187,7 @@ bool mympd_state_set(char *name, char *value) { | |||||||
|          |          | ||||||
|     FILE *fp = fopen(tmpfile, "w"); |     FILE *fp = fopen(tmpfile, "w"); | ||||||
|     if (fp == NULL) { |     if (fp == NULL) { | ||||||
|         printf("Error opening %s", tmpfile); |         printf("Error opening %s\n", tmpfile); | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|     fprintf(fp, value); |     fprintf(fp, value); | ||||||
| @@ -1243,6 +1200,7 @@ int mympd_put_settings(char *buffer) { | |||||||
|     struct mpd_status *status; |     struct mpd_status *status; | ||||||
|     char *replaygain = strdup(""); |     char *replaygain = strdup(""); | ||||||
|     int len; |     int len; | ||||||
|  |     int nr = 0; | ||||||
|     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); |     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); | ||||||
|      |      | ||||||
|     status = mpd_run_status(mpd.conn); |     status = mpd_run_status(mpd.conn); | ||||||
| @@ -1265,9 +1223,7 @@ int mympd_put_settings(char *buffer) { | |||||||
|         "mixrampdb: %f, mixrampdelay: %f, mpdhost: %Q, mpdport: %d, passwort_set: %B, " |         "mixrampdb: %f, mixrampdelay: %f, mpdhost: %Q, mpdport: %d, passwort_set: %B, " | ||||||
|         "streamport: %d, coverimage: %Q, stickers: %B, mixramp: %B, smartpls: %B, maxElementsPerPage: %d, " |         "streamport: %d, coverimage: %Q, stickers: %B, mixramp: %B, smartpls: %B, maxElementsPerPage: %d, " | ||||||
|         "replaygain: %Q, notificationWeb: %B, notificationPage: %B, jukeboxMode: %d, jukeboxPlaylist: %Q, jukeboxQueueLength: %d, " |         "replaygain: %Q, notificationWeb: %B, notificationPage: %B, jukeboxMode: %d, jukeboxPlaylist: %Q, jukeboxQueueLength: %d, " | ||||||
|         "tags: { Artist: %B, Album: %B, AlbumArtist: %B, Title: %B, Track: %B, Genre: %B, Date: %B," |         "tags: [",  | ||||||
|         "Composer: %B, Performer: %B }" |  | ||||||
|         "}}",  |  | ||||||
|         mpd_status_get_repeat(status), |         mpd_status_get_repeat(status), | ||||||
|         mpd_status_get_single(status), |         mpd_status_get_single(status), | ||||||
|         mpd_status_get_crossfade(status), |         mpd_status_get_crossfade(status), | ||||||
| @@ -1289,19 +1245,20 @@ int mympd_put_settings(char *buffer) { | |||||||
|         mympd_state.notificationPage, |         mympd_state.notificationPage, | ||||||
|         mympd_state.jukeboxMode, |         mympd_state.jukeboxMode, | ||||||
|         mympd_state.jukeboxPlaylist, |         mympd_state.jukeboxPlaylist, | ||||||
|         mympd_state.jukeboxQueueLength, |         mympd_state.jukeboxQueueLength | ||||||
|         mpd.tag_artist, |  | ||||||
|         mpd.tag_album, |  | ||||||
|         mpd.tag_album_artist, |  | ||||||
|         mpd.tag_title, |  | ||||||
|         mpd.tag_track, |  | ||||||
|         mpd.tag_genre, |  | ||||||
|         mpd.tag_date, |  | ||||||
|         mpd.tag_composer, |  | ||||||
|         mpd.tag_performer |  | ||||||
|     ); |     ); | ||||||
|     mpd_status_free(status); |     mpd_status_free(status); | ||||||
|     free(replaygain); |     free(replaygain); | ||||||
|  |      | ||||||
|  |     struct node *current = mympd_tags.list; | ||||||
|  |     while (current != NULL) { | ||||||
|  |         if (nr ++)  | ||||||
|  |             len += json_printf(&out, ","); | ||||||
|  |         len += json_printf(&out, "%Q", current->data); | ||||||
|  |         current = current->next; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     len += json_printf(&out, "]}}"); | ||||||
|  |  | ||||||
|     if (len > MAX_SIZE) |     if (len > MAX_SIZE) | ||||||
|         printf("Buffer truncated\n"); |         printf("Buffer truncated\n"); | ||||||
| @@ -2071,7 +2028,7 @@ int mympd_smartpls_put(char *buffer, char *playlist) { | |||||||
|     char pl_file[400]; |     char pl_file[400]; | ||||||
|     char *smartpltype; |     char *smartpltype; | ||||||
|     char *p_charbuf1, *p_charbuf2; |     char *p_charbuf1, *p_charbuf2; | ||||||
|     int je, int_buf1, int_buf2; |     int je, int_buf1; | ||||||
|     int len = 0; |     int len = 0; | ||||||
|     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); |     struct json_out out = JSON_OUT_BUF(buffer, MAX_SIZE); | ||||||
|      |      | ||||||
| @@ -2091,13 +2048,12 @@ int mympd_smartpls_put(char *buffer, char *playlist) { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         else if (strcmp(smartpltype, "newest") == 0) { |         else if (strcmp(smartpltype, "newest") == 0) { | ||||||
|             je = json_scanf(content, strlen(content), "{timerange: %d, maxentries: %d}", &int_buf1, &int_buf2); |             je = json_scanf(content, strlen(content), "{timerange: %d}", &int_buf1); | ||||||
|             if (je == 2) { |             if (je == 1) { | ||||||
|                 len = json_printf(&out, "{type: smartpls, data: {playlist: %Q, type: %Q, timerange: %d, maxentries: %d}}", |                 len = json_printf(&out, "{type: smartpls, data: {playlist: %Q, type: %Q, timerange: %d}}", | ||||||
|                     playlist, |                     playlist, | ||||||
|                     smartpltype, |                     smartpltype, | ||||||
|                     int_buf1, |                     int_buf1); | ||||||
|                     int_buf2); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         else if (strcmp(smartpltype, "search") == 0) { |         else if (strcmp(smartpltype, "search") == 0) { | ||||||
| @@ -2128,9 +2084,9 @@ int mympd_smartpls_save(char *smartpltype, char *playlist, char *tag, char *sear | |||||||
|         mympd_smartpls_update(playlist, tag, maxentries); |         mympd_smartpls_update(playlist, tag, maxentries); | ||||||
|     } |     } | ||||||
|     else if (strcmp(smartpltype, "newest") == 0) { |     else if (strcmp(smartpltype, "newest") == 0) { | ||||||
|         json_fprintf(tmp_file, "{type: %Q, timerange: %d, maxentries: %d}", smartpltype, timerange, maxentries); |         json_fprintf(tmp_file, "{type: %Q, timerange: %d}", smartpltype, timerange); | ||||||
|         rename(tmp_file, pl_file); |         rename(tmp_file, pl_file); | ||||||
|         mympd_smartpls_update_newest(playlist, timerange, maxentries); |         mympd_smartpls_update_newest(playlist, timerange); | ||||||
|     } |     } | ||||||
|     else if (strcmp(smartpltype, "search") == 0) { |     else if (strcmp(smartpltype, "search") == 0) { | ||||||
|         json_fprintf(tmp_file, "{type: %Q, tag: %Q, searchstr: %Q}", smartpltype, tag, searchstr); |         json_fprintf(tmp_file, "{type: %Q, tag: %Q, searchstr: %Q}", smartpltype, tag, searchstr); | ||||||
| @@ -2148,7 +2104,7 @@ int mympd_smartpls_update_all() { | |||||||
|     char dirname[400]; |     char dirname[400]; | ||||||
|     int je; |     int je; | ||||||
|     char *p_charbuf1, *p_charbuf2; |     char *p_charbuf1, *p_charbuf2; | ||||||
|     int int_buf1, int_buf2; |     int int_buf1; | ||||||
|      |      | ||||||
|     if (!config.smartpls) |     if (!config.smartpls) | ||||||
|         return 0; |         return 0; | ||||||
| @@ -2173,9 +2129,9 @@ int mympd_smartpls_update_all() { | |||||||
|                     printf("Can't parse file %s\n", filename); |                     printf("Can't parse file %s\n", filename); | ||||||
|             } |             } | ||||||
|             else if (strcmp(smartpltype, "newest") == 0) { |             else if (strcmp(smartpltype, "newest") == 0) { | ||||||
|                 je = json_scanf(content, strlen(content), "{timerange: %d, maxentries: %d}", &int_buf1, &int_buf2); |                 je = json_scanf(content, strlen(content), "{timerange: %d}", &int_buf1); | ||||||
|                 if (je == 2) { |                 if (je == 1) { | ||||||
|                     mympd_smartpls_update_newest(ent->d_name, int_buf1, int_buf2); |                     mympd_smartpls_update_newest(ent->d_name, int_buf1); | ||||||
|                 } |                 } | ||||||
|                 else |                 else | ||||||
|                     printf("Can't parse file %s\n", filename);                 |                     printf("Can't parse file %s\n", filename);                 | ||||||
| @@ -2240,23 +2196,18 @@ int mympd_smartpls_update(char *playlist, char *sticker, int maxentries) { | |||||||
|     char *name; |     char *name; | ||||||
|     char *p_value; |     char *p_value; | ||||||
|     char *crap; |     char *crap; | ||||||
|     char tmpfile[400]; |  | ||||||
|     long value; |     long value; | ||||||
|     long value_max = 0; |     long value_max = 0; | ||||||
|     size_t len = 0; |  | ||||||
|     ssize_t read; |  | ||||||
|     long i = 0; |     long i = 0; | ||||||
|  |  | ||||||
|     if (!mpd_send_sticker_find(mpd.conn, "song", "", sticker)) { |     if (!mpd_send_sticker_find(mpd.conn, "song", "", sticker)) { | ||||||
|         LOG_ERROR_AND_RECOVER("mpd_send_sticker_find"); |         LOG_ERROR_AND_RECOVER("mpd_send_sticker_find"); | ||||||
|         return 1;     |         return 1;     | ||||||
|     } |     } | ||||||
|     snprintf(tmpfile, 400, "%s/tmp/playlist.tmp", config.varlibdir); |  | ||||||
|     FILE *fp = fopen(tmpfile, "w"); |     struct list add_list; | ||||||
|     if (fp == NULL) { |     list_init(&add_list); | ||||||
|         printf("Error opening %s", tmpfile); |  | ||||||
|         return 1; |  | ||||||
|     }     |  | ||||||
|     while ((pair = mpd_recv_pair(mpd.conn)) != NULL) { |     while ((pair = mpd_recv_pair(mpd.conn)) != NULL) { | ||||||
|         if (strcmp(pair->name, "file") == 0) { |         if (strcmp(pair->name, "file") == 0) { | ||||||
|             uri = strdup(pair->value); |             uri = strdup(pair->value); | ||||||
| @@ -2265,111 +2216,60 @@ int mympd_smartpls_update(char *playlist, char *sticker, int maxentries) { | |||||||
|             name = strtok(strdup(pair->value), "="); |             name = strtok(strdup(pair->value), "="); | ||||||
|             p_value = strtok(NULL, "="); |             p_value = strtok(NULL, "="); | ||||||
|             value = strtol(p_value, &crap, 10); |             value = strtol(p_value, &crap, 10); | ||||||
|             if (value > 1)             |             if (value > 1) | ||||||
|                 fprintf(fp, "%s::%ld\n", uri, value); |                 list_push(&add_list, uri, value); | ||||||
|             if (value > value_max) |             if (value > value_max) | ||||||
|                 value_max = value; |                 value_max = value; | ||||||
|         } |         } | ||||||
|         mpd_return_pair(mpd.conn, pair); |         mpd_return_pair(mpd.conn, pair); | ||||||
|     } |     } | ||||||
|     mpd_response_finish(mpd.conn); |     mpd_response_finish(mpd.conn); | ||||||
|     fclose(fp); |     free(uri); | ||||||
|  |  | ||||||
|     mympd_smartpls_clear(playlist); |     mympd_smartpls_clear(playlist); | ||||||
|       |       | ||||||
|     if (value_max > 2) |     if (value_max > 2) | ||||||
|         value_max = value_max / 2; |         value_max = value_max / 2; | ||||||
|     fp = fopen(tmpfile, "r"); |  | ||||||
|     if (fp == NULL) { |     struct node *current = add_list.list; | ||||||
|         printf("Error opening %s", tmpfile); |     while (current != NULL) { | ||||||
|         return 1; |         if (current->value >= value_max) { | ||||||
|     } |             if (!mpd_run_playlist_add(mpd.conn, playlist, current->data)) { | ||||||
|     while ((read = getline(&uri, &len, fp)) != -1) { |                 LOG_ERROR_AND_RECOVER("mpd_run_playlist_add"); | ||||||
|         name = strtok(uri, "::"); |                 list_free(&add_list); | ||||||
|         p_value = strtok(NULL, "::"); |                 return 1;         | ||||||
|         value = strtol(p_value, &crap, 10); |             } | ||||||
|         if (value < value_max) |             i++; | ||||||
|             continue; |             if (i >= maxentries) | ||||||
|         if (!mpd_run_playlist_add(mpd.conn, playlist, name)) { |                 break; | ||||||
|             LOG_ERROR_AND_RECOVER("mpd_run_playlist_add"); |  | ||||||
|             fclose(fp); |  | ||||||
|             free(uri); |  | ||||||
|             unlink(tmpfile); |  | ||||||
|             return 1;         |  | ||||||
|         } |         } | ||||||
|         i++; |         current = current->next; | ||||||
|         if (i >= maxentries) |  | ||||||
|             break; |  | ||||||
|     } |     } | ||||||
|     fclose(fp); |     list_free(&add_list); | ||||||
|     free(uri); |  | ||||||
|     unlink(tmpfile); |  | ||||||
|     printf("Updated %s with %ld songs, minValue: %ld\n", playlist, i, value_max); |     printf("Updated %s with %ld songs, minValue: %ld\n", playlist, i, value_max); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int mympd_smartpls_update_newest(char *playlist, int timerange, int maxentries) { | int mympd_smartpls_update_newest(char *playlist, int timerange) { | ||||||
|     struct mpd_song *song; |     unsigned long value_max = 0; | ||||||
|     char *uri; |     char searchstr[20]; | ||||||
|     char *p_value; |  | ||||||
|     char *name; |  | ||||||
|     char *crap; |  | ||||||
|     char tmpfile[400]; |  | ||||||
|     time_t value; |  | ||||||
|     time_t value_max = 0; |  | ||||||
|     size_t len = 0; |  | ||||||
|     ssize_t read; |  | ||||||
|     long i = 0; |  | ||||||
|      |      | ||||||
|     if (!mpd_send_list_all_meta(mpd.conn, "/")) { |     struct mpd_stats *stats = mpd_run_stats(mpd.conn); | ||||||
|         LOG_ERROR_AND_RECOVER("mpd_send_list_all_meta"); |     if (stats != NULL) { | ||||||
|         return 1;     |         value_max = mpd_stats_get_db_update_time(stats); | ||||||
|  |         mpd_stats_free(stats); | ||||||
|     } |     } | ||||||
|     snprintf(tmpfile, 400, "%s/tmp/playlist.tmp", config.varlibdir); |     else { | ||||||
|     FILE *fp = fopen(tmpfile, "w"); |         LOG_ERROR_AND_RECOVER("mpd_run_stats"); | ||||||
|     if (fp == NULL) { |  | ||||||
|         printf("Error opening %s", tmpfile); |  | ||||||
|         return 1; |         return 1; | ||||||
|     }     |  | ||||||
|     while ((song = mpd_recv_song(mpd.conn)) != NULL) { |  | ||||||
|         value = mpd_song_get_last_modified(song); |  | ||||||
|         if (value > value_max) |  | ||||||
|             value_max = value; |  | ||||||
|         fprintf(fp, "%s::%ld\n", mpd_song_get_uri(song), value); |  | ||||||
|         mpd_song_free(song); |  | ||||||
|     } |     } | ||||||
|     mpd_response_finish(mpd.conn); |  | ||||||
|     fclose(fp); |  | ||||||
|  |  | ||||||
|     mympd_smartpls_clear(playlist); |     mympd_smartpls_clear(playlist); | ||||||
|      |  | ||||||
|     value_max -= timerange; |     value_max -= timerange; | ||||||
|      |     if (value_max > 0) { | ||||||
|     fp = fopen(tmpfile, "r"); |         snprintf(searchstr, 20, "%lu", value_max); | ||||||
|     if (fp == NULL) { |         mympd_search(mpd.buf, searchstr, "modified-since", playlist, 0); | ||||||
|         printf("Error opening %s", tmpfile); |         printf("Updated %s\n", playlist); | ||||||
|         return 1; |  | ||||||
|     } |     } | ||||||
|     while ((read = getline(&uri, &len, fp)) != -1) { |  | ||||||
|         name = strtok(uri, "::"); |  | ||||||
|         p_value = strtok(NULL, "::"); |  | ||||||
|         value = strtol(p_value, &crap, 10); |  | ||||||
|         if (value >= value_max) |  | ||||||
|             continue; |  | ||||||
|         if (!mpd_run_playlist_add(mpd.conn, playlist, name)) { |  | ||||||
|             LOG_ERROR_AND_RECOVER("mpd_run_playlist_add"); |  | ||||||
|             fclose(fp); |  | ||||||
|             unlink(tmpfile); |  | ||||||
|             free(uri); |  | ||||||
|             return 1;         |  | ||||||
|         } |  | ||||||
|         i++; |  | ||||||
|         if (i >= maxentries) |  | ||||||
|             break; |  | ||||||
|     } |  | ||||||
|     fclose(fp); |  | ||||||
|     free(uri); |  | ||||||
|     unlink(tmpfile); |  | ||||||
|     printf("Updated %s with %ld songs, minValue: %ld\n", playlist, i, value_max); |  | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ | |||||||
| #define __MPD_CLIENT_H__ | #define __MPD_CLIENT_H__ | ||||||
|  |  | ||||||
| #include "../dist/src/mongoose/mongoose.h" | #include "../dist/src/mongoose/mongoose.h" | ||||||
|  | #include "list.h" | ||||||
|  |  | ||||||
| #define RETURN_ERROR_AND_RECOVER(X) do { \ | #define RETURN_ERROR_AND_RECOVER(X) do { \ | ||||||
|     printf("MPD X: %s\n", mpd_connection_get_error_message(mpd.conn)); \ |     printf("MPD X: %s\n", mpd_connection_get_error_message(mpd.conn)); \ | ||||||
| @@ -137,17 +138,11 @@ struct t_mpd { | |||||||
|     const unsigned* protocol; |     const unsigned* protocol; | ||||||
|     // Supported tags |     // Supported tags | ||||||
|     bool feat_sticker; |     bool feat_sticker; | ||||||
|     bool tag_artist; |  | ||||||
|     bool tag_album; |  | ||||||
|     bool tag_album_artist; |  | ||||||
|     bool tag_title; |  | ||||||
|     bool tag_track; |  | ||||||
|     bool tag_genre; |  | ||||||
|     bool tag_date; |  | ||||||
|     bool tag_composer; |  | ||||||
|     bool tag_performer; |  | ||||||
| } mpd; | } mpd; | ||||||
|  |  | ||||||
|  | struct list mpd_tags; | ||||||
|  | struct list mympd_tags; | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
|     long mpdport; |     long mpdport; | ||||||
|     const char* mpdhost; |     const char* mpdhost; | ||||||
| @@ -190,6 +185,7 @@ static int is_websocket(const struct mg_connection *nc) { | |||||||
|     return nc->flags & MG_F_IS_WEBSOCKET; |     return nc->flags & MG_F_IS_WEBSOCKET; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int randrange(int n); | ||||||
| void mympd_idle(struct mg_mgr *sm, int timeout); | void mympd_idle(struct mg_mgr *sm, int timeout); | ||||||
| void mympd_parse_idle(struct mg_mgr *s, int idle_bitmask); | void mympd_parse_idle(struct mg_mgr *s, int idle_bitmask); | ||||||
| void callback_mympd(struct mg_connection *nc, const struct mg_str msg); | void callback_mympd(struct mg_connection *nc, const struct mg_str msg); | ||||||
| @@ -208,7 +204,7 @@ int mympd_smartpls_put(char *buffer, char *playlist); | |||||||
| int mympd_smartpls_update_all(); | int mympd_smartpls_update_all(); | ||||||
| int mympd_smartpls_clear(char *playlist); | int mympd_smartpls_clear(char *playlist); | ||||||
| int mympd_smartpls_update(char *sticker, char *playlist, int maxentries); | int mympd_smartpls_update(char *sticker, char *playlist, int maxentries); | ||||||
| int mympd_smartpls_update_newest(char *playlist, int timerange, int maxentries); | int mympd_smartpls_update_newest(char *playlist, int timerange); | ||||||
| int mympd_smartpls_update_search(char *playlist, char *tag, char *searchstr); | int mympd_smartpls_update_search(char *playlist, char *tag, char *searchstr); | ||||||
| int mympd_get_updatedb_state(char *buffer); | int mympd_get_updatedb_state(char *buffer); | ||||||
| int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, int *last_song_id, unsigned *queue_version, unsigned *queue_length); | int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, int *last_song_id, unsigned *queue_version, unsigned *queue_length); | ||||||
|   | |||||||
							
								
								
									
										71
									
								
								src/mympd.c
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								src/mympd.c
									
									
									
									
									
								
							| @@ -183,14 +183,18 @@ static int inihandler(void* user, const char* section, const char* name, const c | |||||||
| void read_statefiles() { | void read_statefiles() { | ||||||
|     char *crap; |     char *crap; | ||||||
|     char value[400]; |     char value[400]; | ||||||
|  |  | ||||||
|  |     printf("Reading states\n"); | ||||||
|     if (mympd_state_get("notificationWeb", value)) { |     if (mympd_state_get("notificationWeb", value)) { | ||||||
|         if (strcmp(value, "true") == 0) |         if (strcmp(value, "true") == 0) | ||||||
|             mympd_state.notificationWeb = true; |             mympd_state.notificationWeb = true; | ||||||
|         else |         else | ||||||
|             mympd_state.notificationWeb = false; |             mympd_state.notificationWeb = false; | ||||||
|     } |     } | ||||||
|     else |     else { | ||||||
|         mympd_state.notificationWeb = false; |         mympd_state.notificationWeb = false; | ||||||
|  |         mympd_state_set("notificationWeb", "false"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (mympd_state_get("notificationPage", value)) { |     if (mympd_state_get("notificationPage", value)) { | ||||||
|         if (strcmp(value, "true") == 0) |         if (strcmp(value, "true") == 0) | ||||||
| @@ -198,24 +202,44 @@ void read_statefiles() { | |||||||
|         else |         else | ||||||
|             mympd_state.notificationPage = false; |             mympd_state.notificationPage = false; | ||||||
|     } |     } | ||||||
|     else |     else { | ||||||
|         mympd_state.notificationPage = true; |         mympd_state.notificationPage = true; | ||||||
|              |         mympd_state_set("notificationPage", "true"); | ||||||
|  |     } | ||||||
|      |      | ||||||
|     if (mympd_state_get("jukeboxMode", value)) |     if (mympd_state_get("jukeboxMode", value)) | ||||||
|         mympd_state.jukeboxMode = strtol(value, &crap, 10); |         mympd_state.jukeboxMode = strtol(value, &crap, 10); | ||||||
|     else |     else { | ||||||
|         mympd_state.jukeboxMode = 0; |         mympd_state.jukeboxMode = 0; | ||||||
|  |         mympd_state_set("jukeboxMode", "0"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (mympd_state_get("jukeboxPlaylist", value)) |     if (mympd_state_get("jukeboxPlaylist", value)) | ||||||
|         mympd_state.jukeboxPlaylist = strdup(value); |         mympd_state.jukeboxPlaylist = strdup(value); | ||||||
|     else |     else { | ||||||
|         mympd_state.jukeboxPlaylist = "Database"; |         mympd_state.jukeboxPlaylist = "Database"; | ||||||
|  |         mympd_state_set("jukeboxPlaylist", "Database"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (mympd_state_get("jukeboxQueueLength", value)) |     if (mympd_state_get("jukeboxQueueLength", value)) | ||||||
|         mympd_state.jukeboxQueueLength = strtol(value, &crap, 10); |         mympd_state.jukeboxQueueLength = strtol(value, &crap, 10); | ||||||
|     else |     else { | ||||||
|         mympd_state.jukeboxQueueLength = 1; |         mympd_state.jukeboxQueueLength = 1; | ||||||
|  |         mympd_state_set("jukeboxQueueLength", "1"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool testdir(char *name, char *dirname) { | ||||||
|  |     DIR* dir = opendir(dirname); | ||||||
|  |     if (dir) { | ||||||
|  |         closedir(dir); | ||||||
|  |         printf("%s: \"%s\"\n", name, dirname); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |         printf("%s: \"%s\" don't exists\n", name, dirname); | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| int main(int argc, char **argv) { | int main(int argc, char **argv) { | ||||||
| @@ -224,6 +248,7 @@ int main(int argc, char **argv) { | |||||||
|     struct mg_connection *nc_http; |     struct mg_connection *nc_http; | ||||||
|     struct mg_bind_opts bind_opts; |     struct mg_bind_opts bind_opts; | ||||||
|     const char *err; |     const char *err; | ||||||
|  |     char testdirname[400]; | ||||||
|      |      | ||||||
|     //defaults |     //defaults | ||||||
|     config.mpdhost = "127.0.0.1"; |     config.mpdhost = "127.0.0.1"; | ||||||
| @@ -268,18 +293,6 @@ int main(int argc, char **argv) { | |||||||
|  |  | ||||||
|     printf("Starting myMPD %s\n", MYMPD_VERSION); |     printf("Starting myMPD %s\n", MYMPD_VERSION); | ||||||
|  |  | ||||||
|     DIR* dir = opendir(SRC_PATH); |  | ||||||
|     if (dir) { |  | ||||||
|         printf("Document root: %s\n", SRC_PATH); |  | ||||||
|         closedir(dir); |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|         printf("Document root \"%s\" don't exists\n", SRC_PATH); |  | ||||||
|         return EXIT_FAILURE; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     read_statefiles(); |  | ||||||
|  |  | ||||||
|     signal(SIGTERM, signal_handler); |     signal(SIGTERM, signal_handler); | ||||||
|     signal(SIGINT, signal_handler); |     signal(SIGINT, signal_handler); | ||||||
|     setvbuf(stdout, NULL, _IOLBF, 0); |     setvbuf(stdout, NULL, _IOLBF, 0); | ||||||
| @@ -341,6 +354,26 @@ int main(int argc, char **argv) { | |||||||
|         mg_mgr_free(&mgr); |         mg_mgr_free(&mgr); | ||||||
|         return EXIT_FAILURE; |         return EXIT_FAILURE; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     if (!testdir("Document root", SRC_PATH))  | ||||||
|  |         return EXIT_FAILURE; | ||||||
|  |  | ||||||
|  |     snprintf(testdirname, 400, "%s/tmp", config.varlibdir); | ||||||
|  |     if (!testdir("Temp dir", testdirname))  | ||||||
|  |         return EXIT_FAILURE; | ||||||
|  |  | ||||||
|  |     snprintf(testdirname, 400, "%s/smartpls", config.varlibdir); | ||||||
|  |     if (!testdir("Smartpls dir", testdirname))  | ||||||
|  |         return EXIT_FAILURE; | ||||||
|  |  | ||||||
|  |     snprintf(testdirname, 400, "%s/state", config.varlibdir); | ||||||
|  |     if (!testdir("State dir", testdirname))  | ||||||
|  |         return EXIT_FAILURE; | ||||||
|  |  | ||||||
|  |     read_statefiles(); | ||||||
|  |  | ||||||
|  |     list_init(&mpd_tags); | ||||||
|  |     list_init(&mympd_tags); | ||||||
|      |      | ||||||
|     if (config.ssl == true) |     if (config.ssl == true) | ||||||
|         mg_set_protocol_http_websocket(nc_http); |         mg_set_protocol_http_websocket(nc_http); | ||||||
| @@ -358,6 +391,8 @@ int main(int argc, char **argv) { | |||||||
|         mympd_idle(&mgr, 0); |         mympd_idle(&mgr, 0); | ||||||
|     } |     } | ||||||
|     mg_mgr_free(&mgr); |     mg_mgr_free(&mgr); | ||||||
|  |     list_free(&mpd_tags); | ||||||
|  |     list_free(&mympd_tags); | ||||||
|     mympd_disconnect(); |     mympd_disconnect(); | ||||||
|     return EXIT_SUCCESS; |     return EXIT_SUCCESS; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jürgen Mang
					Jürgen Mang