mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Merge branch 'ph3-web'
Thanks to Marvin Scholz for all the great work!
This commit is contained in:
commit
b419a500ac
@ -4,17 +4,16 @@
|
||||
<xsl:variable name="title">Error</xsl:variable>
|
||||
|
||||
<xsl:template name="content">
|
||||
<div class="roundbox">
|
||||
<h2><xsl:value-of select="$title" /></h2>
|
||||
<xsl:for-each select="/report/incident">
|
||||
<div class="article">
|
||||
<h3>Response</h3>
|
||||
<section class="box">
|
||||
<h3 class="box_title">Response</h3>
|
||||
<h4>Message</h4>
|
||||
<p><xsl:value-of select="state/text" /></p>
|
||||
<xsl:if test="state/@definition">
|
||||
<p>Error code: <xsl:value-of select="state/@definition" /></p>
|
||||
</xsl:if>
|
||||
</div>
|
||||
</section>
|
||||
</xsl:for-each>
|
||||
</div>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
|
@ -5,7 +5,11 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title><xsl:if test="$title"><xsl:value-of select="$title"/> — </xsl:if>Icecast Admin</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/assets/css/style.css" />
|
||||
|
||||
<meta name="theme-color" content="#001826" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="description" content="Icecast Server status page" />
|
||||
</head>
|
||||
</xsl:template>
|
||||
|
@ -2,27 +2,24 @@
|
||||
<xsl:output method="html" doctype-system="about:legacy-compat" encoding="UTF-8" indent="yes" />
|
||||
<xsl:template name="header">
|
||||
|
||||
<div class="header">
|
||||
<h1>
|
||||
<a href="/" title="Home page">Icecast</a>
|
||||
<xsl:text> </xsl:text>
|
||||
<span>administration</span>
|
||||
</h1>
|
||||
<div class="nav">
|
||||
<label for="toggle-nav" class="nobar" title="Toggle navigation"></label>
|
||||
<input type="checkbox" id="toggle-nav" />
|
||||
<header>
|
||||
<nav id="main-nav" role="primary">
|
||||
<a href="/" id="branding">
|
||||
<img src="/assets/img/icecast.png" alt="Logo" />
|
||||
<h1>Icecast Server administration</h1>
|
||||
</a>
|
||||
<ul>
|
||||
<li class="on"><a href="/admin/stats.xsl">Administration</a></li>
|
||||
<li><a href="/admin/listmounts.xsl">Mountpoint list</a></li>
|
||||
<li class="adminlink"><a href="/admin/stats.xsl">Server status</a></li>
|
||||
<li class="adminlink"><a href="/admin/listmounts.xsl">Mountpoint list</a></li>
|
||||
<xsl:for-each select="(/report/extension/icestats | /icestats | /iceresponse)/modules/module">
|
||||
<xsl:if test="@management-url and @management-title">
|
||||
<li><a href="{@management-url}"><xsl:value-of select="@management-title" /></a></li>
|
||||
<li class="adminlink"><a href="{@management-url}"><xsl:value-of select="@management-title" /></a></li>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
<li><a href="/status.xsl">Public area</a></li>
|
||||
<li class="right"><a href="/status.xsl">Public area</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
@ -2,12 +2,13 @@
|
||||
<xsl:output method="html" doctype-system="about:legacy-compat" encoding="UTF-8" indent="yes" />
|
||||
<xsl:template name="mountnav">
|
||||
<xsl:param name="mount" select="@mount"/>
|
||||
<div class="nav">
|
||||
<ul>
|
||||
<div class="mountnav">
|
||||
<ul class="boxnav">
|
||||
<li><a href="stats.xsl?mount={$mount}#mount-1">Details</a></li>
|
||||
<li><a href="listclients.xsl?mount={$mount}">Clients</a></li>
|
||||
<li><a href="moveclients.xsl?mount={$mount}">Move listeners</a></li>
|
||||
<li><a href="updatemetadata.xsl?mount={$mount}">Metadata</a></li>
|
||||
<li><a href="killsource.xsl?mount={$mount}">Kill source</a></li>
|
||||
<li class="critical"><a href="killsource.xsl?mount={$mount}">Kill source</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
@ -16,10 +16,14 @@
|
||||
<!-- Header/Menu -->
|
||||
<xsl:call-template name="header" />
|
||||
|
||||
<main role="main">
|
||||
<xsl:call-template name="content" />
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer>
|
||||
<xsl:call-template name="footer" />
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
24
admin/includes/player.xsl
Normal file
24
admin/includes/player.xsl
Normal file
@ -0,0 +1,24 @@
|
||||
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0">
|
||||
<xsl:output method="html" doctype-system="about:legacy-compat" encoding="UTF-8" indent="yes" />
|
||||
<xsl:template name="player">
|
||||
<div>
|
||||
<ul class="playlists">
|
||||
<li><a href="{@mount}">Direct</a></li>
|
||||
<li><a href="{@mount}.m3u">M3U</a></li>
|
||||
<li><a href="{@mount}.xspf">XSPF</a></li>
|
||||
</ul>
|
||||
|
||||
<!-- Playlists section -->
|
||||
<h4>Play stream</h4>
|
||||
|
||||
<!-- Player -->
|
||||
<xsl:if test="content-type and ((content-type = 'application/ogg') or (content-type = 'audio/ogg') or (content-type = 'audio/webm'))">
|
||||
<div class="audioplayer">
|
||||
<audio controls="controls" preload="none">
|
||||
<source src="{@mount}" type="{content-type}" />
|
||||
</audio>
|
||||
</div>
|
||||
</xsl:if>
|
||||
</div>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
30
admin/includes/playlist.xsl
Normal file
30
admin/includes/playlist.xsl
Normal file
@ -0,0 +1,30 @@
|
||||
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0">
|
||||
<xsl:output method="html" doctype-system="about:legacy-compat" encoding="UTF-8" indent="yes" />
|
||||
<xsl:template name="playlist">
|
||||
<xsl:if test="playlist/*">
|
||||
<h4>Playlist</h4>
|
||||
<div class="playlist-container">
|
||||
<table class="table-block">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Album</th>
|
||||
<th width="10%">Track</th>
|
||||
<th>Creator</th>
|
||||
<th width="33%">Title</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<xsl:for-each select="playlist/trackList/track">
|
||||
<tr>
|
||||
<td><xsl:value-of select="album" /></td>
|
||||
<td><xsl:value-of select="trackNum" /></td>
|
||||
<td><xsl:value-of select="creator" /></td>
|
||||
<td><xsl:value-of select="title" /></td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
@ -5,25 +5,42 @@
|
||||
<xsl:template match="/node()">
|
||||
<html>
|
||||
<head>
|
||||
<title><xsl:value-of select="$title"/> — Icecast Streaming Media Server</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
<meta charset="utf-8" />
|
||||
<title><xsl:value-of select="$title"/> — Icecast Server</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/assets/css/style.css" media="screen, print" />
|
||||
|
||||
<meta name="theme-color" content="#001826" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<meta name="description" content="Icecast is free server software for streaming multimedia." />
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="header">Icecast <xsl:value-of select="$title"/></h1>
|
||||
<!--index header menu -->
|
||||
<div id="menu">
|
||||
<!-- Header and menu -->
|
||||
<header>
|
||||
<nav id="main-nav" role="primary">
|
||||
<a href="/" id="branding">
|
||||
<img src="/assets/img/icecast.png" alt="Logo" />
|
||||
<h1>Icecast Server</h1>
|
||||
</a>
|
||||
<ul>
|
||||
<li><a href="admin/">Administration</a></li>
|
||||
<li><a href="status.xsl">Server Status</a></li>
|
||||
<li><a href="server_version.xsl">Version</a></li>
|
||||
<li><a href="/status.xsl">Status</a></li>
|
||||
<li><a href="/server_version.xsl">Version</a></li>
|
||||
<li class="right adminlink"><a href="/admin/">Administration</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<!--end index header menu -->
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<!--<h1 id="header">Icecast <xsl:value-of select="$title"/></h1>-->
|
||||
|
||||
<!-- Content -->
|
||||
<main role="main">
|
||||
<xsl:call-template name="content" namespace="http://www.w3.org/1999/xhtml" />
|
||||
<div id="footer">
|
||||
Support icecast development at <a href="http://www.icecast.org">www.icecast.org</a>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer>
|
||||
<p>Support icecast development at <a href="http://icecast.org">icecast.org</a></p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
|
@ -11,10 +11,11 @@
|
||||
<h2><xsl:value-of select="$title" /></h2>
|
||||
|
||||
<xsl:for-each select="source">
|
||||
<div class="article">
|
||||
<h3>Mountpoint <xsl:value-of select="@mount" /></h3>
|
||||
<section class="box">
|
||||
<h3 class="box_title">Mountpoint <code><xsl:value-of select="@mount" /></code></h3>
|
||||
<!-- Mount nav -->
|
||||
<xsl:call-template name="mountnav" />
|
||||
<h4>Listeners</h4>
|
||||
<xsl:choose>
|
||||
<xsl:when test="listener">
|
||||
<table class="table-flipscroll">
|
||||
@ -25,7 +26,7 @@
|
||||
<th>Role</th>
|
||||
<th>Sec. connected</th>
|
||||
<th>User Agent</th>
|
||||
<th>Action</th>
|
||||
<th class="actions">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -36,9 +37,8 @@
|
||||
<td><xsl:value-of select="role" /></td>
|
||||
<td><xsl:value-of select="connected" /></td>
|
||||
<td><xsl:value-of select="useragent" /></td>
|
||||
<td>
|
||||
<a href="killclient.xsl?mount={../@mount}&id={id}">Kick</a>
|
||||
 
|
||||
<td class="actions">
|
||||
<a class="critical" href="killclient.xsl?mount={../@mount}&id={id}">Kick</a>
|
||||
<a href="moveclients.xsl?mount={../@mount}&id={id}">Move</a>
|
||||
</td>
|
||||
</tr>
|
||||
@ -50,7 +50,7 @@
|
||||
<p>No listeners connected</p>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</div>
|
||||
</section>
|
||||
</xsl:for-each>
|
||||
|
||||
</div>
|
||||
|
@ -3,6 +3,7 @@
|
||||
<!-- Import include files -->
|
||||
<xsl:include href="includes/page.xsl"/>
|
||||
<xsl:include href="includes/mountnav.xsl"/>
|
||||
<xsl:include href="includes/player.xsl"/>
|
||||
|
||||
<xsl:variable name="title">Active Mountpoints</xsl:variable>
|
||||
|
||||
@ -37,23 +38,11 @@
|
||||
<xsl:choose>
|
||||
<xsl:when test="source">
|
||||
<xsl:for-each select="source">
|
||||
<div class="article">
|
||||
<h3>Mountpoint <xsl:value-of select="@mount" /></h3>
|
||||
<section class="box">
|
||||
<h3 class="box_title">Mountpoint <code><xsl:value-of select="@mount" /></code></h3>
|
||||
<!-- Mount nav -->
|
||||
<xsl:call-template name="mountnav" />
|
||||
<h4>Play stream</h4>
|
||||
<xsl:choose>
|
||||
<xsl:when test="authenticator">
|
||||
<a class="play" href="/auth.xsl">Auth</a>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<a class="play" href="{@mount}.m3u">► <span>M3U</span></a>
|
||||
<xsl:text> </xsl:text>
|
||||
<a class="play" href="{@mount}.xspf">► <span>XSPF</span></a>
|
||||
<xsl:text> </xsl:text>
|
||||
<a class="play" href="{@mount}.vclt">► <span>VCLT</span></a>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:call-template name="player" />
|
||||
<p><xsl:value-of select="listeners" /> Listener(s)</p>
|
||||
|
||||
<!-- Mount Authentication -->
|
||||
@ -61,13 +50,13 @@
|
||||
<h4>Mount Authentication</h4>
|
||||
<xsl:call-template name="authlist" />
|
||||
</xsl:if>
|
||||
</div>
|
||||
</section>
|
||||
</xsl:for-each>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<div class="aside error">
|
||||
<aside class="info">
|
||||
<strong>No mounts!</strong> There are no active mountpoints.
|
||||
</div>
|
||||
</aside>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</div>
|
||||
|
@ -10,13 +10,13 @@
|
||||
<div class="section">
|
||||
<h2><xsl:value-of select="$title" /></h2>
|
||||
<xsl:if test="iceresponse">
|
||||
<div class="aside error">
|
||||
<aside class="error">
|
||||
<xsl:value-of select="iceresponse/message" />
|
||||
</div>
|
||||
</aside>
|
||||
</xsl:if>
|
||||
<xsl:for-each select="role">
|
||||
<div class="article">
|
||||
<h3>Role <xsl:value-of select="@name" /> (<xsl:value-of select="@type" />)
|
||||
<section class="box">
|
||||
<h3 class="box_title">Role <code><xsl:value-of select="@name" /></code> (<code><xsl:value-of select="@type" /></code>)
|
||||
<xsl:if test="server_name">
|
||||
<xsl:text> </xsl:text><small><xsl:value-of select="server_name" /></small>
|
||||
</xsl:if>
|
||||
@ -28,7 +28,7 @@
|
||||
<tr>
|
||||
<th>User</th>
|
||||
<xsl:if test="@can-deleteuser = 'true'">
|
||||
<th>Action</th>
|
||||
<th class="actions">Action</th>
|
||||
</xsl:if>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -37,8 +37,8 @@
|
||||
<tr>
|
||||
<td><xsl:value-of select="username" /></td>
|
||||
<xsl:if test="../../@can-deleteuser = 'true'">
|
||||
<td>
|
||||
<a href="manageauth.xsl?id={../../@id}&username={username}&action=delete">Delete</a>
|
||||
<td class="actions">
|
||||
<a class="critical" href="manageauth.xsl?id={../../@id}&username={username}&action=delete">Delete</a>
|
||||
</td>
|
||||
</xsl:if>
|
||||
</tr>
|
||||
@ -54,16 +54,19 @@
|
||||
<xsl:if test="@can-adduser = 'true'">
|
||||
<h4>Add User</h4>
|
||||
<form method="post" action="manageauth.xsl">
|
||||
<label for="username" class="hidden">Username</label>
|
||||
<input type="text" id="username" name="username" value="" placeholder="Username" required="required" />
|
||||
<label for="password" class="hidden">Password</label>
|
||||
<input type="password" id="password" name="password" value="" placeholder="Password" required="required" />
|
||||
<input type="hidden" name="id" value="{@id}"/>
|
||||
<input type="hidden" name="action" value="add"/>
|
||||
|
||||
<label for="username" class="hidden">Username: </label>
|
||||
<input type="text" id="username" name="username" value="" placeholder="Username" required="required" />
|
||||
 
|
||||
<label for="password" class="hidden">Password: </label>
|
||||
<input type="password" id="password" name="password" value="" placeholder="Password" required="required" />
|
||||
 
|
||||
<input type="submit" value="Add new user" />
|
||||
</form>
|
||||
</xsl:if>
|
||||
</div>
|
||||
</section>
|
||||
</xsl:for-each>
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
@ -9,8 +9,8 @@
|
||||
<xsl:template name="content">
|
||||
<div class="section">
|
||||
<h2><xsl:value-of select="$title" /></h2>
|
||||
<div class="article">
|
||||
<h3>Mountpoint <xsl:value-of select="current_source" /></h3>
|
||||
<section class="box">
|
||||
<h3 class="box_title">Mountpoint <code><xsl:value-of select="@mount" /></code></h3>
|
||||
<!-- Mount nav -->
|
||||
<xsl:call-template name="mountnav">
|
||||
<xsl:with-param name="mount" select="current_source"/>
|
||||
@ -38,17 +38,18 @@
|
||||
</xsl:for-each>
|
||||
</select>
|
||||
<input type="hidden" name="mount" value="{current_source}" />
|
||||
 
|
||||
<input type="submit" value="Move listeners" />
|
||||
</form>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<p>
|
||||
<aside class="warning">
|
||||
<strong>No mounts!</strong>
|
||||
There are no other mountpoints you could move the listeners to.
|
||||
</p>
|
||||
</aside>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
|
@ -6,16 +6,14 @@
|
||||
<xsl:variable name="title">Server Response</xsl:variable>
|
||||
|
||||
<xsl:template name="content">
|
||||
<div class="section">
|
||||
<h2><xsl:value-of select="$title" /></h2>
|
||||
<xsl:for-each select="/iceresponse">
|
||||
<div class="article">
|
||||
<h3>Response</h3>
|
||||
<section class="box">
|
||||
<h3 class="box_title">Response</h3>
|
||||
<h4>Message</h4>
|
||||
<p><xsl:value-of select="message" /></p>
|
||||
<p>(Return Code: <xsl:value-of select="return" />)</p>
|
||||
</div>
|
||||
</section>
|
||||
</xsl:for-each>
|
||||
</div>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
|
@ -3,8 +3,12 @@
|
||||
<!-- Import include files -->
|
||||
<xsl:include href="includes/page.xsl"/>
|
||||
<xsl:include href="includes/mountnav.xsl"/>
|
||||
<xsl:include href="includes/player.xsl"/>
|
||||
<xsl:include href="includes/playlist.xsl"/>
|
||||
|
||||
<xsl:variable name="title">Stats</xsl:variable>
|
||||
<xsl:param name="param-showall" />
|
||||
<xsl:param name="param-has-mount" />
|
||||
<xsl:variable name="title">Server status</xsl:variable>
|
||||
|
||||
<!-- Auth template -->
|
||||
<xsl:template name="authlist">
|
||||
@ -32,18 +36,21 @@
|
||||
|
||||
|
||||
<xsl:template name="content">
|
||||
<div class="section">
|
||||
<h2>Administration</h2>
|
||||
<h2>Server status</h2>
|
||||
|
||||
<!-- Global stats table -->
|
||||
<div class="article">
|
||||
<h3>Global server stats</h3>
|
||||
<section class="box">
|
||||
<h3 class="box_title">Global server stats</h3>
|
||||
<!-- Global subnav -->
|
||||
<div class="nav">
|
||||
<ul>
|
||||
<div class="stats">
|
||||
<ul class="boxnav">
|
||||
<li><a href="reloadconfig.xsl">Reload Configuration</a></li>
|
||||
<li><a href="?showall=true">Show all mounts</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h4>Statistics</h4>
|
||||
|
||||
<table class="table-block">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -52,7 +59,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<xsl:for-each select="/icestats/*[not(self::source) and not(self::authentication)]">
|
||||
<xsl:for-each select="/icestats/*[not(self::source) and not(self::authentication) and not(self::modules)]">
|
||||
<tr>
|
||||
<td><xsl:value-of select="name()" /></td>
|
||||
<td><xsl:value-of select="text()" /></td>
|
||||
@ -66,27 +73,16 @@
|
||||
<h4>Authentication</h4>
|
||||
<xsl:call-template name="authlist" />
|
||||
</xsl:if>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Mount stats -->
|
||||
<xsl:if test="$param-showall or $param-has-mount">
|
||||
<xsl:for-each select="source">
|
||||
<div class="article">
|
||||
<h3>Mountpoint <xsl:value-of select="@mount" /></h3>
|
||||
<section class="box" id="mount-{position()}">
|
||||
<h3 class="box_title">Mountpoint <code><xsl:value-of select="@mount" /></code></h3>
|
||||
<!-- Mount nav -->
|
||||
<xsl:call-template name="mountnav" />
|
||||
<h4>Play stream</h4>
|
||||
<xsl:choose>
|
||||
<xsl:when test="authenticator">
|
||||
<a class="play" href="/auth.xsl">Auth</a>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<a class="play" href="{@mount}.m3u">► <span>M3U</span></a>
|
||||
<xsl:text> </xsl:text>
|
||||
<a class="play" href="{@mount}.xspf">► <span>XSPF</span></a>
|
||||
<xsl:text> </xsl:text>
|
||||
<a class="play" href="{@mount}.vclt">► <span>VCLT</span></a>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:call-template name="player" />
|
||||
<h4>Further information</h4>
|
||||
<table class="table-block">
|
||||
<thead>
|
||||
@ -121,36 +117,16 @@
|
||||
</xsl:if>
|
||||
|
||||
<!-- Extra playlist -->
|
||||
<xsl:if test="playlist/*">
|
||||
<h4>Playlist</h4>
|
||||
<table class="table-block">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Album</th>
|
||||
<th>Track</th>
|
||||
<th>Creator</th>
|
||||
<th>Title</th>
|
||||
</tr>
|
||||
<xsl:for-each select="playlist/trackList/track">
|
||||
<tr>
|
||||
<td><xsl:value-of select="album" /></td>
|
||||
<td><xsl:value-of select="trackNum" /></td>
|
||||
<td><xsl:value-of select="creator" /></td>
|
||||
<td><xsl:value-of select="title" /></td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</tbody>
|
||||
</table>
|
||||
</xsl:if>
|
||||
<xsl:call-template name="playlist" />
|
||||
|
||||
<!-- Mount Authentication -->
|
||||
<xsl:if test="authentication">
|
||||
<xsl:if test="authentication/*">
|
||||
<h4>Mount Authentication</h4>
|
||||
<xsl:call-template name="authlist" />
|
||||
</xsl:if>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
</xsl:for-each>
|
||||
</div>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
|
@ -11,19 +11,28 @@
|
||||
<h2><xsl:value-of select="$title" /></h2>
|
||||
|
||||
<xsl:for-each select="source">
|
||||
<div class="article">
|
||||
<h3>Mountpoint <xsl:value-of select="@mount" /></h3>
|
||||
<section class="box">
|
||||
<h3 class="box_title">Mountpoint <code><xsl:value-of select="@mount" /></code></h3>
|
||||
<!-- Mount nav -->
|
||||
<xsl:call-template name="mountnav" />
|
||||
<h4>Update Metadata</h4>
|
||||
<xsl:if test="content-type and not((content-type = 'application/mpeg') or (content-type = 'audio/aac') or (content-type = 'audio/aacp'))">
|
||||
<aside class="warning">
|
||||
<strong>Warning</strong>
|
||||
This is only supported for legacy codecs using ICY as transport such as MP3 and AAC.
|
||||
</aside>
|
||||
</xsl:if>
|
||||
<form method="post" action="/admin/metadata.xsl">
|
||||
<label for="metadata" class="hidden">Metadata</label>
|
||||
<input type="text" id="metadata" name="song" value="" placeholder="Click to edit" required="required" />
|
||||
<input type="hidden" name="mount" value="{@mount}" />
|
||||
<input type="hidden" name="mode" value="updinfo" />
|
||||
<input type="hidden" name="charset" value="UTF-8" />
|
||||
|
||||
<label for="metadata" class="hidden">Metadata:</label>
|
||||
<input type="text" id="metadata" name="song" value="" placeholder="Click to edit" required="required" />
|
||||
 
|
||||
<input type="submit" value="Update Metadata" />
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</xsl:for-each>
|
||||
|
||||
</div>
|
||||
|
17
src/admin.c
17
src/admin.c
@ -462,6 +462,8 @@ void admin_send_response(xmlDocPtr doc,
|
||||
char *fullpath_xslt_template;
|
||||
size_t fullpath_xslt_template_len;
|
||||
ice_config_t *config = config_get_config();
|
||||
const char *showall;
|
||||
const char *mount;
|
||||
|
||||
fullpath_xslt_template_len = strlen(config->adminroot_dir) + strlen(xslt_template) + strlen(PATH_SEPARATOR) + 1;
|
||||
fullpath_xslt_template = malloc(fullpath_xslt_template_len);
|
||||
@ -470,7 +472,17 @@ void admin_send_response(xmlDocPtr doc,
|
||||
config_release_config();
|
||||
|
||||
ICECAST_LOG_DEBUG("Sending XSLT (%s)", fullpath_xslt_template);
|
||||
xslt_transform(doc, fullpath_xslt_template, client, 200, NULL);
|
||||
|
||||
COMMAND_OPTIONAL(client, "showall", showall);
|
||||
COMMAND_OPTIONAL(client, "mount", mount);
|
||||
|
||||
if (showall && util_str_to_bool(showall)) {
|
||||
const char *params[] = {"param-has-mount", mount ? "'true'" : NULL, "param-showall", "'true'", NULL};
|
||||
xslt_transform(doc, fullpath_xslt_template, client, 200, NULL, params);
|
||||
} else {
|
||||
const char *params[] = {"param-has-mount", mount ? "'true'" : NULL, "param-showall", NULL, NULL};
|
||||
xslt_transform(doc, fullpath_xslt_template, client, 200, NULL, params);
|
||||
}
|
||||
free(fullpath_xslt_template);
|
||||
}
|
||||
}
|
||||
@ -1238,6 +1250,9 @@ static void command_updatemetadata(client_t *client,
|
||||
node = admin_build_rootnode(doc, "icestats");
|
||||
srcnode = xmlNewChild(node, NULL, XMLSTR("source"), NULL);
|
||||
xmlSetProp(srcnode, XMLSTR("mount"), XMLSTR(source->mount));
|
||||
if (source->running) {
|
||||
xmlNewTextChild(srcnode, NULL, XMLSTR("content-type"), XMLSTR(source->format->contenttype));
|
||||
}
|
||||
xmlDocSetRootElement(doc, node);
|
||||
|
||||
admin_send_response(doc, client, response,
|
||||
|
@ -642,7 +642,7 @@ void client_send_reportxml(client_t *client, reportxml_t *report, document_domai
|
||||
|
||||
ICECAST_LOG_DEBUG("Sending XSLT (%s)", fullpath_xslt_template);
|
||||
fastevent_emit(FASTEVENT_TYPE_CLIENT_SEND_RESPONSE, FASTEVENT_FLAG_MODIFICATION_ALLOWED, FASTEVENT_DATATYPE_CLIENT, client);
|
||||
xslt_transform(doc, fullpath_xslt_template, client, status, location);
|
||||
xslt_transform(doc, fullpath_xslt_template, client, status, location, NULL);
|
||||
free(fullpath_xslt_template);
|
||||
}
|
||||
|
||||
|
@ -903,6 +903,9 @@ static xmlNodePtr _dump_stats_to_doc (xmlNodePtr root, const char *show_mount, i
|
||||
for (i = 0; i < source_real->format->vc.comments; i++)
|
||||
__add_metadata(metadata, source_real->format->vc.user_comments[i]);
|
||||
}
|
||||
|
||||
if (source_real->running)
|
||||
xmlNewTextChild(xmlnode, NULL, XMLSTR("content-type"), XMLSTR(source_real->format->contenttype));
|
||||
}
|
||||
avl_tree_unlock(global.source_tree);
|
||||
|
||||
@ -1050,7 +1053,7 @@ void stats_transform_xslt(client_t *client)
|
||||
|
||||
doc = stats_get_xml(0, mount, client);
|
||||
|
||||
xslt_transform(doc, xslpath, client, 200, NULL);
|
||||
xslt_transform(doc, xslpath, client, 200, NULL, NULL);
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
free(xslpath);
|
||||
|
@ -320,7 +320,7 @@ static inline void _send_error(client_t *client, icecast_error_id_t id, int old_
|
||||
client_send_error_by_id(client, id);
|
||||
}
|
||||
|
||||
void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client, int status, const char *location)
|
||||
void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client, int status, const char *location, const char **params)
|
||||
{
|
||||
xmlDocPtr res;
|
||||
xsltStylesheetPtr cur;
|
||||
@ -344,7 +344,7 @@ void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client, in
|
||||
return;
|
||||
}
|
||||
|
||||
res = xsltApplyStylesheet(cur, doc, NULL);
|
||||
res = xsltApplyStylesheet(cur, doc, params);
|
||||
if (res != NULL) {
|
||||
if (xsltSaveResultToString(&string, &len, res, cur) < 0)
|
||||
problem = 1;
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#include "icecasttypes.h"
|
||||
|
||||
void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client, int status, const char *location);
|
||||
void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client, int status, const char *location, const char **params);
|
||||
void xslt_initialize(void);
|
||||
void xslt_shutdown(void);
|
||||
void xslt_clear_cache(void);
|
||||
|
@ -4,28 +4,13 @@ webdir = $(pkgdatadir)/web
|
||||
|
||||
nobase_web_DATA = \
|
||||
status.xsl \
|
||||
favicon.ico \
|
||||
icecast.png \
|
||||
style.css \
|
||||
auth.xsl \
|
||||
server_version.xsl \
|
||||
tunein.png \
|
||||
key.png \
|
||||
status-json.xsl \
|
||||
xml2json.xslt \
|
||||
favicon.ico \
|
||||
assets/css/style.css \
|
||||
assets/font/FiraMono-Bold.eot \
|
||||
assets/font/FiraMono-Regular.eot \
|
||||
assets/font/FiraSans-Bold.eot \
|
||||
assets/font/FiraSans-BoldItalic.woff \
|
||||
assets/font/FiraSans-Italic.eot \
|
||||
assets/font/FiraSans-Regular.eot \
|
||||
assets/font/FiraMono-Bold.woff \
|
||||
assets/font/FiraMono-Regular.woff \
|
||||
assets/font/FiraSans-BoldItalic.eot \
|
||||
assets/font/FiraSans-Bold.woff \
|
||||
assets/font/FiraSans-Italic.woff \
|
||||
assets/font/FiraSans-Regular.woff
|
||||
assets/img/icecast.png
|
||||
|
||||
|
||||
EXTRA_DIST = $(nobase_web_DATA)
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.9 KiB |
BIN
web/key.png
BIN
web/key.png
Binary file not shown.
Before Width: | Height: | Size: 2.2 KiB |
@ -3,9 +3,10 @@
|
||||
<xsl:include href="includes/web-page.xsl"/>
|
||||
<xsl:variable name="title">Server Information</xsl:variable>
|
||||
<xsl:template name="content">
|
||||
<div class="roundbox">
|
||||
<h3>Server Information</h3>
|
||||
<table class="yellowkeys">
|
||||
<h2>Version</h2>
|
||||
<section class="box">
|
||||
<h3 class="box_title">Server Information</h3>
|
||||
<table class="table-keys">
|
||||
<tbody>
|
||||
<xsl:for-each select="/icestats">
|
||||
<tr>
|
||||
@ -27,26 +28,26 @@
|
||||
</xsl:for-each>
|
||||
<tr>
|
||||
<td>Download</td>
|
||||
<td><a href="http://icecast.org/download.php">icecast.org</a></td>
|
||||
<td><a href="https://icecast.org/download/">icecast.org/download/</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Subversion</td>
|
||||
<td><a href="http://icecast.org/svn.php">icecast.org/svn.php</a></td>
|
||||
<td>Git</td>
|
||||
<td><a href="https://icecast.org/download/#git">icecast.org/download/#git</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Documentation</td>
|
||||
<td><a href="http://icecast.org/docs.php">icecast.org/docs.php</a></td>
|
||||
<td><a href="https://icecast.org/docs/">icecast.org/docs/</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Stream Directory</td>
|
||||
<td><a href="http://dir.xiph.org/index.php">dir.xiph.org</a></td>
|
||||
<td><a href="https://dir.xiph.org/">dir.xiph.org</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Community</td>
|
||||
<td><a href="http://icecast.org/community.php">icecast.org/community.php</a></td>
|
||||
<td><a href="https://icecast.org/contact/">icecast.org/contact/</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
|
@ -1,6 +1,8 @@
|
||||
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<xsl:output omit-xml-declaration="no" method="xml" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" indent="yes" encoding="UTF-8" />
|
||||
<xsl:include href="includes/web-page.xsl"/>
|
||||
<xsl:include href="includes/player.xsl"/>
|
||||
<xsl:include href="includes/playlist.xsl"/>
|
||||
<xsl:variable name="title">Status</xsl:variable>
|
||||
<xsl:template name="content">
|
||||
<xsl:text disable-output-escaping="yes">
|
||||
@ -13,36 +15,20 @@
|
||||
-->
|
||||
</xsl:text>
|
||||
<!--mount point stats-->
|
||||
<h2>Status</h2>
|
||||
<xsl:choose>
|
||||
<xsl:when test="source">
|
||||
<xsl:for-each select="source">
|
||||
<xsl:choose>
|
||||
<xsl:when test="listeners">
|
||||
<div class="roundbox">
|
||||
<div class="mounthead">
|
||||
<h3 class="mount">Mount Point <xsl:value-of select="@mount" /></h3>
|
||||
<div class="right">
|
||||
<xsl:choose>
|
||||
<xsl:when test="authenticator">
|
||||
<a class="auth" href="/auth.xsl">Login</a>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<ul class="mountlist">
|
||||
<li><a class="play" href="{@mount}.m3u">M3U</a></li>
|
||||
<li><a class="play" href="{@mount}.xspf">XSPF</a></li>
|
||||
<!-- <li><a class="play" href="{@mount}.vclt">VCLT</a></li> -->
|
||||
</ul>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</div>
|
||||
</div>
|
||||
<section class="box">
|
||||
<h3 class="box_title">Mountpoint <code><xsl:value-of select="@mount" /></code></h3>
|
||||
<xsl:call-template name="player" />
|
||||
|
||||
<!-- Stream info and stats -->
|
||||
<h4>Further information</h4>
|
||||
<div class="mountcont">
|
||||
<xsl:if test="server_type and ((server_type = 'application/ogg') or (server_type = 'audio/ogg') or (server_type = 'audio/webm'))">
|
||||
<div class="audioplayer">
|
||||
<audio controls="controls" preload="none">
|
||||
<source src="{@mount}" type="{server_type}" />
|
||||
</audio>
|
||||
</div>
|
||||
</xsl:if>
|
||||
<table class="yellowkeys">
|
||||
<table class="table-keys">
|
||||
<tbody>
|
||||
<xsl:if test="server_name">
|
||||
<tr>
|
||||
@ -136,34 +122,21 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- Extra playlist -->
|
||||
<xsl:if test="playlist/*">
|
||||
<h4>Playlist</h4>
|
||||
<table class="table-block">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Album</th>
|
||||
<th>Track</th>
|
||||
<th>Creator</th>
|
||||
<th>Title</th>
|
||||
</tr>
|
||||
<xsl:for-each select="playlist/trackList/track">
|
||||
<tr>
|
||||
<td><xsl:value-of select="album" /></td>
|
||||
<td><xsl:value-of select="trackNum" /></td>
|
||||
<td><xsl:value-of select="creator" /></td>
|
||||
<td><xsl:value-of select="title" /></td>
|
||||
</tr>
|
||||
</xsl:for-each>
|
||||
</tbody>
|
||||
</table>
|
||||
</xsl:if>
|
||||
</div>
|
||||
<xsl:call-template name="playlist" />
|
||||
</div>
|
||||
</section>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<h3><xsl:value-of select="@mount" /> - Not Connected</h3>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:for-each>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<aside class="info">
|
||||
<strong>No mounts!</strong> There are no active mountpoints.
|
||||
</aside>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
|
274
web/style.css
274
web/style.css
@ -1,274 +0,0 @@
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 0 25px 0 50px;
|
||||
background-color: #000;
|
||||
font-family: Verdana, sans-serif;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #f8ef64;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted #f8ef64;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #f8ef64;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid #f8ef64;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: Verdana, sans-serif;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
font-size: 3em;
|
||||
color: #fff;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
font-family: Verdana, sans-serif;
|
||||
font-weight: bold;
|
||||
font-size: 110%;
|
||||
color: #f8ef64;
|
||||
}
|
||||
|
||||
h1#header{
|
||||
padding: 10px 0px 10px 80px;
|
||||
background: transparent url(/icecast.png) no-repeat scroll left center;
|
||||
}
|
||||
|
||||
h3 small {
|
||||
color: #fff;
|
||||
font-size: 70%;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
form.alignedform label {
|
||||
text-align: right;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 10em;
|
||||
margin: 0 1em 0 0;
|
||||
}
|
||||
|
||||
form.alignedform input {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
border: 1px solid #f8ef64;
|
||||
background-color: #333;
|
||||
color: #f8ef64;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#menu {
|
||||
border-top: 3px solid #7B96C6;
|
||||
border-bottom: 3px solid #7B96C6;
|
||||
text-align: center;
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
|
||||
#menu ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#menu ul li {
|
||||
float: left;
|
||||
padding-left: 25px;
|
||||
padding-right: 25px;
|
||||
}
|
||||
|
||||
#menu ul li a {
|
||||
font-family: Verdana, sans-serif;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#menu ul li a:hover {
|
||||
color: #f8ef64;
|
||||
}
|
||||
|
||||
.roundbox {
|
||||
width: 90%;
|
||||
background-color: #656565;
|
||||
border-radius: 10px;
|
||||
padding: 15px 20px;
|
||||
margin-bottom: 35px;
|
||||
}
|
||||
|
||||
.roundbox h3 {
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px groove #ACACAC;
|
||||
}
|
||||
|
||||
.roundbox table.yellowkeys tr td:last-child {
|
||||
color: #f8ef64;
|
||||
}
|
||||
|
||||
table.colortable {
|
||||
border-collapse: collapse;
|
||||
padding: 20px 0 20px 0;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
table.colortable td {
|
||||
border: 1px solid #000;
|
||||
text-align: center;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
table.colortable thead tr td {
|
||||
color: #656565;
|
||||
background: #f8ef64;
|
||||
border-color: white;
|
||||
}
|
||||
|
||||
.roundbox table.yellowkeys tr td {
|
||||
padding: 5px 5px 0 0;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.mounthead h3 {
|
||||
float: left;
|
||||
margin-bottom: 0px;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.mountcont {
|
||||
border-top: 1px groove #ACACAC;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
ul.mountlist {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.mountlist li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
a.play {
|
||||
padding-left: 22px;
|
||||
margin-left: 25px;
|
||||
border: none;
|
||||
background: transparent url(/tunein.png) no-repeat scroll left center;
|
||||
background-size: auto 100%;
|
||||
}
|
||||
|
||||
a.auth {
|
||||
padding-left: 22px;
|
||||
margin-left: 25px;
|
||||
border: none;
|
||||
background: transparent url(/key.png) no-repeat scroll left top;
|
||||
background-size: auto 100%;
|
||||
}
|
||||
|
||||
/* Admin navigation */
|
||||
|
||||
ul.nav {
|
||||
margin: 0;
|
||||
padding: 5px 0 10px 0;
|
||||
clear: both;
|
||||
list-style: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
ul.nav li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
ul.nav li a {
|
||||
border: none;
|
||||
display: inline-block;
|
||||
padding: .2em .7em;
|
||||
margin-top: .2em;
|
||||
background-color: #333;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
ul.nav li a:hover {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
|
||||
#footer {
|
||||
border-top: 1px groove #ACACAC;
|
||||
margin-top: 20px;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
|
||||
body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.roundbox {
|
||||
width: auto;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.roundbox table.yellowkeys tr td {
|
||||
display: block;
|
||||
padding: 5px 5px 0 0;
|
||||
}
|
||||
|
||||
.roundbox table.yellowkeys tr td:last-child {
|
||||
margin-bottom: 5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.scrolltable {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 320px) {
|
||||
|
||||
ul.nav, #menu ul {
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul.nav li, #menu ul li {
|
||||
float: none;
|
||||
}
|
||||
|
||||
ul.nav li a, #menu ul li a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
ul.nav li + li, #menu ul li + li {
|
||||
border-top: 1px solid #ACACAC;
|
||||
}
|
||||
|
||||
a.play {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
}
|
||||
|
BIN
web/tunein.png
BIN
web/tunein.png
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB |
Loading…
Reference in New Issue
Block a user