rompr www
This commit is contained in:
parent
d2e02277d2
commit
467a426bf5
41
www/jukebox/404.php
Normal file
41
www/jukebox/404.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
include('includes/vars.php');
|
||||
include("includes/functions.php");
|
||||
$base_url = get_base_url();
|
||||
$request = $_SERVER['REQUEST_URI'];
|
||||
logger::log('REDIRECT','Uri is',$_SERVER['REQUEST_URI']);
|
||||
if (preg_match('#prefs/userstreams/.*\.jpg#', $request)) {
|
||||
$redirect = $base_url.'/newimages/broadcast.svg';
|
||||
logger::log("404", "Request for missing userstream image. Redirecting to ".$redirect);
|
||||
header("HTTP/1.1 307 Temporary Redirect");
|
||||
header("Location: ".$redirect);
|
||||
} else if (preg_match('#prefs/podcasts/.*\.jpg#', $request) ||
|
||||
preg_match('#prefs/podcasts/.*\.png#', $request)) {
|
||||
$redirect = $base_url.'/newimages/podcast-logo.svg';
|
||||
logger::log("404", "Request for missing podcast image. Redirecting to ".$redirect);
|
||||
header("HTTP/1.1 307 Temporary Redirect");
|
||||
header("Location: ".$redirect);
|
||||
} else {
|
||||
header("HTTP/1.1 404 Not Found");
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="css/layout-january.css" />
|
||||
<link rel="stylesheet" type="text/css" href="themes/Darkness.css" />
|
||||
<title>Badgers!</title>
|
||||
</head>
|
||||
<body>
|
||||
<br><br><br>
|
||||
<table align="center"><tr><td><img src="newimages/favicon-196.png"></td></tr></table>
|
||||
<h2 align="center">404 Error!</h2>
|
||||
<br><br>
|
||||
<h2 align="center">It's all gone horribly wrong</h2>
|
||||
<br><br>
|
||||
<?php
|
||||
print '<h3 align="center">The document "'.$request."" doesn't exist. Are you sure you know what you're doing?</h3>";
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
}
|
||||
?>
|
22
www/jukebox/INSTALL.txt
Normal file
22
www/jukebox/INSTALL.txt
Normal file
@ -0,0 +1,22 @@
|
||||
==================
|
||||
= Installing RompR
|
||||
==================
|
||||
Please read the installation instructions here:
|
||||
|
||||
http://sourceforge.net/p/rompr/wiki/Installation/
|
||||
|
||||
MacOS X Users
|
||||
=============
|
||||
|
||||
Please read the instructions here:
|
||||
|
||||
http://sourceforge.net/p/rompr/wiki/Installation%20on%20Mac%20OS%20X/
|
||||
|
||||
Windows Users
|
||||
=============
|
||||
|
||||
First, install a better operating system, then read this file again :)
|
||||
Actually, it may well be possible to get this to run on Windows, if mpd or mopidy can be got
|
||||
to work then there's probably a LAMP stack for Windows that will run apache and php
|
||||
OK. But I don't intend to go buy a Windows computer just to find out.
|
||||
|
23
www/jukebox/LICENSE.txt
Normal file
23
www/jukebox/LICENSE.txt
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
# (C) Fat German Productions/Mark Greenwood 2017
|
||||
|
||||
SEE includes/license.html
|
||||
|
||||
CREDITS
|
||||
=======
|
||||
|
||||
This program makes use of lots of other stuff which are all released
|
||||
under their own licenses, just to make it complicated.
|
||||
|
||||
The original inspiration came from phpMP, and the original core of this app was lifted
|
||||
directly from there. It's grown quite a lot since then.
|
||||
|
||||
jquery (http://jquery.com) and the jquery UI framework (http://jqueryui.com)
|
||||
are probably released under the GPL or something. I dunno, their websites aren't
|
||||
very clear on that point.
|
||||
|
||||
The md5 hashing algorithm code was taken from http://pajhome.org.uk/crypt/md5
|
||||
and is released under a BSD license
|
||||
|
||||
The jquery form plugin comes from http://malsup.com/jquery/form/
|
||||
and also has two licenses.
|
23
www/jukebox/README.md
Normal file
23
www/jukebox/README.md
Normal file
@ -0,0 +1,23 @@
|
||||
# RompЯ
|
||||
This is a browser-based client for Mopidy and MPD, which are both music players.
|
||||
|
||||
You can use RompЯ to control a music player on another device or on your computer. Because it runs in a web browser you can run it ony any device - your laptop,tablet, or phone can all be used to control your music player.
|
||||
It has a rich and beautiful interface which is intended to sort your music, manage radio stations, browse and subscribe to podcasts.
|
||||
When used with Mopidy you can listen to Spotify and make use of RompЯ's incredible music discovery features which will help to introduce you to new music.
|
||||
|
||||
## Installation from GitHub
|
||||
Please see the [New Project Homepage](https://fatg3erman.github.io/RompR/)
|
||||
|
||||
![](docs/images/rompr-1.png)
|
||||
|
||||
![](docs/images/rompr-on-a-phone.png)
|
||||
|
||||
### What people are saying about RompЯ
|
||||
|
||||
* “Best interface to mpd / mopidy ever. A real must!”
|
||||
* “Best browser based frontend to mpd I've ever seen!! Thank you!”
|
||||
* “Rompr is a wonderful web based interface client to mpd.”
|
||||
* “Great Project! I use it everyday already. I hope for VK-support soon. Thanks!”
|
||||
* “I tired now a fiew clients to control my mopidy server running on Raspberry. rompr is far the best one, easy to install, very fast, good design and useful features.”
|
||||
* “This application is amazing and easy to setup. I love it.”
|
||||
* “Wow! Great stuff! I was searching for something like that for months!”
|
13
www/jukebox/README_ru.md
Normal file
13
www/jukebox/README_ru.md
Normal file
@ -0,0 +1,13 @@
|
||||
# RompЯ
|
||||
Это браузерный клиент для музыкальных проигрывателей Mopidy и MPD.
|
||||
|
||||
RompЯ можно использовать для управления музыкальным проигрывателем на удалённом или локальном компьютере. Поскольку он работает в веб-браузере, вы можете запускать его на любом устройстве - ноутбуке, планшете или телефоне для управления вашим музыкальным проигрывателем..
|
||||
Он имеет богатый и красивый интерфейс, который предназначен для сортировки музыки, управления радиостанциями, просмотра и подписки на подкасты.
|
||||
При использовании с Mopidy вы можете слушать Spotify, которые помогут вам познакомиться с новой музыкой.
|
||||
|
||||
## Установка с GitHub
|
||||
Инструкция [Новая Страница проекта](https://fatg3erman.github.io/RompR/)
|
||||
|
||||
![](docs/images/rompr-1.png)
|
||||
|
||||
![](docs/images/rompr-on-a-phone.png)
|
BIN
www/jukebox/REC/REC.png
Normal file
BIN
www/jukebox/REC/REC.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
450
www/jukebox/REC/bootstrap.css
vendored
Normal file
450
www/jukebox/REC/bootstrap.css
vendored
Normal file
@ -0,0 +1,450 @@
|
||||
/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */
|
||||
|
||||
/* Document
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Correct the line height in all browsers.
|
||||
* 2. Prevent adjustments of font size after orientation changes in
|
||||
* IE on Windows Phone and in iOS.
|
||||
*/
|
||||
|
||||
html {
|
||||
line-height: 1.15; /* 1 */
|
||||
-ms-text-size-adjust: 100%; /* 2 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
|
||||
/* Sections
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove the margin in all browsers (opinionated).
|
||||
margin: 0;
|
||||
*/
|
||||
|
||||
body {
|
||||
margin-left:auto;
|
||||
margin-right:auto;
|
||||
width:98%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 9-.
|
||||
*/
|
||||
|
||||
article,
|
||||
aside,
|
||||
footer,
|
||||
header,
|
||||
nav,
|
||||
section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the font size and margin on `h1` elements within `section` and
|
||||
* `article` contexts in Chrome, Firefox, and Safari.
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
/* Grouping content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 9-.
|
||||
* 1. Add the correct display in IE.
|
||||
*/
|
||||
|
||||
figcaption,
|
||||
figure,
|
||||
main { /* 1 */
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct margin in IE 8.
|
||||
*/
|
||||
|
||||
figure {
|
||||
margin: 1em 40px;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in Firefox.
|
||||
* 2. Show the overflow in Edge and IE.
|
||||
*/
|
||||
|
||||
hr {
|
||||
box-sizing: content-box; /* 1 */
|
||||
height: 0; /* 1 */
|
||||
overflow: visible; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
pre {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/* Text-level semantics
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Remove the gray background on active links in IE 10.
|
||||
* 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
|
||||
*/
|
||||
|
||||
a {
|
||||
background-color: transparent; /* 1 */
|
||||
-webkit-text-decoration-skip: objects; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Remove the bottom border in Chrome 57- and Firefox 39-.
|
||||
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
|
||||
*/
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: none; /* 1 */
|
||||
text-decoration: underline; /* 2 */
|
||||
text-decoration: underline dotted; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent the duplicate application of `bolder` by the next rule in Safari 6.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font weight in Chrome, Edge, and Safari.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||
* 2. Correct the odd `em` font sizing in all browsers.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: monospace, monospace; /* 1 */
|
||||
font-size: 1em; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font style in Android 4.3-.
|
||||
*/
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct background and color in IE 9-.
|
||||
*/
|
||||
|
||||
mark {
|
||||
background-color: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent `sub` and `sup` elements from affecting the line height in
|
||||
* all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
/* Embedded content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 9-.
|
||||
*/
|
||||
|
||||
audio,
|
||||
video {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct display in iOS 4-7.
|
||||
*/
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the border on images inside links in IE 10-.
|
||||
*/
|
||||
|
||||
img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the overflow in IE.
|
||||
*/
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Forms
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Change the font styles in all browsers (opinionated).
|
||||
* 2. Remove the margin in Firefox and Safari.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font-family: sans-serif; /* 1 */
|
||||
font-size: 100%; /* 1 */
|
||||
line-height: 1.15; /* 1 */
|
||||
margin: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the overflow in IE.
|
||||
* 1. Show the overflow in Edge.
|
||||
*/
|
||||
|
||||
button,
|
||||
input { /* 1 */
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inheritance of text transform in Edge, Firefox, and IE.
|
||||
* 1. Remove the inheritance of text transform in Firefox.
|
||||
*/
|
||||
|
||||
button,
|
||||
select { /* 1 */
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
|
||||
* controls in Android 4.
|
||||
* 2. Correct the inability to style clickable types in iOS and Safari.
|
||||
*/
|
||||
|
||||
button,
|
||||
html [type="button"], /* 1 */
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inner border and padding in Firefox.
|
||||
*/
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the focus styles unset by the previous rule.
|
||||
*/
|
||||
|
||||
button:-moz-focusring,
|
||||
[type="button"]:-moz-focusring,
|
||||
[type="reset"]:-moz-focusring,
|
||||
[type="submit"]:-moz-focusring {
|
||||
outline: 1px dotted ButtonText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the padding in Firefox.
|
||||
*/
|
||||
|
||||
fieldset {
|
||||
padding: 0.35em 0.75em 0.625em;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the text wrapping in Edge and IE.
|
||||
* 2. Correct the color inheritance from `fieldset` elements in IE.
|
||||
* 3. Remove the padding so developers are not caught out when they zero out
|
||||
* `fieldset` elements in all browsers.
|
||||
*/
|
||||
|
||||
legend {
|
||||
box-sizing: border-box; /* 1 */
|
||||
color: inherit; /* 2 */
|
||||
display: table; /* 1 */
|
||||
max-width: 100%; /* 1 */
|
||||
padding: 0; /* 3 */
|
||||
white-space: normal; /* 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Add the correct display in IE 9-.
|
||||
* 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
|
||||
*/
|
||||
|
||||
progress {
|
||||
display: inline-block; /* 1 */
|
||||
vertical-align: baseline; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the default vertical scrollbar in IE.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Add the correct box sizing in IE 10-.
|
||||
* 2. Remove the padding in IE 10-.
|
||||
*/
|
||||
|
||||
[type="checkbox"],
|
||||
[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct the cursor style of increment and decrement buttons in Chrome.
|
||||
*/
|
||||
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the odd appearance in Chrome and Safari.
|
||||
* 2. Correct the outline style in Safari.
|
||||
*/
|
||||
|
||||
[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
outline-offset: -2px; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
|
||||
*/
|
||||
|
||||
[type="search"]::-webkit-search-cancel-button,
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct the inability to style clickable types in iOS and Safari.
|
||||
* 2. Change font properties to `inherit` in Safari.
|
||||
*/
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button; /* 1 */
|
||||
font: inherit; /* 2 */
|
||||
}
|
||||
|
||||
/* Interactive
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Add the correct display in IE 9-.
|
||||
* 1. Add the correct display in Edge, IE, and Firefox.
|
||||
*/
|
||||
|
||||
details, /* 1 */
|
||||
menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the correct display in all browsers.
|
||||
*/
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/* Scripting
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 9-.
|
||||
*/
|
||||
|
||||
canvas {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the correct display in IE.
|
||||
*/
|
||||
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hidden
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Add the correct display in IE 10-.
|
||||
*/
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
BIN
www/jukebox/REC/fond.jpg
Normal file
BIN
www/jukebox/REC/fond.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 382 KiB |
134
www/jukebox/REC/youtube-dl.php
Normal file
134
www/jukebox/REC/youtube-dl.php
Normal file
@ -0,0 +1,134 @@
|
||||
<?php
|
||||
/*
|
||||
* THIS CODE IS RELATED TO zen/_CopyLaRadio shell's
|
||||
DONE!!!? WRITE THAT CODE IN infobar2.js : arrount line 158 before "return lines;"
|
||||
// ZEEBOX HACK ZONE
|
||||
var host = window.location.hostname;
|
||||
var reclink = 'http://' + host + ':10010/_CopyLaRadio/youtube-dl.php?q=REC&artist=' + escape(encodeURIComponent(npinfo.Artist)) + '&title=' + escape(encodeURIComponent(npinfo.Title)) + '&radio='+ escape(encodeURIComponent(npinfo.Album)) +'&maxResults=1';
|
||||
var zcopylink = ' <a id="REC" title="Enregistrer sur Youtube" href="#" onclick=\'javascript:window.open("'+ reclink +'","REC","menubar=no, scrollbars=no, top=10, left=10, width=320, height=400");return false;\'>[REC]</a>';
|
||||
zcopylink += ' <a title="RECHERCHE LIBRE" href="'+ reclink +'" target="youtube">*</a>';
|
||||
lines[0].text += zcopylink;
|
||||
// ZEEBOX HACK ZONE
|
||||
*/
|
||||
// RUN CLI if($argc>1) parse_str(implode('&',array_slice($argv, 1)), $_REQUEST);
|
||||
$search=$radio=$artist=$title=$lnk=$lnkform=$cmd=$len="";
|
||||
$search = trim(urldecode($_REQUEST['q']));
|
||||
|
||||
$radio = urldecode($_REQUEST['radio']);
|
||||
$artist = urldecode($_REQUEST['artist']);
|
||||
$title = urldecode($_REQUEST['title']);
|
||||
$lnk = trim(urldecode($_REQUEST['lnk']));
|
||||
$cmd="$radio|$artist|$title";
|
||||
$len=strlen($artist.$title);
|
||||
|
||||
//$result='<a href="#null" onclick="javascript:window.close();"><img src="./REC.png"></a><br>';
|
||||
$result='<a href="" target="copylaradio"><img src="./REC.png"></a><br>';
|
||||
if( $radio == "" ) { $radio = "CopyLaRadio"; }
|
||||
if( $radio == "Nova zz" ) {
|
||||
$artist = "undefined";
|
||||
$title = "undefined";
|
||||
}
|
||||
// Write request for copy.sh triggering
|
||||
if( $search == "REC" ) {
|
||||
|
||||
$result.='<h2>♫ '.$radio.' ♫</h2>';
|
||||
// LINK RECEIVED
|
||||
if ($lnk) {
|
||||
$artist="";
|
||||
// Not making double request
|
||||
if( ! exec('grep '.escapeshellarg($lnk).' /tmp/ytdl.list') ) {
|
||||
// file_put_contents("/tmp/ytdl.list","CopyLibre||$lnk\n", FILE_APPEND);
|
||||
// instead of using a relay daemon to monitor a /tmp shared file, we are going to send sbot message to make it. #zenyta SSB message.
|
||||
shell_exec('/var/www/loveland/_CopyLaRadio/sbotc_zenyta.sh '. $lnk);
|
||||
}
|
||||
$result.='<p><a href="'.$lnk.'" target="check">LIEN: '.$lnk.'</a></p>';
|
||||
|
||||
|
||||
// TRACK COPY (not for undefined or local file)
|
||||
} else if ($radio && $artist != $title && $artist != "undefined" && $title != "undefined" && strlen(explode(".", $title)[1]) != 3 && explode(".", $title)[1] != "opus" ) {
|
||||
// Not making double request
|
||||
if( ! exec('grep '.escapeshellarg($cmd).' /tmp/ytdl.list') ) {
|
||||
// shell_exec('/home/pi/G1sms+/_CopyLaRadio/parle.sh "Enregistrement ajouté."');
|
||||
|
||||
shell_exec('/var/www/loveland/_CopyLaRadio/artist_song_to_sbotc_zenyta.sh "'. $artist . '" "' . $title .'"');
|
||||
|
||||
} else {
|
||||
shell_exec('/var/www/loveland/_CopyLaRadio/parle.sh "Copie déjà lancée"');
|
||||
}
|
||||
$result.='<a style="color:#FFFFFF" href="https://www.youtube.com/results?search_query='.urlencode($artist).'%20'.urlencode($title).'" target="check">
|
||||
<h4>'.$artist.' / '.$title.'</h4>
|
||||
</a>';
|
||||
|
||||
// RADIO EXTERNAL TRACK SCRAPERs ....
|
||||
} else if($radio != "" && $artist == "undefined" && $title == "undefined" ){
|
||||
shell_exec('/var/www/loveland/_CopyLaRadio/parle.sh "Recherche externe pour '.$radio.'"');
|
||||
file_put_contents("/tmp/youtube-dl.log", "/home/pi/G1sms+/_CopyLaRadio/libradio/".escapeshellcmd($radio).".php".PHP_EOL, FILE_APPEND);
|
||||
if ( file_exists("/home/pi/G1sms+/_CopyLaRadio/libradio/".escapeshellcmd($radio).".php") ) {
|
||||
file_put_contents("/tmp/ytdl.list","$radio||".PHP_EOL, FILE_APPEND);
|
||||
} else {
|
||||
shell_exec('/var/www/loveland/_CopyLaRadio/parle.sh "Aucun module"');
|
||||
}
|
||||
|
||||
} else {
|
||||
shell_exec('/var/www/loveland/_CopyLaRadio/parle.sh "Identification imprécise. Podcast? Fichier local?"');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$ytform = '<form action="./youtube-dl.php" method="GET">
|
||||
<div>
|
||||
<h3>ARTISTE: <input type="search" id="artist" name="artist" size="17" placeholder="Indiquez un artiste" value="'.$artist.'"></h3>
|
||||
<h3>TITRE: <input type="search" id="title" name="title" size="20" placeholder="Titre de la chanson" value="'.$title.'"></h3>
|
||||
</div>
|
||||
<input type="hidden" id="radio" name="radio" value="'.$radio.'">
|
||||
<input type="hidden" id="q" name="q" value="REC">
|
||||
<br>
|
||||
<input type="submit" value="♫ Copie Youtube ♫">
|
||||
</form>
|
||||
';
|
||||
|
||||
$lnkform.='<form action="./youtube-dl.php" method="GET">
|
||||
<a href="https://youtube.com" target="search"><img src="./youtube.png"></a>
|
||||
<p><h1>youtube-dl</h1>
|
||||
<a style="color:#FFFFFF" href="https://ytdl-org.github.io/youtube-dl/supportedsites.html" target="_blank">- Sites compatibles -</a>
|
||||
<input type="search" id="lnk" name="lnk" placeholder="Inscrivez le lien à copier" value="" size="40">
|
||||
<input type="hidden" id="q" name="q" value="REC">
|
||||
</p>
|
||||
<div>
|
||||
<input type="submit" value="Copie du Lien #zenyta">
|
||||
</div>
|
||||
</form>';
|
||||
|
||||
?>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="fred" >
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" >
|
||||
<title><?php echo $search;?> - Recherche YouTube & Copie privée</title>
|
||||
<link href="./bootstrap.css" rel="stylesheet">
|
||||
</head>
|
||||
<body style='background: url("./fond.jpg") no-repeat scroll center center / cover rgb(0, 0, 0); color:#FFFFFF;'>
|
||||
<section class="content-section text-center">
|
||||
<div class="container-fluid">
|
||||
<div class="container" id="result" >
|
||||
<div class="col-lg-8 col-lg-offset-2 page-scroll">
|
||||
<ul>
|
||||
<?php echo $result; ?>
|
||||
<hr>
|
||||
</ul>
|
||||
<ul>
|
||||
<?php echo $ytform; ?>
|
||||
<hr>
|
||||
<?php echo $lnkform; ?>
|
||||
<hr>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
BIN
www/jukebox/REC/youtube.png
Normal file
BIN
www/jukebox/REC/youtube.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
9
www/jukebox/_header
Normal file
9
www/jukebox/_header
Normal file
@ -0,0 +1,9 @@
|
||||
## Pages On This website
|
||||
|
||||
[Home](https://fatg3erman.github.io/RompR/)
|
||||
|
||||
[Recommended Linux Installation - with Nginx](https://fatg3erman.github.io/RompR/Recommended-Installation-on-Linux)
|
||||
|
||||
[Alternative Linux Installation - with Apache](https://fatg3erman.github.io/RompR/Installation-on-Linux-Alternative-Method)
|
||||
|
||||
[Troubleshooting](https://fatg3erman.github.io/RompR/Troubleshooting)
|
266
www/jukebox/albumart.php
Normal file
266
www/jukebox/albumart.php
Normal file
@ -0,0 +1,266 @@
|
||||
<?php
|
||||
define('ROMPR_IS_LOADING', true);
|
||||
require_once ("includes/vars.php");
|
||||
require_once ("includes/functions.php");
|
||||
require_once ("international.php");
|
||||
require_once ('utils/imagefunctions.php');
|
||||
require_once ("backends/sql/backend.php");
|
||||
require_once ("player/".$prefs['player_backend']."/player.php");
|
||||
$only_plugins_on_menu = false;
|
||||
$skin = "desktop";
|
||||
set_version_string();
|
||||
?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<title>RompЯ Album Art</title>
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<?php
|
||||
print '<script type="application/json" name="translations">'."\n".json_encode($translations)."\n</script>\n";
|
||||
print '<script type="application/json" name="prefs">'."\n".json_encode($prefs)."\n</script>\n";
|
||||
print '<link rel="stylesheet" type="text/css" href="css/layout-january.css?version=?'.ROMPR_VERSION.'" />'."\n";
|
||||
print '<link rel="stylesheet" type="text/css" href="skins/desktop/skin.css?version=='.ROMPR_VERSION.'" />'."\n";
|
||||
print '<link rel="stylesheet" type="text/css" href="css/albumart.css?version=?'.ROMPR_VERSION.'" />'."\n";
|
||||
?>
|
||||
<link rel="stylesheet" id="theme" type="text/css" />
|
||||
<link type="text/css" href="css/jquery.mCustomScrollbar.css" rel="stylesheet" />
|
||||
<?php
|
||||
$scripts = array(
|
||||
"jquery/jquery-3.3.1.min.js",
|
||||
"jquery/jquery-migrate-3.0.1.js",
|
||||
"ui/functions.js",
|
||||
"ui/prefs.js",
|
||||
"ui/language.js",
|
||||
"jquery/jquery-ui.min-19.1.18.js",
|
||||
"jquery/jquery.mCustomScrollbar.concat.min-3.1.5.js",
|
||||
"includes/globals.js",
|
||||
"ui/uifunctions.js",
|
||||
"ui/metahandlers.js",
|
||||
"ui/widgets.js",
|
||||
"ui/debug.js",
|
||||
"ui/coverscraper.js",
|
||||
"ui/albumart.js"
|
||||
);
|
||||
foreach ($scripts as $i) {
|
||||
logger::mark("INIT", "Loading ".$i);
|
||||
print '<script type="text/javascript" src="'.$i.'?version='.ROMPR_VERSION.'"></script>'."\n";
|
||||
}
|
||||
include ("includes/globals.php");
|
||||
?>
|
||||
</head>
|
||||
<body class="desktop">
|
||||
<div id="pset" class="invisible"></div>
|
||||
<div id="pmaxset" class="invisible"></div>
|
||||
<div id="pbgset" class="invisible"></div>
|
||||
<div class="albumcovers">
|
||||
<div class="infosection">
|
||||
<table width="100%">
|
||||
<?php
|
||||
print '<tr>
|
||||
<td colspan="4"><h2>'.get_int_text("albumart_title").'</h2></td>
|
||||
<td class="outer" align="right" colspan="1"><button id="finklestein">'.get_int_text("albumart_onlyempty").'</button></td>
|
||||
</tr>';
|
||||
print '<tr>
|
||||
<td class="outer" id="totaltext"></td>
|
||||
<td colspan="3"><div class="invisible" id="progress"></div></td>
|
||||
<td class="outer" align="right"><button id="harold">'.get_int_text("albumart_getmissing").'</button></td>
|
||||
</tr>';
|
||||
// <td class="outer" align="right"><button id="doobag">'.get_int_text("albumart_findsmall").'</button></td>
|
||||
print '<tr>
|
||||
<td class="outer" id="infotext"></td>
|
||||
<td colspan="3" align="center"><div class="inner" id="status">'.get_int_text('label_loading').'</div></td>
|
||||
<td class="outer styledinputs" align="right"><input type="checkbox" class="topcheck" id="dinkytoys"><label for="dinkytoys" onclick="toggleLocal()">Ignore Local Images</label></td>
|
||||
</tr>';
|
||||
|
||||
print '<tr>
|
||||
<td colspan="4"></td>
|
||||
<td class="outer styledinputs" align="right"><input type="checkbox" class="topcheck" id="poobag"><label for="poobag" onclick="toggleScrolling()">Follow Progress</label></td>
|
||||
</tr>';
|
||||
?>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div id="wobblebottom">
|
||||
|
||||
<div id="artistcoverslist" class="tleft noborder">
|
||||
<div class="noselection fullwidth">
|
||||
<?php
|
||||
if ($mysqlc) {
|
||||
print '<div class="containerbox menuitem clickable clickselectartist selected" id="allartists"><div class="expand" class="artistrow">'.get_int_text("albumart_allartists").'</div></div>';
|
||||
print '<div class="containerbox menuitem clickable clickselectartist" id="savedplaylists"><div class="expand" class="artistrow">Saved Playlists</div></div>';
|
||||
print '<div class="containerbox menuitem clickable clickselectartist" id="radio"><div class="expand" class="artistrow">'.get_int_text("label_yourradio").'</div></div>';
|
||||
do_artists_db_style();
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<div id="coverslist" class="tleft noborder">
|
||||
|
||||
<?php
|
||||
|
||||
// Do Local Albums
|
||||
$count = 0;
|
||||
$albums_without_cover = 0;
|
||||
do_covers_db_style();
|
||||
do_playlists();
|
||||
do_radio_stations();
|
||||
|
||||
print '</div>';
|
||||
|
||||
print "</div>\n";
|
||||
print "</div>\n";
|
||||
print '<script language="JavaScript">'."\n";
|
||||
print 'var numcovers = '.$count.";\n";
|
||||
print 'var albums_without_cover = '.$albums_without_cover.";\n";
|
||||
print "</script>\n";
|
||||
print "</body>\n";
|
||||
print "</html>\n";
|
||||
|
||||
function do_artists_db_style() {
|
||||
$alist = get_list_of_artists();
|
||||
foreach ($alist as $artist) {
|
||||
print '<div class="containerbox menuitem clickable clickselectartist';
|
||||
print '" id="artistname'.$artist['Artistindex'].'">';
|
||||
print '<div class="expand" class="artistrow">'.$artist['Artistname'].'</div>';
|
||||
print '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
function do_covers_db_style() {
|
||||
global $count;
|
||||
global $albums_without_cover;
|
||||
$alist = get_list_of_artists();
|
||||
foreach ($alist as $artist) {
|
||||
print '<div class="cheesegrater" name="artistname'.$artist['Artistindex'].'">';
|
||||
print '<div class="albumsection">';
|
||||
print '<div class="tleft"><h2>'.$artist['Artistname'].'</h2></div><div class="tright rightpad"><button class="invisible" onclick="getNewAlbumArt(\'#album'.$count.'\')">'.get_int_text("albumart_getthese").'</button></div>';
|
||||
print "</div>\n";
|
||||
print '<div id="album'.$count.'" class="containerbox fullwidth bigholder wrap">';
|
||||
$blist = get_list_of_albums($artist['Artistindex']);
|
||||
foreach ($blist as $album) {
|
||||
print '<div class="fixed albumimg closet">';
|
||||
print '<div class="covercontainer">';
|
||||
$class = "clickable clickicon clickalbumcover droppable";
|
||||
$src = "";
|
||||
if ($album['Image'] && $album['Image'] !== "") {
|
||||
$src = $album['Image'];
|
||||
} else {
|
||||
$class = $class . " notexist";
|
||||
$albums_without_cover++;
|
||||
}
|
||||
print '<input name="albumpath" type="hidden" value="'.get_album_directory($album['Albumindex'], $album['AlbumUri']).'" />';
|
||||
print '<input name="searchterm" type="hidden" value="'.rawurlencode($artist['Artistname']." ".munge_album_name($album['Albumname'])).'" />';
|
||||
print '<img class="'.$class.'" name="'.$album['ImgKey'].'"';
|
||||
if ($src != "") {
|
||||
print ' src="'.$src.'" ';
|
||||
}
|
||||
print '/>';
|
||||
|
||||
print '<div>'.$album['Albumname'].'</div>';
|
||||
print '</div>';
|
||||
print '</div>';
|
||||
$count++;
|
||||
}
|
||||
print "</div>\n";
|
||||
print "</div>\n";
|
||||
}
|
||||
}
|
||||
|
||||
function do_radio_stations() {
|
||||
|
||||
global $count;
|
||||
global $albums_without_cover;
|
||||
|
||||
$playlists = get_user_radio_streams();
|
||||
if (count($playlists) > 0) {
|
||||
print '<div class="cheesegrater" name="radio">';
|
||||
print '<div class="albumsection">';
|
||||
print '<div class="tleft"><h2>Radio Stations</h2></div><div class="tright rightpad"><button class="invisible" onclick="getNewAlbumArt(\'#album'.$count.'\')">'.get_int_text("albumart_getthese").'</button></div>';
|
||||
print "</div>\n";
|
||||
print '<div id="album'.$count.'" class="containerbox fullwidth bigholder wrap">';
|
||||
foreach ($playlists as $file) {
|
||||
print '<div class="fixed albumimg closet">';
|
||||
print '<div class="covercontainer">';
|
||||
$class = "";
|
||||
$src = "";
|
||||
if ($file['Image']) {
|
||||
$src = $file['Image'];
|
||||
} else {
|
||||
$class = " notexist";
|
||||
$albums_without_cover++;
|
||||
}
|
||||
print '<input name="searchterm" type="hidden" value="'.rawurlencode($file['StationName']).'" />';
|
||||
print '<input name="artist" type="hidden" value="STREAM" />';
|
||||
print '<input name="album" type="hidden" value="'.rawurlencode($file['StationName']).'" />';
|
||||
$albumimage = new baseAlbumImage(array('artist' => 'STREAM', 'album' => $file['StationName']));
|
||||
print '<img class="clickable clickicon clickalbumcover droppable'.$class.'" name="'.$albumimage->get_image_key().'"';
|
||||
if ($src != "") {
|
||||
print ' src="'.$src.'" ';
|
||||
}
|
||||
print '/>';
|
||||
print '<div>'.htmlentities($file['StationName']).'</div>';
|
||||
print '</div>';
|
||||
print '</div>';
|
||||
$count++;
|
||||
}
|
||||
print "</div>\n";
|
||||
print "</div>\n";
|
||||
}
|
||||
}
|
||||
|
||||
function do_playlists() {
|
||||
|
||||
global $count;
|
||||
global $albums_without_cover;
|
||||
global $PLAYER_TYPE;
|
||||
logger::log("PLAYLISTART", "Player type is", $PLAYER_TYPE);
|
||||
$player = new $PLAYER_TYPE();
|
||||
|
||||
$playlists = $player->get_stored_playlists(false);
|
||||
if (!is_array($playlists)) {
|
||||
$playlists = array();
|
||||
}
|
||||
$plfiles = glob('prefs/userplaylists/*');
|
||||
foreach ($plfiles as $f) {
|
||||
$playlists[] = basename($f);
|
||||
}
|
||||
print '<div class="cheesegrater" name="savedplaylists">';
|
||||
print '<div class="albumsection">';
|
||||
print '<div class="tleft"><h2>Saved Playlists</h2></div>';
|
||||
print "</div>\n";
|
||||
print '<div id="album'.$count.'" class="containerbox fullwidth bigholder wrap">';
|
||||
sort($playlists, SORT_STRING);
|
||||
foreach ($playlists as $pl) {
|
||||
logger::log("PLAYLISTART", "Playlist",$pl);
|
||||
print '<div class="fixed albumimg closet">';
|
||||
print '<div class="covercontainer">';
|
||||
$class = "";
|
||||
$albumimage = new baseAlbumImage(array('artist' => 'PLAYLIST', 'album' => $pl));
|
||||
$src = $albumimage->get_image_if_exists();
|
||||
if ($src === null) {
|
||||
$class = " plimage notfound";
|
||||
$src = '';
|
||||
$albums_without_cover++;
|
||||
}
|
||||
$plsearch = preg_replace('/ \(by .*?\)$/', '', $pl);
|
||||
print '<input name = "searchterm" type="hidden" value="'.rawurlencode($plsearch).'" />';
|
||||
print '<input name="artist" type="hidden" value="PLAYLIST" />';
|
||||
print '<input name="album" type="hidden" value="'.rawurlencode($pl).'" />';
|
||||
print '<img class="clickable clickicon clickalbumcover droppable playlistimage'.$class.'" name="'.$albumimage->get_image_key().'"';
|
||||
if ($src != "") {
|
||||
print ' src="'.$src.'" ';
|
||||
}
|
||||
print '/>';
|
||||
print '<div>'.htmlentities($pl).'</div>';
|
||||
print '</div>';
|
||||
print '</div>';
|
||||
$count++;
|
||||
}
|
||||
print "</div>\n";
|
||||
print "</div>\n";
|
||||
|
||||
}
|
||||
|
||||
?>
|
1
www/jukebox/albumart/.empty
Executable file
1
www/jukebox/albumart/.empty
Executable file
@ -0,0 +1 @@
|
||||
|
331
www/jukebox/albums.php
Normal file
331
www/jukebox/albums.php
Normal file
@ -0,0 +1,331 @@
|
||||
<?php
|
||||
|
||||
// Automatic Collection Updates can be performed using cURL:
|
||||
// curl -b "currenthost=Default;player_backend=mpd" http://localhost/rompr/albums.php?rebuild > /dev/null
|
||||
// where currenthost is the name of one of the Players defined in the Configuration menu
|
||||
// and player_backend MUST be mpd or mopidy, depending on what your player is.
|
||||
// You can also use eg -b "debug_enabled=8;currenthost=MPD;player_backend=mpd"
|
||||
// to get more debug info in the webserver error log.
|
||||
|
||||
require_once ("includes/vars.php");
|
||||
require_once ("includes/functions.php");
|
||||
require_once ("utils/imagefunctions.php");
|
||||
require_once ("international.php");
|
||||
require_once ("backends/sql/backend.php");
|
||||
$error = 0;
|
||||
|
||||
logger::trace("TIMINGS", "======================================================================");
|
||||
$initmem = memory_get_usage();
|
||||
logger::trace("COLLECTION", "Memory Used is ".$initmem);
|
||||
$now2 = time();
|
||||
|
||||
switch (true) {
|
||||
|
||||
case array_key_exists('item', $_REQUEST):
|
||||
logit('item');
|
||||
// Populate a dropdown in the collection or search results
|
||||
dumpAlbums($_REQUEST['item']);
|
||||
break;
|
||||
|
||||
case array_key_exists('mpdsearch', $_REQUEST):
|
||||
logit('mpdsearch');
|
||||
// Handle an mpd-style search request
|
||||
require_once ("player/".$prefs['player_backend']."/player.php");
|
||||
require_once ("collection/collection.php");
|
||||
$trackbytrack = true;
|
||||
$doing_search = true;
|
||||
mpd_search();
|
||||
break;
|
||||
|
||||
case array_key_exists('browsealbum', $_REQUEST):
|
||||
logit('browsealbum');
|
||||
// Populate a spotify album in mopidy's search results - as spotify doesn't return all tracks
|
||||
require_once ("player/".$prefs['player_backend']."/player.php");
|
||||
require_once ("collection/collection.php");
|
||||
$trackbytrack = true;
|
||||
$doing_search = true;
|
||||
browse_album();
|
||||
break;
|
||||
|
||||
case array_key_exists("rawterms", $_REQUEST):
|
||||
logit('rawterms');
|
||||
// Handle an mpd-style search request requiring tl_track format results
|
||||
// Note that raw_search uses the collection models but not the database
|
||||
// hence $trackbytrack must be false
|
||||
logger::log("MPD SEARCH", "Doing RAW search");
|
||||
require_once ("player/".$prefs['player_backend']."/player.php");
|
||||
require_once ("collection/collection.php");
|
||||
require_once ("collection/dbsearch.php");
|
||||
$doing_search = true;
|
||||
raw_search();
|
||||
break;
|
||||
|
||||
case array_key_exists('terms', $_REQUEST):
|
||||
logit('terms');
|
||||
// SQL database search request
|
||||
require_once ("player/".$prefs['player_backend']."/player.php");
|
||||
require_once ("collection/collection.php");
|
||||
require_once ("collection/dbsearch.php");
|
||||
$doing_search = true;
|
||||
database_search();
|
||||
break;
|
||||
|
||||
case array_key_exists('rebuild', $_REQUEST):
|
||||
logit('rebuild');
|
||||
// This is a request to rebuild the music collection
|
||||
require_once ("player/".$prefs['player_backend']."/player.php");
|
||||
require_once ("collection/collection.php");
|
||||
$trackbytrack = true;
|
||||
update_collection();
|
||||
break;
|
||||
|
||||
default:
|
||||
logger::fail("ALBUMS", "Couldn't figure out what to do!");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
logger::trace("TIMINGS", "== Collection Update And Send took ".format_time(time() - $now2));
|
||||
$peakmem = memory_get_peak_usage();
|
||||
$ourmem = $peakmem - $initmem;
|
||||
logger::trace("TIMINGS", "Peak Memory Used Was ".number_format($peakmem)." bytes - meaning we used ".number_format($ourmem)." bytes.");
|
||||
logger::trace("TIMINGS", "======================================================================");
|
||||
|
||||
function logit($key) {
|
||||
logger::log("COLLECTION", "Request is",$key,"=",$_REQUEST[$key]);
|
||||
}
|
||||
|
||||
function checkDomains($d) {
|
||||
if (array_key_exists('domains', $d)) {
|
||||
return $d['domains'];
|
||||
}
|
||||
logger::debug("SEARCH", "No search domains in use");
|
||||
return false;
|
||||
}
|
||||
|
||||
function mpd_search() {
|
||||
global $dbterms, $skin, $PLAYER_TYPE;
|
||||
// If we're searching for tags or ratings it would seem sensible to only search the database
|
||||
// HOWEVER - we could be searching for genre or performer or composer - which will not match in the database
|
||||
// For those cases ONLY, controller.js will call into this instead of database_search, and we set $dbterms
|
||||
// to make the collection check everything it finds against the database
|
||||
$cmd = $_REQUEST['command'];
|
||||
$domains = checkDomains($_REQUEST);
|
||||
foreach ($_REQUEST['mpdsearch'] as $key => $term) {
|
||||
switch ($key) {
|
||||
case 'tag':
|
||||
case 'rating':
|
||||
$dbterms[$key] = $term;
|
||||
break;
|
||||
|
||||
case 'any':
|
||||
// This makes a search term of 'Madness My Girl' into
|
||||
// search any Madness any My any Girl
|
||||
// which seems to produce better results with Spotify. But probably doesn't with Google Play, which
|
||||
// only uses the first term. Soundcloud concatenates them all back into one term again. What does MPD do?
|
||||
foreach ($term as $t) {
|
||||
$terms = explode(' ',$t);
|
||||
foreach ($terms as $tom) {
|
||||
$cmd .= " ".$key.' "'.format_for_mpd(html_entity_decode(trim($tom))).'"';
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
foreach ($term as $t) {
|
||||
$cmd .= " ".$key.' "'.format_for_mpd(html_entity_decode(trim($t))).'"';
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
logger::log("MPD SEARCH", "Search command : ".$cmd);
|
||||
if ($_REQUEST['resultstype'] == "tree") {
|
||||
require_once ("player/mpd/filetree.php");
|
||||
require_once ("skins/".$skin."/ui_elements.php");
|
||||
$player = new fileCollector();
|
||||
$player->doFileSearch($cmd, $domains);
|
||||
} else {
|
||||
cleanSearchTables();
|
||||
prepareCollectionUpdate();
|
||||
$collection = new musicCollection();
|
||||
$player = new $PLAYER_TYPE();
|
||||
$player->populate_collection($cmd, $domains, $collection);
|
||||
$collection->tracks_to_database();
|
||||
close_transaction();
|
||||
dumpAlbums($_REQUEST['dump']);
|
||||
remove_findtracks();
|
||||
}
|
||||
}
|
||||
|
||||
function browse_album() {
|
||||
global $PLAYER_TYPE, $skin;
|
||||
$a = preg_match('/(a|b)(.*?)(\d+|root)/', $_REQUEST['browsealbum'], $matches);
|
||||
if (!$a) {
|
||||
print '<h3>'.get_int_text("label_general_error").'</h3>';
|
||||
logger::error("DUMPALBUMS", "Browse Album Failed - regexp failed to match", $_REQUEST['browsealbum']);
|
||||
return false;
|
||||
}
|
||||
$why = $matches[1];
|
||||
$what = $matches[2];
|
||||
$who = $matches[3];
|
||||
$albumlink = get_albumlink($who);
|
||||
if (substr($albumlink, 0, 8) == 'podcast+') {
|
||||
require_once ('includes/podcastfunctions.php');
|
||||
logger::log("ALBUMS", "Browsing For Podcast ".substr($albumlink, 9));
|
||||
$podid = getNewPodcast(substr($albumlink, 8), 0, false);
|
||||
logger::trace("ALBUMS", "Ouputting Podcast ID ".$podid);
|
||||
outputPodcast($podid, false);
|
||||
} else {
|
||||
if (preg_match('/^.+?:artist:/', $albumlink)) {
|
||||
remove_album_from_database($who);
|
||||
}
|
||||
$player = new $PLAYER_TYPE();
|
||||
$collection = new musicCollection();
|
||||
$cmd = 'find file "'.$albumlink.'"';
|
||||
logger::log("MPD", "Doing Album Browse : ".$cmd);
|
||||
prepareCollectionUpdate();
|
||||
$player->populate_collection($cmd, false, $collection);
|
||||
$collection->tracks_to_database(true);
|
||||
close_transaction();
|
||||
remove_findtracks();
|
||||
if (preg_match('/^.+?:album:/', $albumlink)) {
|
||||
// Just occasionally, the spotify album originally returned by search has an incorrect AlbumArtist
|
||||
// When we browse the album the new tracks therefore get added to a new album, while the original tracks
|
||||
// remain attached to the old one. This is where we use do_tracks_from_database with an array of albumids
|
||||
// which joins them together into a virtual album, with the track ordering correct
|
||||
print do_tracks_from_database($why, $what, find_justadded_albums(), true);
|
||||
} else {
|
||||
$artistarray = find_justadded_artists();
|
||||
$do_controlheader = true;
|
||||
foreach ($artistarray as $artistid) {
|
||||
do_albums_from_database($why, 'album', $artistid, false, false, true, $do_controlheader);
|
||||
$do_controlheader = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function raw_search() {
|
||||
global $PLAYER_TYPE, $doing_search;
|
||||
$domains = checkDomains($_REQUEST);
|
||||
$collection = new musicCollection();
|
||||
$found = 0;
|
||||
logger::trace("MPD SEARCH", "checkdb is ".$_REQUEST['checkdb']);
|
||||
if ($_REQUEST['checkdb'] !== 'false') {
|
||||
logger::trace("MPD SEARCH", " ... checking database first ");
|
||||
$found = doDbCollection($_REQUEST['rawterms'], $domains, "RAW", $collection);
|
||||
if ($found > 0) {
|
||||
logger::log("MPD SEARCH", " ... found ".$found." matches in database");
|
||||
}
|
||||
}
|
||||
if ($found == 0) {
|
||||
$cmd = $_REQUEST['command'];
|
||||
foreach ($_REQUEST['rawterms'] as $key => $term) {
|
||||
$cmd .= " ".$key.' "'.format_for_mpd(html_entity_decode($term[0])).'"';
|
||||
}
|
||||
logger::log("MPD SEARCH", "Search command : ".$cmd);
|
||||
$doing_search = true;
|
||||
$player = new $PLAYER_TYPE();
|
||||
$player->populate_collection($cmd, $domains, $collection);
|
||||
|
||||
// For backends that don't support multiple parameters (Google Play)
|
||||
// This'll return nothing for Spotify, so it's OK. It might help SoundCloud too.
|
||||
|
||||
$cmd = $_REQUEST['command'].' any ';
|
||||
$parms = array();
|
||||
if (array_key_exists('artist', $_REQUEST['rawterms'])) {
|
||||
$parms[] = format_for_mpd(html_entity_decode($_REQUEST['rawterms']['artist'][0]));
|
||||
}
|
||||
if (array_key_exists('title', $_REQUEST['rawterms'])) {
|
||||
$parms[] = format_for_mpd(html_entity_decode($_REQUEST['rawterms']['title'][0]));
|
||||
}
|
||||
if (count($parms) > 0) {
|
||||
$cmd .= '"'.implode(' ',$parms).'"';
|
||||
logger::log("MPD SEARCH", "Search command : ".$cmd);
|
||||
$doing_search = true;
|
||||
$collection->filter_duplicate_tracks();
|
||||
$player->populate_collection($cmd, $domains, $collection);
|
||||
}
|
||||
|
||||
}
|
||||
print json_encode($collection->tracks_as_array());
|
||||
}
|
||||
|
||||
function database_search() {
|
||||
$tree = null;
|
||||
$domains = checkDomains($_REQUEST);
|
||||
if ($_REQUEST['resultstype'] == "tree") {
|
||||
$tree = new mpdlistthing(null);
|
||||
} else {
|
||||
cleanSearchTables();
|
||||
open_transaction();
|
||||
}
|
||||
$fcount = doDbCollection($_REQUEST['terms'], $domains, $_REQUEST['resultstype'], $tree);
|
||||
if ($_REQUEST['resultstype'] == "tree") {
|
||||
printFileSearch($tree, $fcount);
|
||||
} else {
|
||||
close_transaction();
|
||||
dumpAlbums($_REQUEST['dump']);
|
||||
}
|
||||
}
|
||||
|
||||
function update_collection() {
|
||||
global $PLAYER_TYPE;
|
||||
|
||||
// Check that an update is not currently in progress
|
||||
// and create the update lock if not
|
||||
if (collectionUpdateRunning()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
print get_int_text('error_nocol');
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (file_exists('prefs/monitor')) {
|
||||
unlink('prefs/monitor');
|
||||
}
|
||||
// Send some dummy data back to the browser, then close the connection
|
||||
// so that the browser doesn't time out and retry
|
||||
$sapi_type = php_sapi_name();
|
||||
logger::log('COLLECTION','SAPI Name is',$sapi_type);
|
||||
if (preg_match('/fpm/', $sapi_type) || preg_match('/fcgi/', $sapi_type)) {
|
||||
logger::mark('COLLECTION', 'Closing Request The FastCGI Way');
|
||||
print('<html></html>');
|
||||
fastcgi_finish_request();
|
||||
} else {
|
||||
logger::mark('COLLECTION', 'Closing Request The Apache Way');
|
||||
ob_end_clean();
|
||||
ignore_user_abort(true); // just to be safe
|
||||
ob_start();
|
||||
print('<html></html>');
|
||||
$size = ob_get_length();
|
||||
header("Content-Length: $size");
|
||||
header("Content-Encoding: none");
|
||||
header("Connection: close");
|
||||
ob_end_flush();
|
||||
ob_flush();
|
||||
flush();
|
||||
if (ob_get_contents()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
}
|
||||
|
||||
if (session_id()) {
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
// Browser is now happy. Now we can do our work in peace.
|
||||
cleanSearchTables();
|
||||
prepareCollectionUpdate();
|
||||
$player = new $PLAYER_TYPE();
|
||||
$player->musicCollectionUpdate();
|
||||
tidy_database();
|
||||
remove_findtracks();
|
||||
// Add a marker to the monitor file to say we've finished
|
||||
$player->collectionUpdateDone();
|
||||
// Clear the update lock
|
||||
clearUpdateLock();
|
||||
|
||||
}
|
||||
|
||||
?>
|
1953
www/jukebox/backends/sql/backend.php
Normal file
1953
www/jukebox/backends/sql/backend.php
Normal file
File diff suppressed because it is too large
Load Diff
301
www/jukebox/backends/sql/connect.php
Normal file
301
www/jukebox/backends/sql/connect.php
Normal file
@ -0,0 +1,301 @@
|
||||
<?php
|
||||
|
||||
$mysqlc = null;
|
||||
if (array_key_exists('collection_type', $prefs)) {
|
||||
include("backends/sql/".$prefs['collection_type']."/specifics.php");
|
||||
}
|
||||
|
||||
function probe_database() {
|
||||
// In the case where collection_type is not set, probe to see which type of DB to use
|
||||
// This keeps the behaviour the same as previous versions which auto-detected
|
||||
// the database type. This does mean we get some duplicate code but this is
|
||||
// so much better for the user.
|
||||
global $mysqlc, $prefs;
|
||||
logger::mark("SQL_CONNECT", "Probing Database Type");
|
||||
logger::log("SQL_CONNECT", "Attempting to connect to MYSQL Server");
|
||||
try {
|
||||
if (is_numeric($prefs['mysql_port'])) {
|
||||
logger::trace("SQL_CONNECT", "Connecting using hostname and port");
|
||||
$dsn = "mysql:host=".$prefs['mysql_host'].";port=".$prefs['mysql_port'].";dbname=".$prefs['mysql_database'];
|
||||
} else {
|
||||
logger::trace("SQL_CONNECT", "Connecting using unix socket");
|
||||
$dsn = "mysql:unix_socket=".$prefs['mysql_port'].";dbname=".$prefs['mysql_database'];
|
||||
}
|
||||
$mysqlc = new PDO($dsn, $prefs['mysql_user'], $prefs['mysql_password']);
|
||||
logger::mark("SQL_CONNECT", "Connected to MySQL");
|
||||
$prefs['collection_type'] = 'mysql';
|
||||
} catch (Exception $e) {
|
||||
logger::warn("SQL_CONNECT", "Couldn't connect to MySQL - ".$e);
|
||||
$mysqlc = null;
|
||||
}
|
||||
if ($mysqlc == null) {
|
||||
logger::log("SQL_CONNECT", "Attempting to use SQLite Database");
|
||||
try {
|
||||
$dsn = "sqlite:prefs/collection.sq3";
|
||||
$mysqlc = new PDO($dsn);
|
||||
logger::mark("MYSQL", "Connected to SQLite");
|
||||
$prefs['collection_type'] = 'sqlite';
|
||||
} catch (Exception $e) {
|
||||
logger::fail("MYSQL", "Couldn't use SQLite Either - ".$e);
|
||||
$mysqlc = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Initialisation
|
||||
//
|
||||
|
||||
function show_sql_error($text = "", $stmt = null) {
|
||||
global $mysqlc;
|
||||
logger::error("MYSQL ERROR", $text,":",$mysqlc->errorInfo()[1],":",$mysqlc->errorInfo()[2]);
|
||||
if ($stmt !== null) {
|
||||
logger::error("STMT ERROR", $text,":",$stmt->errorInfo()[1],":",$stmt->errorInfo()[2]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Queries
|
||||
//
|
||||
|
||||
function generic_sql_query($qstring, $return_boolean = false, $return_type = PDO::FETCH_ASSOC, $return_value = null, $value_default = null, $return_rowcount = false ) {
|
||||
global $mysqlc;
|
||||
logger::debug("GENERIC_SQL", $qstring);
|
||||
$retval = true;
|
||||
if (($result = @$mysqlc->query($qstring)) !== false) {
|
||||
logger::debug("GENERIC_SQL", "Done : ".($result->rowCount())." rows affected");
|
||||
if ($return_value !== null) {
|
||||
$arr = $result->fetch(PDO::FETCH_ASSOC);
|
||||
$retval = ($arr) ? $arr[$return_value] : $value_default;
|
||||
} else if ($return_boolean) {
|
||||
$retval = true;
|
||||
} else if ($return_rowcount) {
|
||||
return $result->rowCount();
|
||||
} else {
|
||||
$retval = $result->fetchAll($return_type);
|
||||
}
|
||||
} else {
|
||||