Initial commit of kettek MediaServe. Contains basic framework and implementation. FileBrowser module fairly complete, much more to be added, including Playlist module and Player module.
commit
cf52a6d616
|
@ -0,0 +1,132 @@
|
|||
<?php
|
||||
namespace ktk\MusicServe;
|
||||
session_start();
|
||||
|
||||
class MusicServe {
|
||||
static public $modules = array();
|
||||
static public $errors = array();
|
||||
static public $warnings = array();
|
||||
static private $storage = array();
|
||||
|
||||
static function loadModule($name) {
|
||||
if (file_exists('modules/'.$name.'.php')) {
|
||||
include_once 'modules/'.$name.'.php';
|
||||
array_push(self::$modules, $name);
|
||||
} else {
|
||||
self::reportError(__CLASS__, __FUNCTION__, "Module ".$name." does not exist!");
|
||||
}
|
||||
}
|
||||
static function checkModule($name) {
|
||||
return array_search($name, self::$modules);
|
||||
}
|
||||
|
||||
static function initProgram() {
|
||||
foreach(self::$modules as $module) {
|
||||
if (method_exists('ktk\\MusicServe\\'.$module, 'onInit')) {
|
||||
call_user_func('ktk\\MusicServe\\'.$module.'::onInit');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function processProgram() {
|
||||
// check for module commands and call them if so
|
||||
if (isset($_POST['m'])) {
|
||||
if (isset($_POST['c'])) {
|
||||
if (method_exists('ktk\\MusicServe\\'.$_POST['m'], $_POST['c'])) {
|
||||
call_user_func('ktk\\MusicServe\\'.$_POST['m'].'::'.$_POST['c'], $_POST['p1']);
|
||||
}
|
||||
}
|
||||
} else if (isset($_GET['m'])) {
|
||||
if (isset($_GET['c'])) {
|
||||
if (method_exists('ktk\\MusicServe\\'.$_GET['m'], $_GET['c'])) {
|
||||
call_user_func('ktk\\MusicServe\\'.$_GET['m'].'::'.$_GET['c'], $_GET['p1']);
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach(self::$modules as $module) {
|
||||
if (method_exists('ktk\\MusicServe\\'.$module, 'onProcess')) {
|
||||
call_user_func('ktk\\MusicServe\\'.$module.'::onProcess');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function renderCss() {
|
||||
echo ' <link rel="stylesheet" href="main.css" type="text/css" media="screen" charset="utf-8">'.PHP_EOL;
|
||||
foreach(self::$modules as $module) {
|
||||
if (file_exists('modules/'.$module.'.css')) {
|
||||
echo ' <link rel="stylesheet" href="modules/'.$module.'.css" type="text/css" media="screen" charset="utf-8">'.PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function renderProgram() {
|
||||
foreach(self::$modules as $module) {
|
||||
if (method_exists('ktk\\MusicServe\\'.$module, 'onRender')) {
|
||||
call_user_func('ktk\\MusicServe\\'.$module.'::onRender');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function closeProgram() {
|
||||
foreach(self::$modules as $module) {
|
||||
if (method_exists('ktk\\MusicServe\\'.$module, 'onClose')) {
|
||||
call_user_func('ktk\\MusicServe\\'.$module.'::onClose');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function reportError($context, $subcontext, $error) {
|
||||
if(!self::$errors[$context."::".$subcontext])
|
||||
self::$errors[$context."::".$subcontext] = array();
|
||||
array_push(self::$errors[$context."::".$subcontext], $error);
|
||||
}
|
||||
|
||||
static function reportWarning($context, $subcontext, $warning) {
|
||||
if(!self::$warnings[$context."::".$subcontext])
|
||||
self::$warnings[$context."::".$subcontext] = array();
|
||||
array_push(self::$warnings[$context."::".$subcontext], $warning);
|
||||
}
|
||||
|
||||
static function loadConf($file) {
|
||||
if (file_exists('conf/'.$file.'.ini')) {
|
||||
return parse_ini_file('conf/'.$file.'.ini');
|
||||
} else {
|
||||
self::reportWarning(__CLASS__, __FUNCTION__, "Could not load ".'conf/'.$file.'.ini');
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
static function saveConf($data) {
|
||||
if ($fp = fopen($data, 'w')) {
|
||||
self::writeData_r($fp, $data);
|
||||
fclose($fp);
|
||||
} else {
|
||||
MusicServe::reportError(__CLASS__, __FUNCTION__, "Could not write to \"".$data."\", please check your permissions!");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
static function writeData_r($handle, $value) {
|
||||
foreach ($data as $key=>$value) {
|
||||
if (is_array($value)) {
|
||||
fwrite($handle, '['.$key.']'.PHP_EOL);
|
||||
self::writeData_r($handle, $value);
|
||||
} else {
|
||||
fwrite($handle, $key.'='.$value.PHP_EOL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static function storeData($var, $data) {
|
||||
$_SESSION[$var] = $data;
|
||||
}
|
||||
|
||||
static function &getData($data) {
|
||||
if (isset($_SESSION[$data])) {
|
||||
return $_SESSION[$data];
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1 @@
|
|||
pub = pub
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
include_once 'MusicServe.php';
|
||||
|
||||
ktk\MusicServe\MusicServe::loadModule("BasicAuth");
|
||||
ktk\MusicServe\MusicServe::loadModule("ErrorReporter");
|
||||
ktk\MusicServe\MusicServe::loadModule("FileBrowser");
|
||||
ktk\MusicServe\MusicServe::loadModule("Playlist");
|
||||
ktk\MusicServe\MusicServe::loadModule("Player");
|
||||
|
||||
ktk\MusicServe\MusicServe::initProgram();
|
||||
ktk\MusicServe\MusicServe::processProgram();
|
||||
?>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!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>
|
||||
<meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
|
||||
<title>ktk MusicServe</title>
|
||||
<?php ktk\MusicServe\MusicServe::renderCss() ?>
|
||||
</head>
|
||||
<body>
|
||||
<?php ktk\MusicServe\MusicServe::renderProgram() ?>
|
||||
</body>
|
||||
</html>
|
||||
<?php ktk\MusicServe\MusicServe::closeProgram() ?>
|
|
@ -0,0 +1,6 @@
|
|||
html,body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
#ktk_MusicServe_BasicAuth {
|
||||
position: absolute;
|
||||
bottom:0;
|
||||
right:0;
|
||||
float:right;
|
||||
background-color: #222;
|
||||
}
|
||||
|
||||
#ktk_MusicServe_BasicAuth input {
|
||||
border: 0;
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
namespace ktk\MusicServe;
|
||||
|
||||
class BasicAuth {
|
||||
static private $realm = "ktk_MusicServe";
|
||||
static private $auth_file = "BasicAuth";
|
||||
static private $creds = array();
|
||||
|
||||
static public function onInit() {
|
||||
self::$creds = MusicServe::loadConf(self::$auth_file);
|
||||
if (!isset($_SESSION['logged'])) {
|
||||
self::doAuth();
|
||||
}
|
||||
}
|
||||
static public function onRender() {
|
||||
echo ' <div id="ktk_MusicServe_BasicAuth">'.PHP_EOL;
|
||||
echo ' <form action="" method="POST">';
|
||||
echo ' <input type="hidden" name="m" value="BasicAuth" />';
|
||||
echo ' <input type="hidden" name="c" value="doLogout" />';
|
||||
echo ' <input type="submit" name="" value="Exit" />';
|
||||
echo ' </form>';
|
||||
echo ' </div>';
|
||||
}
|
||||
static public function doLogout() {
|
||||
if (ini_get("session.use_cookies")) {
|
||||
$params = session_get_cookie_params();
|
||||
setcookie(session_name(), '', time() - 42000,
|
||||
$params["path"], $params["domain"],
|
||||
$params["secure"], $params["httponly"]
|
||||
);
|
||||
session_destroy();
|
||||
session_unset($_SESSION['logged']);
|
||||
header('HTTP/1.1 401 Unauthorized');
|
||||
die("Logged out, please <a href=\"".$_SERVER['PHP_SELF']."\">click here</a> to login");
|
||||
}
|
||||
}
|
||||
static public function doAuth() {
|
||||
if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
|
||||
header('HTTP/1.1 401 Unauthorized');
|
||||
header('WWW-Authenticate: Digest realm="'.self::$realm.'",qop="auth",nonce="'.uniqid().'",opaque="'.md5(self::$realm).'"');
|
||||
die("Canceled - refresh or <a href=\"".$_SERVER['PHP_SELF']."\">click here</a> to try again");
|
||||
}
|
||||
if (!($data = self::parseHttpDigest($_SERVER['PHP_AUTH_DIGEST'])) || !isset(self::$creds[$data['username']])) {
|
||||
header('HTTP/1.1 401 Unauthorized');
|
||||
die("Incorrect credentials, please <a href=\"".$_SERVER['PHP_SELF']."\">click here</a> to try again");
|
||||
}
|
||||
$A1 = md5($data['username'] . ':' . self::$realm . ':' . self::$creds[$data['username']]);
|
||||
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
|
||||
$valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);
|
||||
if ($data['response'] != $valid_response) {
|
||||
header('HTTP/1.1 401 Unauthorized');
|
||||
die("Incorrect credentials, please <a href=\"".$_SERVER['PHP_SELF']."\">click here</a> to try again");
|
||||
}
|
||||
$_SESSION['logged'] = TRUE;
|
||||
}
|
||||
static public function parseHttpDigest($text) {
|
||||
$needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
|
||||
$data = array();
|
||||
$keys = implode('|', array_keys($needed_parts));
|
||||
preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $text, $matches, PREG_SET_ORDER);
|
||||
foreach ($matches as $m) {
|
||||
$data[$m[1]] = $m[3] ? $m[3] : $m[4];
|
||||
unset($needed_parts[$m[1]]);
|
||||
}
|
||||
return $needed_parts ? false : $data;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
namespace ktk\MusicServe;
|
||||
|
||||
class Clock {
|
||||
static private $time = "";
|
||||
static function onInit() {
|
||||
if (!MusicServe::getData('time_format')) {
|
||||
MusicServe::storeData('time_format', 'H:i:s');
|
||||
}
|
||||
}
|
||||
static function onProcess() {
|
||||
self::$time = date(MusicServe::getData('time_format'));
|
||||
}
|
||||
static function onRender() {
|
||||
echo '<div id="ktk_MusicServe_Clock">'.PHP_EOL;
|
||||
echo self::$time.PHP_EOL;
|
||||
echo '<a href="?m=Clock&c=changeTime&p1=g:i:s a">12-hour</a>'.PHP_EOL;
|
||||
echo '</div>'.PHP_EOL;
|
||||
}
|
||||
static function changeTime($format) {
|
||||
MusicServe::storeData('time_format', $format);
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,21 @@
|
|||
#ktk_MusicServe_ErrorReporter {
|
||||
background-color: #633;
|
||||
color: #FCA;
|
||||
font-family: console, consolas, terminal;
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
#ktk_MusicServe_ErrorReporter * {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#ktk_MusicServe_ErrorReporter h1 {
|
||||
text-align: center;
|
||||
color: #FAA;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
#ktk_MusicServe_ErrorReporter table {
|
||||
width: 100%;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
namespace ktk\MusicServe;
|
||||
|
||||
class ErrorReporter {
|
||||
|
||||
static function onInit() {}
|
||||
|
||||
static function onRender() {
|
||||
if (!MusicServe::$errors)
|
||||
return;
|
||||
echo '<div id="ktk_MusicServe_ErrorReporter">';
|
||||
echo '<h1>ERRORS</h1>';
|
||||
echo '<table>';
|
||||
echo '<tr><th>context</th><th>error</th></tr>';
|
||||
foreach (MusicServe::$errors as $context=>$error_context) {
|
||||
foreach($error_context as $error) {
|
||||
echo '<tr><td>'.$context.'</td><td>'.$error.'</td></tr>';
|
||||
}
|
||||
}
|
||||
echo '</table>';
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,57 @@
|
|||
#ktk_MusicServe_FileBrowser {
|
||||
float: left;
|
||||
overflow: auto;
|
||||
margin: auto;
|
||||
width:200px;
|
||||
display: block;
|
||||
height:100%;
|
||||
background-color: #444;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
#ktk_MusicServe_FileBrowser * {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-family: console, consolas, terminal;
|
||||
font-size: 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#ktk_MusicServe_FileBrowser h1 {
|
||||
display: block;
|
||||
height: 24px;
|
||||
overflow: hidden;
|
||||
color: #CCC;
|
||||
}
|
||||
|
||||
#ktk_MusicServe_FileBrowser table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#ktk_MusicServe_FileBrowser table,
|
||||
#ktk_MusicServe_FileBrowser tr,
|
||||
#ktk_MusicServe_FileBrowser td,
|
||||
#ktk_MusicServe_FileBrowser input
|
||||
{
|
||||
background-color: #444;
|
||||
color: #CCC;
|
||||
}
|
||||
|
||||
#ktk_MusicServe_FileBrowser th,
|
||||
#ktk_MusicServe_FileBrowser th input {
|
||||
min-width: 32px;
|
||||
background-color:#777;
|
||||
}
|
||||
|
||||
#ktk_MusicServe_FileBrowser td input {
|
||||
width: 160px;
|
||||
background-color: #111;
|
||||
color: #CCC;
|
||||
}
|
||||
|
||||
#ktk_MusicServe_FileBrowser input:hover {
|
||||
background-color: #777;
|
||||
cursor: pointer;
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
<?php
|
||||
namespace ktk\MusicServe;
|
||||
|
||||
class FileBrowser {
|
||||
const ROOT = "media/";
|
||||
|
||||
const T_DIR = 1;
|
||||
const T_FILE = 2;
|
||||
|
||||
const F_TYPE = 0;
|
||||
const F_NAME = 1;
|
||||
const F_EXT = 2;
|
||||
|
||||
static function onInit() {
|
||||
// set default options if need be
|
||||
if (!MusicServe::getData('sort_by')) {
|
||||
MusicServe::storeData('sort_order', SORT_ASC);
|
||||
MusicServe::storeData('sort_by', "name");
|
||||
}
|
||||
if (!MusicServe::getData('cwd')) {
|
||||
MusicServe::storeData('cwd', FileBrowser::ROOT);
|
||||
self::getFiles();
|
||||
self::sortFiles();
|
||||
}
|
||||
}
|
||||
|
||||
static function onRender() {
|
||||
$cwd = MusicServe::getData('cwd');
|
||||
echo ' <div id="ktk_MusicServe_FileBrowser">'.PHP_EOL;
|
||||
echo ' <h1>',$cwd,'</h1>'.PHP_EOL;
|
||||
if (MusicServe::checkModule("Playlist")) {
|
||||
echo ' <form action="" method="POST">';
|
||||
echo ' <input type="hidden" name="m" value="FileBrowser" />';
|
||||
echo ' <input type="hidden" name="c" value="openFiles" />';
|
||||
echo ' <input type="submit" name="" value="add all to playlist" />';
|
||||
echo ' </form>';
|
||||
}
|
||||
echo ' <table>'.PHP_EOL;
|
||||
echo ' <form action="" method="POST">';
|
||||
echo ' <input type="hidden" name="m" value="FileBrowser" />';
|
||||
echo ' <input type="hidden" name="c" value="changeSort" />';
|
||||
echo ' <tr><th><input type="submit" name="p1" value="name" /></th><th><input type="submit" name="p1" value="ext" /></th></tr>'.PHP_EOL;
|
||||
echo ' </form>'.PHP_EOL;
|
||||
echo ' <form action="" method="POST">';
|
||||
echo ' <input type="hidden" name="m" value="FileBrowser" />';
|
||||
echo ' <input type="hidden" name="c" value="changeCwd" />';
|
||||
echo ' <tr><td><input type="submit" name="p1" value="../"></td><td></td></tr>'.PHP_EOL;
|
||||
foreach(MusicServe::getData('dirs') as $dir) {
|
||||
echo ' <tr><td><input type="submit" name="p1" value="'.$dir[FileBrowser::F_NAME].'/"></td><td></td></tr>'.PHP_EOL;
|
||||
}
|
||||
echo ' </form>'.PHP_EOL;
|
||||
|
||||
echo ' <form action="" method="POST">';
|
||||
echo ' <input type="hidden" name="m" value="FileBrowser" />';
|
||||
echo ' <input type="hidden" name="c" value="openFile" />';
|
||||
foreach(MusicServe::getData('files') as $file) {
|
||||
echo ' <tr><td><input type="submit" name="p1" value="'.$file[FileBrowser::F_NAME].'"/></td><td>'.$file[FileBrowser::F_EXT].'</td></tr>'.PHP_EOL;
|
||||
}
|
||||
echo ' </form>'.PHP_EOL;
|
||||
echo ' </table>'.PHP_EOL;
|
||||
echo ' </div>'.PHP_EOL;
|
||||
}
|
||||
|
||||
/* COMMAND FUNCTIONS */
|
||||
static function changeCwd($directory) {
|
||||
// NOTE: temporarily resolving any ".." to one dir up, rather than all
|
||||
if (substr_count($directory, "..")) {
|
||||
if (MusicServe::getData('cwd') == FileBrowser::ROOT) {
|
||||
return NULL;
|
||||
}
|
||||
$directory = dirname(MusicServe::getData('cwd')).'/';
|
||||
} else {
|
||||
$directory = MusicServe::getData('cwd').$directory;
|
||||
}
|
||||
if (!file_exists($directory)) {
|
||||
MusicServe::reportError(__CLASS__, __FUNCTION__,
|
||||
"Cannot change working directory to \"'.$directory.'\", as it does not exist!\n"
|
||||
);
|
||||
return NULL;
|
||||
}
|
||||
MusicServe::storeData('cwd', $directory);
|
||||
self::getFiles();
|
||||
self::sortFiles();
|
||||
}
|
||||
|
||||
static function changeSort($type) {
|
||||
MusicServe::storeData('sort_by', $type);
|
||||
if (($sort_order = MusicServe::getData('sort_order')) != SORT_ASC) {
|
||||
MusicServe::storeData('sort_order', SORT_ASC);
|
||||
} else {
|
||||
MusicServe::storeData('sort_order', SORT_DESC);
|
||||
}
|
||||
self::sortFiles();
|
||||
}
|
||||
|
||||
static function openFile($file) {
|
||||
if (MusicServe::checkModule("Playlist")) {
|
||||
Playlist::addFile(MusicServe::getData('cwd').$file);
|
||||
}
|
||||
}
|
||||
|
||||
static function openFiles() {
|
||||
if (MusicServe::checkModule("Playlist")) {
|
||||
foreach(MusicServe::getData('files') as $file) {
|
||||
Playlist::addFile(MusicServe::getData('cwd').$file[FileBrowser::F_NAME]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* GENERAL FUNCTIONS */
|
||||
static function getFiles() {
|
||||
$directory = MusicServe::getData('cwd');
|
||||
if (!file_exists($directory)) {
|
||||
MusicServe::reportError(__CLASS__, __FUNCTION__,
|
||||
"Directory \"'.$directory.'\"does not exist!\n"
|
||||
);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$directory_handle = opendir($directory);
|
||||
$i = 0;
|
||||
while (false !== ($filename = readdir($directory_handle))) {
|
||||
if ($filename[0] != '.' && $filename != "..") {
|
||||
$files[$i] = array();
|
||||
if (is_dir($directory.$filename)) {
|
||||
$files[$i][FileBrowser::F_TYPE] = FileBrowser::T_DIR;
|
||||
} else {
|
||||
$files[$i][FileBrowser::F_TYPE] = FileBrowser::T_FILE;
|
||||
}
|
||||
$files[$i][FileBrowser::F_NAME] = $filename;
|
||||
$files[$i][FileBrowser::F_EXT] = pathinfo($filename, PATHINFO_EXTENSION);
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
MusicServe::storeData('dir_list', $files);
|
||||
}
|
||||
|
||||
/* INTERNAL FUNCTIONS */
|
||||
static function sortFiles() {
|
||||
$sort = array();
|
||||
$sort_by = MusicServe::getData('sort_by');
|
||||
$sort_order = MusicServe::getData('sort_order');
|
||||
$i = 0;
|
||||
if ($sort_by == "ext") {
|
||||
foreach (MusicServe::getData('dir_list') as $file) {
|
||||
$sort[$i++] = $file[FileBrowser::F_EXT];
|
||||
}
|
||||
} else {
|
||||
foreach (MusicServe::getData('dir_list') as $file) {
|
||||
$sort[$i++] = $file[FileBrowser::F_NAME];
|
||||
}
|
||||
}
|
||||
array_multisort($sort, $sort_order, MusicServe::getData('dir_list'));
|
||||
// Wasteful, but we want directories always on top
|
||||
$dirs = array();
|
||||
$files = array();
|
||||
foreach (MusicServe::getData('dir_list') as $file) {
|
||||
if ($file[FileBrowser::F_TYPE] == FileBrowser::T_DIR) {
|
||||
$dirs[] = $file;
|
||||
} else {
|
||||
$files[] = $file;
|
||||
}
|
||||
}
|
||||
MusicServe::storeData('files', $files);
|
||||
MusicServe::storeData('dirs', $dirs);
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,4 @@
|
|||
#ktk_MusicServe_Player {
|
||||
background-color: #111;
|
||||
height: 65%;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
namespace ktk\MusicServe;
|
||||
|
||||
class Player {
|
||||
static public function onInit() {
|
||||
}
|
||||
static public function onProcess() {
|
||||
}
|
||||
static public function onRender() {
|
||||
echo '<div id="ktk_MusicServe_Player">',PHP_EOL;
|
||||
echo "Player goes here";
|
||||
echo '</div>',PHP_EOL;
|
||||
}
|
||||
static public function onClose() {
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,10 @@
|
|||
#ktk_MusicServe_Playlist * {
|
||||
font-size: 10px;
|
||||
}
|
||||
#ktk_MusicServe_Playlist {
|
||||
background-color: #444;
|
||||
color: #BBA;
|
||||
height: 35%;
|
||||
overflow-y: auto;
|
||||
font-size: 12px;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
namespace ktk\MusicServe;
|
||||
|
||||
class Playlist {
|
||||
static private $playlist;
|
||||
static public function onInit() {
|
||||
if (!MusicServe::getData('playlist')) {
|
||||
MusicServe::storeData('playlist', array());
|
||||
}
|
||||
}
|
||||
static public function onProcess() {
|
||||
}
|
||||
static public function onRender() {
|
||||
echo ' <div id="ktk_MusicServe_Playlist">',PHP_EOL;
|
||||
foreach (MusicServe::getData('playlist') as $file) {
|
||||
echo $file.'<br />';
|
||||
}
|
||||
echo ' </div>',PHP_EOL;
|
||||
}
|
||||
static public function onClose() {
|
||||
}
|
||||
|
||||
static public function addFile($file) {
|
||||
MusicServe::getData('playlist')[] = $file;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
namespace ktk\MusicServe;
|
||||
|
||||
class TemplateModule {
|
||||
static public function onInit() {
|
||||
}
|
||||
static public function onProcess() {
|
||||
}
|
||||
static public function onRender() {
|
||||
}
|
||||
static public function onClose() {
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,5 @@
|
|||
#ktk_MusicServe_Devel {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
namespace ktk\MusicServe;
|
||||
|
||||
class Devel {
|
||||
static public function onRender() {
|
||||
echo '<div id="ktk_MusicServe_Devel">',PHP_EOL;
|
||||
echo '<form action="" method="POST">',PHP_EOL;
|
||||
echo '<input type="hidden" name="m" value="Devel" />',PHP_EOL;
|
||||
echo '<input type="submit" name="c" value="endSession" />',PHP_EOL;
|
||||
echo '</form>',PHP_EOL;
|
||||
echo '</div>',PHP_EOL;
|
||||
}
|
||||
static public function endSession() {
|
||||
if (ini_get("session.use_cookies")) {
|
||||
$params = session_get_cookie_params();
|
||||
setcookie(session_name(), '', time() - 42000,
|
||||
$params["path"], $params["domain"],
|
||||
$params["secure"], $params["httponly"]
|
||||
);
|
||||
session_destroy();
|
||||
header('Location: '.$_SERVER['PHP_SELF']);
|
||||
die;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
namespace ktk\MusicServe;
|
||||
|
||||
class SimpleClock {
|
||||
static private $time = "";
|
||||
static function onInit() {
|
||||
if (!SimpleDB::getData('time_format')) {
|
||||
SimpleDB::storeData('time_format', 'H:i:s');
|
||||
}
|
||||
}
|
||||
static function onProcess() {
|
||||
self::$time = date(SimpleDB::getData('time_format'));
|
||||
}
|
||||
static function onRender() {
|
||||
echo '<div id="ktk_MusicServe_Clock">'.PHP_EOL;
|
||||
echo self::$time.PHP_EOL;
|
||||
echo '<a href="?m=SimpleClock&c=changeTime&p1=g:i:s a">12-hour</a>'.PHP_EOL;
|
||||
echo '</div>'.PHP_EOL;
|
||||
}
|
||||
static function changeTime($format) {
|
||||
SimpleDB::storeData('time_format', $format);
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
namespace ktk\MusicServe;
|
||||
|
||||
class SimpleDB {
|
||||
static private $data_file = "sdb.ini";
|
||||
static private $data = array();
|
||||
// CORE
|
||||
static public function onInit() {
|
||||
if (!file_exists(self::$data_file)) {
|
||||
if ($fp = fopen(self::$data_file, 'w')) {
|
||||
fwrite($fp, "");
|
||||
fclose($fp);
|
||||
} else {
|
||||
MusicServe::reportError(__CLASS__, __FUNCTION__, "Could not create \"".self::$data_file."\", please check your permissions!");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
self::$data = parse_ini_file(self::$data_file, true);
|
||||
}
|
||||
static public function onClose() {
|
||||
if ($fp = fopen(self::$data_file, 'w')) {
|
||||
self::writeData_r($fp, self::$data);
|
||||
fclose($fp);
|
||||
} else {
|
||||
MusicServe::reportError(__CLASS__, __FUNCTION__, "Could not write to \"".self::$data_file."\", please check your permissions!");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
// ACCESS
|
||||
static public function getData($var) {
|
||||
if (self::$data[$var]) {
|
||||
return self::$data[$var];
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
static public function storeData($var, $value) {
|
||||
self::$data[$var] = $value;
|
||||
}
|
||||
// INTERNAL
|
||||
static private function writeData_r($handle, $data) {
|
||||
foreach ($data as $key=>$value) {
|
||||
if (is_array($value)) {
|
||||
fwrite($handle, '['.$key.']'.PHP_EOL);
|
||||
self::writeData_r($handle, $value);
|
||||
} else {
|
||||
fwrite($handle, $key.'='.$value.PHP_EOL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,7 @@
|
|||
#ktk_MusicServe_StyledClock {
|
||||
background-color: #222;
|
||||
color: #999;
|
||||
position: fixed;
|
||||
top:0;
|
||||
right:0;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
namespace ktk\MusicServe;
|
||||
|
||||
class StyledClock {
|
||||
static private $time = "";
|
||||
static function onInit() {
|
||||
if (!MusicServe::getData('time_format')) {
|
||||
MusicServe::storeData('time_format', 'H:i:s');
|
||||
}
|
||||
}
|
||||
static function onProcess() {
|
||||
self::$time = date(MusicServe::getData('time_format'));
|
||||
}
|
||||
static function onRender() {
|
||||
echo '<div id="ktk_MusicServe_StyledClock">'.PHP_EOL;
|
||||
echo self::$time.PHP_EOL;
|
||||
echo '<a href="?m=StyledClock&c=changeTime&p1=g:i:s a">12-hour</a>'.PHP_EOL;
|
||||
echo '</div>'.PHP_EOL;
|
||||
}
|
||||
static function changeTime($format) {
|
||||
MusicServe::storeData('time_format', $format);
|
||||
}
|
||||
}
|
||||
?>
|
Loading…
Reference in New Issue