3
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
public/images/thumbnails/
|
||||
server/views/assets/images/thumbnails/
|
||||
server/node_modules/
|
||||
node_modules/
|
||||
scripts/
|
||||
.DS_Store
|
||||
|
||||
62
.htaccess
@@ -1,62 +0,0 @@
|
||||
Options +FollowSymLinks
|
||||
RewriteEngine on
|
||||
RewriteBase /
|
||||
|
||||
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
|
||||
RewriteCond %{HTTP_HOST} ^zoff.me
|
||||
RewriteCond %{HTTPS} !=on
|
||||
RewriteRule ^(.*)$ https://zoff.me/$1 [L]
|
||||
|
||||
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
|
||||
RewriteCond %{HTTP_HOST} ^zoff.me
|
||||
RewriteRule ^(.*)$ https://zoff.me/$1 [L]
|
||||
|
||||
RewriteCond %{HTTP_HOST} ^(.*zoff.me.*)$
|
||||
RewriteCond %{HTTPS} !=on
|
||||
RewriteRule ^/?(.*) https://zoff.me/$1 [L]
|
||||
|
||||
#RewriteCond %{HTTP_HOST} ^zoff.no
|
||||
#RewriteRule ^/?(.*) https://zoff.me/$1 [L]
|
||||
|
||||
RewriteCond %{HTTP_HOST} ^remote.zoff.no
|
||||
RewriteRule ^/?(.*) https://remote.zoff.me/$1 [L]
|
||||
|
||||
RewriteCond %{HTTP_HOST} ^remote.zoff.me
|
||||
RewriteCond %{REQUEST_URI} !/public/css
|
||||
RewriteCond %{REQUEST_URI} !/public/js
|
||||
RewriteCond %{REQUEST_URI} !/public/dist
|
||||
RewriteCond %{REQUEST_URI} !/public/images
|
||||
RewriteCond %{REQUEST_URI} !/public/font
|
||||
RewriteRule ^(.*)$ public/php/controller.php [L,NC,QSA]
|
||||
|
||||
RewriteCond %{HTTP_HOST} ^bot.zoff.me
|
||||
|
||||
RewriteRule ^(.*)$ /public/php/bot.php [L,NC,QSA]
|
||||
|
||||
RewriteCond %{HTTP_HOST} ^zoff.me
|
||||
RewriteCond %{REQUEST_URI} /o_callback
|
||||
RewriteRule ^(.*)$ public/html/callback.html [L,NC,QSA]
|
||||
|
||||
RewriteCond %{HTTP_HOST} ^zoff.me
|
||||
RewriteCond %{REQUEST_URI} /_embed
|
||||
RewriteRule ^(.*)$ public/html/embed.html [L,NC,QSA]
|
||||
|
||||
RewriteCond %{HTTP_HOST} ^localhost
|
||||
RewriteCond %{REQUEST_URI} /o_callback
|
||||
RewriteRule ^(.*)$ /public/html/callback.html [L,NC,QSA]
|
||||
|
||||
RewriteCond %{HTTP_HOST} ^localhost
|
||||
RewriteCond %{REQUEST_URI} /_embed
|
||||
RewriteRule ^(.*)$ /public/html/embed.html [L,NC,QSA]
|
||||
|
||||
#RewriteRule (?i)^remote/(.*) /public/php/controller.php?id=$1 [L]
|
||||
#RewriteRule (?i)^remote /public/php/controller.php [L]
|
||||
|
||||
RewriteCond %{REQUEST_URI} !(/$|\.)
|
||||
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L]
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule /(.*)$ /$1 [L]
|
||||
|
||||
Options -Indexes
|
||||
30
gulpfile.js
@@ -4,65 +4,65 @@ var gulp = require('gulp'),
|
||||
concat = require('gulp-concat');
|
||||
|
||||
gulp.task('js', function () {
|
||||
gulp.src(['public/js/*.js', '!public/js/embed*', '!public/js/remotecontroller.js', '!public/js/callback.js'])
|
||||
gulp.src(['server/views/assets/js/*.js', '!server/views/assets/js/embed*', '!server/views/assets/js/remotecontroller.js', '!server/views/assets/js/callback.js'])
|
||||
.pipe(uglify({
|
||||
mangle: true,
|
||||
compress: true,
|
||||
enclose: true
|
||||
}))
|
||||
.pipe(concat('main.min.js'))
|
||||
.pipe(gulp.dest('public/dist'));
|
||||
.pipe(gulp.dest('server/views/assets/dist'));
|
||||
});
|
||||
|
||||
gulp.task('embed', function () {
|
||||
gulp.src(['public/js/player.js', 'public/js/helpers.js', 'public/js/playercontrols.js', 'public/js/list.js', 'public/js/embed.js', '!public/js/frontpage*', '!public/js/remotecontroller.js'])
|
||||
gulp.src(['server/views/assets/js/player.js', 'server/views/assets/js/helpers.js', 'server/views/assets/js/playercontrols.js', 'server/views/assets/js/list.js', 'server/views/assets/js/embed.js', '!server/views/assets/js/frontpage*', '!server/views/assets/js/remotecontroller.js'])
|
||||
.pipe(uglify({
|
||||
mangle: true,
|
||||
compress: true,
|
||||
enclose: true
|
||||
}))
|
||||
.pipe(concat('embed.min.js'))
|
||||
.pipe(gulp.dest('public/dist'));
|
||||
.pipe(gulp.dest('server/views/assets/dist'));
|
||||
});
|
||||
|
||||
gulp.task('callback', function () {
|
||||
gulp.src(['public/js/callback.js'])
|
||||
gulp.src(['server/views/assets/js/callback.js'])
|
||||
.pipe(uglify({
|
||||
mangle: true,
|
||||
compress: true,
|
||||
enclose: true
|
||||
}))
|
||||
.pipe(concat('callback.min.js'))
|
||||
.pipe(gulp.dest('public/dist'));
|
||||
.pipe(gulp.dest('server/views/assets/dist'));
|
||||
});
|
||||
|
||||
/*
|
||||
gulp.task('nochan', function () {
|
||||
gulp.src(['public/js/nochan.js', 'public/js/helpers.js'])
|
||||
gulp.src(['server/views/assets/js/nochan.js', 'server/views/assets/js/helpers.js'])
|
||||
.pipe(uglify({
|
||||
mangle: true,
|
||||
compress: true,
|
||||
enclose: true
|
||||
}))
|
||||
.pipe(concat('frontpage.min.js'))
|
||||
.pipe(gulp.dest('public/dist'));
|
||||
.pipe(gulp.dest('server/views/assets/dist'));
|
||||
});*/
|
||||
|
||||
gulp.task('remotecontroller', function () {
|
||||
gulp.src(['public/js/remotecontroller.js'])
|
||||
gulp.src(['server/views/assets/js/remotecontroller.js'])
|
||||
.pipe(uglify({
|
||||
mangle: true,
|
||||
compress: true,
|
||||
enclose: true
|
||||
}))
|
||||
.pipe(concat('remote.min.js'))
|
||||
.pipe(gulp.dest('public/dist'));
|
||||
.pipe(gulp.dest('server/views/assets/dist'));
|
||||
});
|
||||
|
||||
gulp.task('default', function(){
|
||||
gulp.watch('public/js/*.js', ['js']);
|
||||
gulp.watch('public/js/*.js', ['embed']);
|
||||
gulp.watch(['public/js/callback.js', 'public/js/helpers.js'], ['callback']);
|
||||
//gulp.watch('public/js/*.js', ['nochan']);
|
||||
gulp.watch('public/js/remotecontroller.js', ['remotecontroller']);
|
||||
gulp.watch('server/views/assets/js/*.js', ['js']);
|
||||
gulp.watch('server/views/assets/js/*.js', ['embed']);
|
||||
gulp.watch(['server/views/assets/js/callback.js', 'server/views/assets/js/helpers.js'], ['callback']);
|
||||
//gulp.watch('server/views/assets/js/*.js', ['nochan']);
|
||||
gulp.watch('server/views/assets/js/remotecontroller.js', ['remotecontroller']);
|
||||
});
|
||||
|
||||
10
index.php
@@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<?php
|
||||
$guid=substr(base64_encode(crc32($_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_ACCEPT_LANGUAGE'])), 0, 8);
|
||||
if(isset($_GET['chan'])) {header('Location: '.$_GET['chan']); exit;}
|
||||
//if(isset($_GET['__mref']) || isset($_GET['fb_source']) || isset($_GET['ref']) || isset($_GET['fref'])) {}
|
||||
else if(count($_GET) > 0 || $_SERVER['REQUEST_URI'] == "/?"){header('Location: /'); exit;}
|
||||
$list = explode("/", htmlspecialchars(strtolower($_SERVER["REQUEST_URI"])));
|
||||
if($list[1]==""||!isset($list[1])||count($list)<=1){$list="";include('public/php/frontpage.php');die();}
|
||||
else{$list=preg_replace("/[^A-Za-z0-9 ]/", '', $list[1]);include('public/php/channel.php');die();}
|
||||
?>
|
||||
2
public/dist/embed.min.js
vendored
4
public/dist/main.min.js
vendored
@@ -1,112 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
|
||||
<?php include("header.php"); ?>
|
||||
</head>
|
||||
<body class="noselect cursor-default">
|
||||
<header>
|
||||
<nav id="fp-nav">
|
||||
<div class="nav-wrapper">
|
||||
<a href="/" class="brand-logo brand-logo-navigate hide-on-med-and-down noselect">
|
||||
<img id="zicon" src="public/images/z.svg" alt="zoff" title="Zoff" />
|
||||
</a>
|
||||
<div class="brand-logo truncate zbrand">
|
||||
<a href="/" class="hide-on-large-only brand-logo-navigate">
|
||||
<img id="zicon" src="public/images/z.svg" alt="zoff" title="Zoff" />
|
||||
</a>
|
||||
</div>
|
||||
<ul class="right hide-on-med-and-down">
|
||||
<li><a class="waves-effect green" title="Remote control a Zoff player" href="https://remote.zoff.me">Remote</a></li>
|
||||
<li><a class="modal-trigger waves-effect waves-orange" onclick="$('#about').modal('open')">About</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
<div id="about" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>About</h4>
|
||||
<p>Zoff is a shared (free) YouTube based radio service, built upon the YouTube API. <br><br>
|
||||
Zoff is mainly a web-based service. The website uses NodeJS with Socket.IO, MongoDB and PHP on the backend, with JavaScript, jQuery and Materialize on the frontend.<br><br>
|
||||
The team consists of Kasper Rynning-Tønnesen and Nicolas Almagro Tonne, and the project has been worked on since late 2014.<br><br>
|
||||
|
||||
</p>
|
||||
<h4>Legal</h4>
|
||||
<p>Copyright © 2017 <br>Nicolas Almagro Tonne and Kasper Rynning-Tønnesen
|
||||
<br><br>
|
||||
Creative Commons License<br>
|
||||
Zoff is licensed under a <br><a href="http://creativecommons.org/licenses/by-nc-nd/3.0/no/">Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Norway License.</a>
|
||||
<br>
|
||||
Do not redistribute without permission from the developers.
|
||||
<br>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#!" class=" modal-action modal-close waves-effect waves-green btn-flat">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="help" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Help</h4>
|
||||
<p>To remote-control a computer, just type in the ID for that computer. (This can be found in the settings panel on the computer you want to remote control. There is also a QR code for you to scan.</p>
|
||||
<p>When you've entered the ID for the computer you want to control, you'll be able to change the volume, have the controled computer vote for skipping, pause the video or play the video.</p>
|
||||
<p>The input field you used to enter the ID (if you entered it), has now changed some. If you type in something here now, the controled computer will change channel!</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#!" class=" modal-action modal-close waves-effect waves-green btn-flat">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="center-align container remote-container">
|
||||
<div class="section">
|
||||
<h3 id="remote-text">Remote Controller</h3>
|
||||
</div>
|
||||
<div class="section">
|
||||
<form action="#" class="row" id="remoteform">
|
||||
<div class="input-field col s12">
|
||||
<input
|
||||
class="input-field"
|
||||
type="text"
|
||||
id="search"
|
||||
name="chan"
|
||||
title="Type channel name here to create or listen to a channel. Only alphanumerical chars. [a-zA-Z0-9]+"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
maxlength="10"
|
||||
data-length="10"
|
||||
/>
|
||||
<label for="search" id="forsearch">Type ID of host to be controlled</label>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="rc" id="remote-controls">
|
||||
<a id="playbutton" class="remote-button chan-link waves-effect btn green">
|
||||
<i id="remote_play" class="material-icons">play_arrow</i>
|
||||
</a>
|
||||
<a id="pausebutton" class="remote-button chan-link waves-effect btn gray">
|
||||
<i id="remote_pause" class="material-icons">pause</i>
|
||||
</a>
|
||||
<a id="skipbutton" class="remote-button chan-link waves-effect btn blue">
|
||||
<i id="remote_skip" class="material-icons">skip_next</i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="volume-elements">
|
||||
<div class="rc" id="volume-control" title="Volume"></div>
|
||||
<i class="material-icons slider-vol rc">volume_up</i>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="section about-remote">
|
||||
<b>Here you can control another Zoff player from any device.</b>
|
||||
<br>
|
||||
To find the ID of your player, click the Conf <i class="material-icons">menu</i> icon on the top right of the player page, then "Remote Control".
|
||||
<br>You can either scan the QR code or type the ID manually.
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php include("footer.php"); ?>
|
||||
|
||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js"></script>
|
||||
<script type="text/javascript" src="/public/dist/remote.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,136 +0,0 @@
|
||||
<div id="contact" class="modal">
|
||||
<div class="modal-content">
|
||||
<h4>Contact</h4>
|
||||
<div id="contact-container">
|
||||
<form id="contact-form" method="post" onsubmit="return false;">
|
||||
<div class="input-field">
|
||||
<input id="contact-form-from" name="from" type="email" autocomplete="off" class="validate" />
|
||||
<label for="contact-form-from" class="noselect">Email</label>
|
||||
</div>
|
||||
<div class="input-field">
|
||||
<input id="contact-form-message" name="message" type="text" autocomplete="off">
|
||||
<label for="contact-form-message" class="noselect">Message</label>
|
||||
</div>
|
||||
<button class="contact-button-submit" id="submit-contact-form">Send</button>
|
||||
<div class="valign hide" id="send-loader">
|
||||
<div class="preloader-wrapper small active">
|
||||
<div class="spinner-layer spinner-blue">
|
||||
<div class="circle-clipper left">
|
||||
<div class="circle"></div>
|
||||
</div><div class="gap-patch">
|
||||
<div class="circle"></div>
|
||||
</div><div class="circle-clipper right">
|
||||
<div class="circle"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="spinner-layer spinner-red">
|
||||
<div class="circle-clipper left">
|
||||
<div class="circle"></div>
|
||||
</div><div class="gap-patch">
|
||||
<div class="circle"></div>
|
||||
</div><div class="circle-clipper right">
|
||||
<div class="circle"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="spinner-layer spinner-yellow">
|
||||
<div class="circle-clipper left">
|
||||
<div class="circle"></div>
|
||||
</div><div class="gap-patch">
|
||||
<div class="circle"></div>
|
||||
</div><div class="circle-clipper right">
|
||||
<div class="circle"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="spinner-layer spinner-green">
|
||||
<div class="circle-clipper left">
|
||||
<div class="circle"></div>
|
||||
</div><div class="gap-patch">
|
||||
<div class="circle"></div>
|
||||
</div><div class="circle-clipper right">
|
||||
<div class="circle"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#!" class=" modal-action modal-close waves-effect waves-green btn-flat">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="page-footer cursor-default">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col l6 s12">
|
||||
<h5 class="white-text">Zoff</h5>
|
||||
<p class="grey-text text-lighten-4">The shared YouTube radio</p>
|
||||
<p class="grey-text text-lighten-4">
|
||||
Being built around the YouTube search and video API
|
||||
it enables the creation of collaborative and shared live playlists,
|
||||
with billions of videos and songs to choose from, all for free and without registration.
|
||||
<br />
|
||||
Enjoy!
|
||||
</p>
|
||||
<ul class="footer-buttons">
|
||||
<li>
|
||||
<a class="modal-trigger waves-effect cyan darken-2 btn help-button-footer" title="Need help with the site?" onclick="$('#help').modal('open')">
|
||||
<i class="material-icons left footer-button-icon">help_outline</i>HELP
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="modal-trigger waves-effect blue-grey darken-2 btn help-button-footer hide-on-small-only" id="embed-button" title="Want to embed this channel?" onclick="$('#embed').modal('open')">
|
||||
<i class="material-icons left footer-button-icon">code</i>EMBED
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="modal-trigger waves-effect red darken-2 btn help-button-footer" id="contact-button" title="Contact us" onclick="$('#contact').modal('open')">
|
||||
<i class="material-icons left footer-button-icon">email</i>CONTACT
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<p id="latest-commit" class="grey-text text-lighten-4"></p>
|
||||
</div>
|
||||
<div class="col l4 offset-l2 s12 valign-wrapper">
|
||||
<ul class="footer-buttons">
|
||||
<li>
|
||||
<a id="facebook-code-link" class="waves-effect waves-light btn light-blue share shareface" href="https://www.facebook.com/sharer/sharer.php?u=http://<?php echo $_SERVER['HTTP_HOST'].'/'.$list; ?>" target="popup" onclick="window.open('https://www.facebook.com/sharer/sharer.php?u=http://<?php echo $_SERVER['HTTP_HOST'].'/'.$list; ?>','Share Playlist','width=600,height=300')">
|
||||
<img class="left" src="/public/images/facebook.png" alt="Share on Facebook" />Share on Facebook
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a id="twitter-code-link" class="waves-effect waves-light btn light-blue share" href="http://twitter.com/intent/tweet?url=http://<?php echo $_SERVER['HTTP_HOST'].'/'.$list; ?>&text=Check%20out%20this%20playlist%20<?php echo ucfirst($list); ?>%20on%20Zöff!&via=zoffmusic" target="popup" onclick="window.open('http://twitter.com/intent/tweet?url=http://<?php echo $_SERVER['HTTP_HOST'].'/'.$list; ?>&text=Check%20out%20this%20playlist%20<?php echo ucfirst($list); ?>%20on%20Zöff!&via=zoffmusic','Share Playlist','width=600,height=300')">
|
||||
<img class="left" src="/public/images/twitter.png" alt="Share on Twitter" />Share on Twitter
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank" id="donate_form">
|
||||
<input type="hidden" name="cmd" value="_s-xclick">
|
||||
<input type="hidden" name="hosted_button_id" value="JEXDYP59N5VWE">
|
||||
<a title="Like what we made? Help us by donating (a) beer!" class="waves-effect waves-light btn orange light-blue share" onclick="document.getElementById('donate_form').submit();">
|
||||
<i class="material-icons left footer-button-icon">payment</i>Donate
|
||||
</a>
|
||||
</form>
|
||||
<p class="hide-on-small-only">
|
||||
<div id="qr-code-link">
|
||||
<img id="qr-code-image-link" class="card rounded" src="//chart.googleapis.com/chart?chs=150x150&cht=qr&chl=http://<?php echo $_SERVER['HTTP_HOST'].'/'.$list; ?>&choe=UTF-8&chld=L%7C1" alt="QRCode for link" title="QR code for this page, for easy sharing!" />
|
||||
</div>
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-copyright">
|
||||
<div class="container">
|
||||
© <?php echo date("Y"); ?>
|
||||
<a href="http://nixo.no">Nixo</a> &
|
||||
<a href="http://kasperrt.no">KasperRT</a>,
|
||||
All rights reserved
|
||||
<a class="grey-text text-lighten-4 right" href="https://github.com/zoff-music/">Contribute on GitHub</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -1,46 +0,0 @@
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
| Zoff |
|
||||
| Project is on github: https://github.com/zoff-music/Zoff |
|
||||
| Made by: Nicolas Almagro Tonne and Kasper Rynning-Tønnesen |
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
|
||||
<title>Zoff</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
|
||||
<meta name="author" content="Nicolas 'Nixo' Almagro Tonne & Kasper 'KasperRT' Rynning-Tønnesen"/>
|
||||
<meta name="description" content="The Shared (free) YouTube radio."/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"/>
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="theme-color" content="#2D2D2D" />
|
||||
<meta property="og:image" content="https://zoff.me/public/images/favicon.png" />
|
||||
<meta property="og:url" content="https://zoff.me" />
|
||||
<meta property="og:title" content="Zoff"/>
|
||||
<meta property="og:description" content="The Shared (free) YouTube radio."/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<meta property="fb:app_id" content="1581693815380949" />
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.min.css">
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<link type="text/css" rel="stylesheet" href="/public/css/materialize.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/public/css/style.css" title="Default" />
|
||||
<link rel="icon" id="favicon" type="image/png" href="/public/images/favicon.png"/>
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', '***REMOVED***', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
|
||||
<script type="text/javascript" src="/public/dist/lib/jquery-2.1.3.min.js"></script>
|
||||
<script type="text/javascript" src="/public/dist/lib/materialize.min.js"></script>
|
||||
<script type="text/javascript" src="/public/dist/lib/jquery-ui-1.10.3.min.js"></script>
|
||||
<script type="text/javascript" src="/public/dist/lib/jquery.ui.touch-punch.min.js"></script>
|
||||
<script type="text/javascript" src="/public/dist/lib/socket.io.min.js"></script>
|
||||
<script type="text/javascript" src="/public/dist/lib/color-thief.js"></script>
|
||||
<script type="text/javascript" src="/public/dist/lib/sha256.js"></script>
|
||||
<script type="text/javascript" src="/public/dist/lib/aes.js"></script>
|
||||
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
$url = file_get_contents("https://img.youtube.com/vi/".$_POST['id']."/mqdefault.jpg");
|
||||
|
||||
$image = new Imagick();
|
||||
$image->readImageBlob($url);
|
||||
|
||||
|
||||
$image->blurImage(30,50);
|
||||
|
||||
$output = $image->getimageblob();
|
||||
|
||||
$image->setImageFormat("jpeg");
|
||||
|
||||
file_put_contents ("../images/thumbnails/".$_POST['id'].".jpg", $image);
|
||||
|
||||
echo base64_encode($output);
|
||||
?>
|
||||
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
if(isset($_POST['from']) && isset($_POST['message'])){
|
||||
|
||||
$from = htmlspecialchars($_POST['from']);
|
||||
$message = htmlspecialchars($_POST['message']);
|
||||
$headers = "From: " . $from . "\r\n";
|
||||
|
||||
if(filter_var($from, FILTER_VALIDATE_EMAIL) && $message != ""){
|
||||
$result = mail("contact@zoff.no", "ZOFF: Contact from form", $message, $headers);
|
||||
|
||||
if($result == FALSE){
|
||||
echo "failure";
|
||||
}else{
|
||||
echo "success";
|
||||
}
|
||||
}else{
|
||||
echo "failure";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
4
server/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
node_modules/
|
||||
scripts/
|
||||
.DS_Store
|
||||
mongo_config.js
|
||||
35
server/README.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Zoff-Serverside
|
||||
|
||||
For the client-side repo, go to <a href="https://github.com/zoff-music/Zoff">here</a>
|
||||
|
||||
## Install
|
||||
|
||||
Prerequisites:
|
||||
|
||||
```
|
||||
MongoDB : https://www.mongodb.org/
|
||||
NodeJS : https://nodejs.org/en/
|
||||
npm : https://www.npmjs.com/
|
||||
```
|
||||
|
||||
Clone this repository into a folder, and navigate to it. Use ```npm install``` in the project folder and use ```$ node server.js``` to start the server.
|
||||
|
||||
## About
|
||||
|
||||
Zoff is a shared (free) YouTube based radio service, built upon the YouTube API.
|
||||
|
||||
Zoff is mainly a webbased service. The website uses NodeJS with Socket.IO, MongoDB and PHP on the backend, with JavaScript, jQuery and Materialize on the frontend.
|
||||
|
||||
The team consists of Kasper Rynning-Tønnesen and Nicolas Almagro Tonne, and the project has been worked on since late 2014.
|
||||
|
||||
The team can be reached on contact@zoff.no
|
||||
|
||||
### Legal
|
||||
|
||||
Copyright © 2017
|
||||
Nicolas Almagro Tonne and Kasper Rynning-Tønnesen
|
||||
|
||||
Creative Commons License
|
||||
Zoff is licensed under a
|
||||
<a href="http://creativecommons.org/licenses/by-nc-nd/3.0/no/">Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Norway License.</a>.
|
||||
Do not redistribute without permission from the developers.
|
||||
20
server/change_pinned.js
Normal file
@@ -0,0 +1,20 @@
|
||||
var readline = require('readline');
|
||||
var mongojs = require('mongojs');
|
||||
var db = mongojs.connect('mydb');
|
||||
|
||||
|
||||
var rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
|
||||
rl.question("Channel to pin: ", function(coll) {
|
||||
// TODO: Log the answer in a database
|
||||
db.collection("frontpage_lists").update({pinned:1}, {$set:{pinned:0}}, function(err, resp){
|
||||
db.collection("frontpage_lists").update({_id:coll}, {$set:{pinned:1}}, function(err, resp){
|
||||
console.log("Changed pinned channel to: " + coll);
|
||||
process.exit();
|
||||
});
|
||||
});
|
||||
rl.close();
|
||||
});
|
||||
38
server/package.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "zoff",
|
||||
"version": "2.0.2",
|
||||
"description": "Zoff, the shared YouTube based radio services",
|
||||
"dependencies": {
|
||||
"bad-words": "^1.5.1",
|
||||
"body-parser": "^1.17.1",
|
||||
"cookie-parser": "^1.4.3",
|
||||
"cors-anywhere": "^0.2.3",
|
||||
"emoji-strip": "^0.0.3",
|
||||
"express": "^4.15.2",
|
||||
"express-handlebars": "^3.0.0",
|
||||
"express-subdomain": "^1.0.5",
|
||||
"jimp": "^0.2.27",
|
||||
"lwip": "0.0.9",
|
||||
"mongodb": "^2.0.27",
|
||||
"mongojs": "^2.4.0",
|
||||
"node-cryptojs-aes": "^0.4.0",
|
||||
"request": "^2.72.0",
|
||||
"sendmail": "^1.1.1",
|
||||
"socket.io": "^1.7.3",
|
||||
"uniqid": "^4.1.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/zoff-music/zoff-server.git"
|
||||
},
|
||||
"author": {
|
||||
"name": "Kasper Rynning Tønnesen",
|
||||
"email": "kasper@kasperrt.no"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp-util": "~3.0.6",
|
||||
"gulp": "~3.9.0",
|
||||
"gulp-concat": "~2.6.0",
|
||||
"gulp-uglifyjs": "~0.6.2"
|
||||
}
|
||||
}
|
||||
137
server/router.js
Normal file
@@ -0,0 +1,137 @@
|
||||
var express = require('express');
|
||||
var router = express.Router();
|
||||
const path = require('path');
|
||||
var sendmail = require('sendmail')();
|
||||
|
||||
router.use(function(req, res, next) {
|
||||
next(); // make sure we go to the next routes and don't stop here
|
||||
});
|
||||
|
||||
router.route('/:channel_name').get(function(req, res, next){
|
||||
var url = req.headers['x-forwarded-host'];
|
||||
var subdomain = req.headers['x-forwarded-host'].split(".");
|
||||
if(url != "zoff.me" && url != "remote.zoff.me" && url != "remote.localhost" && url != "localhost") {
|
||||
res.redirect("https://zoff.me");
|
||||
return;
|
||||
}
|
||||
if(subdomain[0] == "remote") {
|
||||
var data = {
|
||||
year: 2017,
|
||||
javascript_file: "remote.min.js"
|
||||
}
|
||||
res.render('layouts/remote', data);
|
||||
} else if(subdomain.length >= 2 && subdomain[0] == "www") {
|
||||
res.redirect("https://zoff.me");
|
||||
} else {
|
||||
if(req.params.channel_name == "_embed") {
|
||||
res.sendFile(path.join(__dirname, '/views/assets/html/embed.html'));
|
||||
} else if(req.params.channel_name == "o_callback") {
|
||||
res.sendFile(path.join(__dirname, '/views/assets/html/callback.html'));
|
||||
} else {
|
||||
var data = {
|
||||
list_name: capitalizeFirstLetter(req.params.channel_name),
|
||||
year: 2017,
|
||||
javascript_file: "main.min.js"
|
||||
}
|
||||
res.render('layouts/channel', data);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
router.route('/api/imageblob').post(function(req, res) {
|
||||
var Jimp = require("jimp");
|
||||
Jimp.read('https://img.youtube.com/vi/' + req.body.id + '/mqdefault.jpg', function (err, image) {
|
||||
if (err) throw err;
|
||||
image.blur(50)
|
||||
.write(path.join(__dirname, '/views/assets/images/thumbnails/' + req.body.id + '.jpg'), function(e, r) {
|
||||
res.send(req.body.id + ".jpg");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
*
|
||||
* TODO:
|
||||
*
|
||||
* Add custom userplaylists, only visible for those with that specific cookie
|
||||
*
|
||||
*
|
||||
router.route('/:user_name/:channel_name').get(function(req, res, next){
|
||||
var protocol = req.protocol;
|
||||
var subdomain = req.headers['x-forwarded-host'].split(".");
|
||||
|
||||
if((subdomain[0] != 'localhost' && !(subdomain.length >= 2 && subdomain[1] == 'localhost')) && protocol != "https") {
|
||||
res.redirect("https://zoff.me");
|
||||
return;
|
||||
}
|
||||
if(subdomain[0] == "remote") {
|
||||
var data = {
|
||||
year: 2017,
|
||||
javascript_file: "remote.min.js"
|
||||
}
|
||||
res.render('layouts/remote', data);
|
||||
} else if(subdomain.length >= 2 && subdomain[0] == "www") {
|
||||
res.redirect("https://zoff.me");
|
||||
} else {
|
||||
if(req.params.channel_name == "_embed") {
|
||||
res.sendFile(path.join(__dirname, '/views/assets/html/embed.html'));
|
||||
} else if(req.params.channel_name == "o_callback") {
|
||||
res.sendFile(path.join(__dirname, '/views/assets/html/callback.html'));
|
||||
} else {
|
||||
var data = {
|
||||
list_name: capitalizeFirstLetter(req.params.channel_name),
|
||||
year: 2017,
|
||||
javascript_file: "main.min.js"
|
||||
}
|
||||
res.render('layouts/channel', data);
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
router.route('/api/mail').post(function(req, res) {
|
||||
var from = req.body.from;
|
||||
var message = req.body.message;
|
||||
sendmail({
|
||||
from: from,
|
||||
to: 'contact@zoff.no',
|
||||
subject: 'ZOFF: Contact form webpage',
|
||||
html: message,
|
||||
}, function(err, reply) {
|
||||
if(err) {
|
||||
res.sendStatus(500);
|
||||
} else {
|
||||
res.sendStatus(200);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
router.route('/').get(function(req, res, next){
|
||||
var url = req.headers['x-forwarded-host'];
|
||||
var subdomain = req.headers['x-forwarded-host'].split(".");
|
||||
if(url != "zoff.me" && url != "remote.zoff.me" && url != "remote.localhost" && url != "localhost") {
|
||||
res.redirect("https://zoff.me");
|
||||
return;
|
||||
}
|
||||
if(subdomain[0] == "remote") {
|
||||
var data = {
|
||||
year: 2017,
|
||||
javascript_file: "remote.min.js"
|
||||
}
|
||||
res.render('layouts/remote', data);
|
||||
} else if(subdomain[0] == "www") {
|
||||
res.redirect("https://zoff.me");
|
||||
} else {
|
||||
var data = {
|
||||
year: 2017,
|
||||
javascript_file: "main.min.js"
|
||||
}
|
||||
res.render('layouts/frontpage', data);
|
||||
}
|
||||
});
|
||||
|
||||
function capitalizeFirstLetter(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
|
||||
module.exports = router;
|
||||
1225
server/server.js
Executable file
@@ -1361,7 +1361,7 @@ ul #chat-log{
|
||||
|
||||
}
|
||||
|
||||
#channelpage{
|
||||
.channelpage{
|
||||
background-color:#2D2D2D;
|
||||
-webkit-transition: background-color .5s ease;
|
||||
-moz-transition: background-color .5s ease;
|
||||
@@ -2220,7 +2220,7 @@ nav ul li:hover, nav ul li.active {
|
||||
}
|
||||
|
||||
.page-footer{
|
||||
margin-top:40px !important;
|
||||
padding-top: 40px !important;
|
||||
}
|
||||
|
||||
.padding-bottom-novideo{
|
||||
2
server/views/assets/dist/embed.min.js
vendored
Executable file
4
server/views/assets/dist/main.min.js
vendored
Executable file
@@ -1 +1 @@
|
||||
!function(){var e=!0;mobilecheck=function(){var e=!1;return function(t){(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(t)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(t.substr(0,4)))&&(e=!0)}(navigator.userAgent||navigator.vendor||window.opera),e},$(document).ready(function(){document.title="Zoff Remote",setTimeout(function(){$("#search").focus()},500);var e={"sync disconnect on unload":!0,secure:!0};$("#about").modal(),$("#contact").modal(),"remote.zoff.me"==window.location.hostname?add="https://zoff.me":add="localhost",socket=io.connect(add+":8080",e),id=window.location.pathname.split("/")[1],id&&(id=id.toLowerCase(),t.control()),git_info=$.ajax({type:"GET",url:"https://api.github.com/users/zoff-music/received_events",async:!1}).responseText,git_info=$.parseJSON(git_info),$("#latest-commit").html("Latest Commit: <br>"+git_info[0].created_at.substring(0,10)+": "+git_info[0].actor.display_login+"<br><a href='https://github.com/"+git_info[0].repo.name+"/commit/"+git_info[0].payload.commits[0].sha+"' target='_blank'>"+git_info[0].payload.commits[0].sha.substring(0,10)+"</a>: "+git_info[0].payload.commits[0].message+"<br")}),$("#playbutton").on("click",function(){socket.emit("id",{id:id,type:"play",value:"mock"})}),$("#pausebutton").on("click",function(){socket.emit("id",{id:id,type:"pause",value:"mock"})}),$("#skipbutton").on("click",function(){socket.emit("id",{id:id,type:"skip",value:"mock"})}),$("#remoteform").on("submit",function(){t.control()});var t={control:function(){e?(id||(id=document.getElementById("remoteform").chan.value,window.history.pushState("object or string","Title","/"+id)),document.getElementById("remoteform").chan.value="",e=!1,$(".rc").css("display","block"),$("#remote-text").text("Controlling "+id.toUpperCase()),document.getElementById("search").setAttribute("length","18"),document.getElementById("search").setAttribute("maxlength","18"),$("#forsearch").html("Type new channel name to change to"),$("#volume-control").slider({min:0,max:100,value:100,range:"min",animate:!0,stop:function(e,t){socket.emit("id",{id:id,type:"volume",value:t.value})}})):(socket.emit("id",{id:id,type:"channel",value:$("#search").val().toLowerCase()}),$("#search").val(""))}}}();
|
||||
!function(){var e=!0;mobilecheck=function(){var e=!1;return function(t){(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(t)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(t.substr(0,4)))&&(e=!0)}(navigator.userAgent||navigator.vendor||window.opera),e},$(document).ready(function(){document.title="Zoff Remote",setTimeout(function(){$("#search").focus()},500);var e={"sync disconnect on unload":!0,secure:!0};$("#about").modal(),$("#contact").modal(),"remote.zoff.me"==window.location.hostname?add="https://zoff.me":add="localhost",socket=io.connect(add+":8080",e),id=window.location.pathname.split("/")[1],id&&(id=id.toLowerCase(),t.control());try{git_info=$.ajax({type:"GET",url:"https://api.github.com/users/zoff-music/received_events",async:!1}).responseText,git_info=$.parseJSON(git_info),$("#latest-commit").html("Latest Commit: <br>"+git_info[0].created_at.substring(0,10)+": "+git_info[0].actor.display_login+"<br><a href='https://github.com/"+git_info[0].repo.name+"/commit/"+git_info[0].payload.commits[0].sha+"' target='_blank'>"+git_info[0].payload.commits[0].sha.substring(0,10)+"</a>: "+git_info[0].payload.commits[0].message+"<br")}catch(e){}}),$(document).on("click","#playbutton",function(){socket.emit("id",{id:id,type:"play",value:"mock"})}),$(document).on("click","#pausebutton",function(){socket.emit("id",{id:id,type:"pause",value:"mock"})}),$(document).on("click","#skipbutton",function(){socket.emit("id",{id:id,type:"skip",value:"mock"})}),$(document).on("submit","#remoteform",function(e){console.log("testing"),e.preventDefault(),t.control()});var t={control:function(){e?(id||(id=document.getElementById("remoteform").chan.value,window.history.pushState("object or string","Title","/"+id)),document.getElementById("remoteform").chan.value="",e=!1,$(".rc").css("display","block"),$("#remote-text").text("Controlling "+id.toUpperCase()),document.getElementById("search").setAttribute("length","18"),document.getElementById("search").setAttribute("maxlength","18"),$("#forsearch").html("Type new channel name to change to"),$("#volume-control").slider({min:0,max:100,value:100,range:"min",animate:!0,stop:function(e,t){socket.emit("id",{id:id,type:"volume",value:t.value})}})):(socket.emit("id",{id:id,type:"channel",value:$("#search").val().toLowerCase()}),$("#search").val(""))}}}();
|
||||
|
Before Width: | Height: | Size: 322 KiB After Width: | Height: | Size: 322 KiB |
@@ -2,7 +2,7 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Zoff OAuth Callback</title>
|
||||
<script type="text/javascript" src="/public/dist/callback.min.js"></script>
|
||||
<script type="text/javascript" src="/assets/dist/callback.min.js"></script>
|
||||
<meta charset="UTF-8"/>
|
||||
</head>
|
||||
<body>
|
||||
@@ -5,13 +5,13 @@
|
||||
<meta name="author" content="Nicolas 'Nixo' Almagro Tonne & Kasper 'KasperRT' Rynning-Tønnesen"/>
|
||||
<meta name="description" content="The Shared (free) YouTube radio. Being built around the YouTube search and video API it enables the creation of collaborative and shared live playlists, with billions of videos and songs to choose from, all for free and without registration. Enjoy!"/>
|
||||
<meta charset="UTF-8"/>
|
||||
<link type="text/css" rel="stylesheet" href="/public/css/materialize.min.css" />
|
||||
<link type="text/css" rel="stylesheet" href="/assets/css/materialize.min.css" />
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<script type="text/javascript" src="/public/dist/lib/jquery-2.1.3.min.js"></script>
|
||||
<script type="text/javascript" src="/public/dist/lib/jquery-ui-1.10.3.min.js"></script>
|
||||
<script type="text/javascript" src="/public/dist/lib/socket.io.min.js"></script>
|
||||
<link type="text/css" rel="stylesheet" href="/public/css/embed.css" />
|
||||
<script src="public/dist/embed.min.js"></script>
|
||||
<script type="text/javascript" src="/assets/dist/lib/jquery-2.1.3.min.js"></script>
|
||||
<script type="text/javascript" src="/assets/dist/lib/jquery-ui-1.10.3.min.js"></script>
|
||||
<script type="text/javascript" src="/assets/dist/lib/socket.io.min.js"></script>
|
||||
<link type="text/css" rel="stylesheet" href="/assets/css/embed.css" />
|
||||
<script src="/assets/dist/embed.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
@@ -10,11 +10,11 @@
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="theme-color" content="#2D2D2D" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta property="og:image" content="/public/images/favicon.png" />
|
||||
<meta property="og:image" content="/assets/images/favicon.png" />
|
||||
<meta property="og:title" content="Zoff"/>
|
||||
<meta property="og:description" content="The Shared (free) YouTube radio. Being built around the YouTube search and video API it enables the creation of collaborative and shared live playlists, with billions of videos and songs to choose from, all for free and without registration. Enjoy!"/>
|
||||
<meta property="og:type" content="website"/>
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<link rel="manifest" href="/assets/manifest.json">
|
||||
<script>if(window.location.hostname == "zoff.no") window.location.href="https://zoff.me";</script>
|
||||
</head>
|
||||
<body>
|
||||
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 697 B After Width: | Height: | Size: 697 B |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 786 B After Width: | Height: | Size: 786 B |
|
Before Width: | Height: | Size: 299 B After Width: | Height: | Size: 299 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 980 B After Width: | Height: | Size: 980 B |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
@@ -11,6 +11,7 @@ var adminpass = "";
|
||||
var mobile_beginning = false;
|
||||
var durationBegun = false;
|
||||
var chromecastAvailable = false;
|
||||
var private_channel = false;
|
||||
var offline = false;
|
||||
var from_frontpage = false;
|
||||
var seekTo;
|
||||
@@ -232,19 +232,19 @@ var Frontpage = {
|
||||
},500);
|
||||
} else {
|
||||
var img = new Image();
|
||||
img.src = "/public/images/thumbnails/"+id+".jpg";
|
||||
img.src = "/assets/images/thumbnails/"+id+".jpg";
|
||||
|
||||
img.onerror = function(){ // Failed to load
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {id:id},
|
||||
url: "/public/php/imageblob.php",
|
||||
url: "/api/imageblob",
|
||||
success: function(data){
|
||||
Frontpage.blob_list.push(data);
|
||||
//Frontpage.blob_list.push(data);
|
||||
//data will contain the vote count echoed by the controller i.e.
|
||||
//$(".room-namer").css("opacity", 0);
|
||||
setTimeout(function(){
|
||||
$("#mega-background").css("background", "url(data:image/png;base64,"+data+")");
|
||||
$("#mega-background").css("background", "url(/assets/images/thumbnails/"+data+")");
|
||||
$("#mega-background").css("background-size" , "200%");
|
||||
$("#mega-background").css("opacity", 1);
|
||||
$(".desktop-search").attr("placeholder", list[i].channel);
|
||||
@@ -269,6 +269,7 @@ var Frontpage = {
|
||||
Frontpage.times_rotated = 0;
|
||||
i = 0;
|
||||
socket.emit("frontpage_lists");
|
||||
socket.emit('get_userlists', Crypt.getCookie('_uI'));
|
||||
}else if(frontpage){
|
||||
Frontpage.times_rotated += 1;
|
||||
Frontpage.add_backdrop(list, i+1);
|
||||
@@ -321,12 +322,13 @@ var Frontpage = {
|
||||
Helper.log("removing all listeners");
|
||||
socket.removeAllListeners();
|
||||
}
|
||||
$("body").css("background-color", "#2d2d2d");
|
||||
$("#main-container").css("background-color", "#2d2d2d");
|
||||
$("#offline-mode").tooltip("remove");
|
||||
currently_showing_channels = 1;
|
||||
$.ajax({
|
||||
url: new_channel + "/public/php/index.php",
|
||||
|
||||
url: "/" + new_channel,
|
||||
method: "get",
|
||||
data: {channel: new_channel},
|
||||
success: function(e){
|
||||
|
||||
if(Player.player !== ""){
|
||||
@@ -352,7 +354,7 @@ var Frontpage = {
|
||||
$(".mega").remove();
|
||||
$(".mobile-search").remove();
|
||||
$("main").attr("class", "container center-align main");
|
||||
$("body").attr("id", "channelpage");
|
||||
$("#main-container").addClass("channelpage");
|
||||
//$("header").html($($(e)[63]).html());
|
||||
$("header").html($(response.find("header")).html());
|
||||
if($("#alreadychannel").length === 0 || Helper.mobilecheck() || Player.player === undefined){
|
||||
@@ -451,6 +453,7 @@ function initfp(){
|
||||
});
|
||||
}
|
||||
socket.emit('frontpage_lists');
|
||||
socket.emit('get_userlists', Crypt.getCookie('_uI'));
|
||||
|
||||
$("#channel-load").css("display", "none");
|
||||
//Materialize.toast("<a href='/remote' style='color:white;'>Try out our new feature, remote!</a>", 8000)
|
||||
@@ -222,7 +222,7 @@ var Helper = {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
data: {from: from, message: message},
|
||||
url: "/public/php/mail.php",
|
||||
url: "/api/mail",
|
||||
success: function(data){
|
||||
if(data == "success"){
|
||||
$("#contact-container").empty();
|
||||
@@ -40,7 +40,9 @@ var Hostcontroller = {
|
||||
$("#chan").html(Helper.upperFirst(chan));
|
||||
|
||||
w_p = true;
|
||||
socket.emit("list", chan.toLowerCase());
|
||||
var add = "";
|
||||
if(private_channel) add = Crypt.getCookie("_uI") + "_";
|
||||
socket.emit("list", add + chan.toLowerCase());
|
||||
|
||||
/*if(Crypt.get_pass(chan.toLowerCase()) !== undefined && Crypt.get_pass(chan.toLowerCase()) != ""){
|
||||
socket.emit("password", {password: Crypt.crypt_pass(Crypt.get_pass(chan.toLowerCase())), channel: chan.toLowerCase()});
|
||||
@@ -8,6 +8,7 @@ var api_key = "***REMOVED***";
|
||||
var searching = false;
|
||||
var time_regex = /P((([0-9]*\.?[0-9]*)Y)?(([0-9]*\.?[0-9]*)M)?(([0-9]*\.?[0-9]*)W)?(([0-9]*\.?[0-9]*)D)?)?(T(([0-9]*\.?[0-9]*)H)?(([0-9]*\.?[0-9]*)M)?(([0-9]*\.?[0-9]*)S)?)?/;
|
||||
var conf = [];
|
||||
var private_channel = false;
|
||||
var music = 0;
|
||||
var frontpage = 1;
|
||||
var adminpass = "";
|
||||
@@ -235,7 +236,11 @@ function init(){
|
||||
$("#code-link").attr("href", codeURL);
|
||||
}
|
||||
|
||||
if(no_socket) socket.emit('list', chan.toLowerCase());
|
||||
if(no_socket){
|
||||
var add = "";
|
||||
if(private_channel) add = Crypt.getCookie("_uI") + "_";
|
||||
socket.emit("list", add + chan.toLowerCase());
|
||||
}
|
||||
$("#viewers").tooltip({
|
||||
delay: 5,
|
||||
position: "top",
|
||||
@@ -493,7 +498,9 @@ function setup_youtube_listener(){
|
||||
|
||||
function get_list_listener(){
|
||||
socket.on("get_list", function(){
|
||||
socket.emit('list', chan.toLowerCase());
|
||||
var add = "";
|
||||
if(private_channel) add = Crypt.getCookie("_uI") + "_";
|
||||
socket.emit("list", add + chan.toLowerCase());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -686,8 +693,10 @@ function change_offline(enabled, already_offline){
|
||||
$("#seekToDuration").remove();
|
||||
if(window.location.pathname != "/"){
|
||||
socket.emit("pos");
|
||||
socket.emit('list', chan.toLowerCase());
|
||||
if($("#controls").hasClass("ewresize")) $("#controls").removeClass("ewresize");
|
||||
var add = "";
|
||||
if(private_channel) add = Crypt.getCookie("_uI") + "_";
|
||||
socket.emit("list", add + chan.toLowerCase());
|
||||
if($("#controls").hasClass("ewresize")) $("#controls").removeClass("ewresize");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1575,9 +1584,10 @@ function onepage_load(){
|
||||
|
||||
chan = url_split[3].replace("#", "");
|
||||
$("#chan").html(Helper.upperFirst(chan));
|
||||
|
||||
var add = "";
|
||||
w_p = true;
|
||||
socket.emit("list", chan.toLowerCase());
|
||||
if(private_channel) add = Crypt.getCookie("_uI") + "_";
|
||||
socket.emit("list", add + chan.toLowerCase());
|
||||
}else if(url_split[3] === ""){
|
||||
clearTimeout(width_timeout);
|
||||
if(fireplace_initiated){
|
||||
@@ -1602,8 +1612,9 @@ function onepage_load(){
|
||||
$('#chan_thumbnail').tooltip("remove");
|
||||
$('#admin-lock').tooltip("remove");
|
||||
$("#seekToDuration").remove();
|
||||
|
||||
$.ajax({
|
||||
url: "public/php/frontpage.php",
|
||||
url: "/",
|
||||
success: function(e){
|
||||
|
||||
if(Helper.mobilecheck()) {
|
||||
@@ -1658,8 +1669,8 @@ function onepage_load(){
|
||||
$(".drag-target").remove();
|
||||
$("#sidenav-overlay").remove();
|
||||
$("main").attr("class", "center-align container");
|
||||
$("body").attr("id", "");
|
||||
$("body").attr("style", "");
|
||||
$("#main-container").removeClass("channelpage");
|
||||
$("#main-container").attr("style", "");
|
||||
$("header").html($(response.find("header")).html());
|
||||
$($(response.find(".section.mega"))).insertAfter("header");
|
||||
$($(response.find(".section.mobile-search"))).insertAfter(".mega");
|
||||
@@ -388,7 +388,7 @@ var Player = {
|
||||
var color = colorThief.getColor(img);
|
||||
|
||||
if(window.location.pathname != "/"){
|
||||
document.getElementsByTagName("body")[0].style.backgroundColor = Helper.rgbToHsl(color,true);
|
||||
document.getElementById("main-container").style.backgroundColor = Helper.rgbToHsl(color,true);
|
||||
$("meta[name=theme-color]").attr("content", Helper.rgbToHex(color[0], color[1], color[2]));
|
||||
}
|
||||
};
|
||||
@@ -19,7 +19,7 @@ $(document).ready(function (){
|
||||
|
||||
if(window.location.hostname == "remote.zoff.me") add = "https://zoff.me";
|
||||
else add = "localhost";
|
||||
socket = io.connect(add + ':8080', connection_options);
|
||||
socket = io.connect(add+':8080', connection_options);
|
||||
id = window.location.pathname.split("/")[1];
|
||||
if(id)
|
||||
{
|
||||
@@ -27,6 +27,7 @@ $(document).ready(function (){
|
||||
Remotecontroller.control();
|
||||
}
|
||||
|
||||
try{
|
||||
git_info = $.ajax({ type: "GET",
|
||||
url: "https://api.github.com/users/zoff-music/received_events",
|
||||
async: false
|
||||
@@ -39,25 +40,28 @@ $(document).ready(function (){
|
||||
"<br><a href='https://github.com/"+git_info[0].repo.name+"/commit/" + git_info[0].payload.commits[0].sha + "' target='_blank'>" +
|
||||
git_info[0].payload.commits[0].sha.substring(0,10) + "</a>: " +
|
||||
git_info[0].payload.commits[0].message+"<br");
|
||||
} catch(e) {}
|
||||
});
|
||||
|
||||
$("#playbutton").on("click", function()
|
||||
$(document).on("click", "#playbutton", function()
|
||||
{
|
||||
socket.emit("id", {id: id, type: "play", value: "mock"});
|
||||
});
|
||||
|
||||
$("#pausebutton").on("click", function()
|
||||
$(document).on("click", "#pausebutton", function()
|
||||
{
|
||||
socket.emit("id", {id: id, type: "pause", value: "mock"});
|
||||
});
|
||||
|
||||
$("#skipbutton").on("click", function()
|
||||
$(document).on("click", "#skipbutton", function()
|
||||
{
|
||||
socket.emit("id", {id: id, type: "skip", value: "mock"});
|
||||
});
|
||||
|
||||
$("#remoteform").on("submit", function()
|
||||
$(document).on("submit", "#remoteform", function(e)
|
||||
{
|
||||
console.log("testing");
|
||||
e.preventDefault();
|
||||
/*
|
||||
if(start)
|
||||
window.location.href = '/remote/'+document.getElementById("remoteform").chan.value;
|
||||
@@ -1,21 +1,15 @@
|
||||
<html lang="en">
|
||||
<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
<?php include("public/php/header.php"); ?>
|
||||
<script type="text/javascript" src="/public/dist/main.min.js"></script>
|
||||
</head>
|
||||
<body id="channelpage" class="noselect cursor-default">
|
||||
<header>
|
||||
<div id="main-container" class="channelpage noselect cursor-default">
|
||||
<header>
|
||||
<div class="navbar-fixed">
|
||||
<nav id="nav">
|
||||
<div class="nav-wrapper">
|
||||
|
||||
<div class="brand-logo truncate zbrand">
|
||||
<a href="/" class="brand-logo brand-logo-navigate noselect">
|
||||
<img id="zicon" src="public/images/z.svg" alt="zoff" title="Zoff" />
|
||||
<img id="zicon" src="/assets/images/z.svg" alt="zoff" title="Zoff" />
|
||||
</a>
|
||||
|
||||
<span id="chan" class="chan clickable truncate" title="Show big URL"><?php echo(ucfirst($list));?></span>
|
||||
<span id="chan" class="chan clickable truncate" title="Show big URL">{{list_name}}</span>
|
||||
</div>
|
||||
|
||||
<ul class="title-container">
|
||||
@@ -69,13 +63,13 @@
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="side-nav" id="settings-bar">
|
||||
<?php include("public/php/panel.php");?>
|
||||
{{> panel}}
|
||||
</ul>
|
||||
<div id="results" class="search_results hide">
|
||||
<div id="temp-results-container">
|
||||
<div id="temp-results" class="result-object">
|
||||
<div id="result" class="result">
|
||||
<img class="thumb" src="/public/images/loading.png" alt="Thumb"/>
|
||||
<img class="thumb" src="/assets/images/loading.png" alt="Thumb"/>
|
||||
|
||||
<div class="search-title truncate"></div>
|
||||
<span class="result_info"></span>
|
||||
@@ -217,7 +211,7 @@
|
||||
<div id="list-song" class="card left-align list-song">
|
||||
<div class="clickable vote-container" title="Vote!">
|
||||
<a class="clickable center-align votebg">
|
||||
<span class="lazy card-image cardbg list-image" style="background-image:url('/public/images/loading.png');">
|
||||
<span class="lazy card-image cardbg list-image" style="background-image:url('/assets/images/loading.png');">
|
||||
</span>
|
||||
<span class="card-duration">
|
||||
01:00
|
||||
@@ -255,7 +249,7 @@
|
||||
<div class="row inherit-height">
|
||||
<div class="col s12">
|
||||
<ul class="tabs chatTabs tabs-fixed-width">
|
||||
<li class="tab col s3 chat-tab-li"><a class="active chat-tab truncate" href="#channelchat"><?php echo $list; ?></a></li>
|
||||
<li class="tab col s3 chat-tab-li"><a class="active chat-tab truncate" href="#channelchat">{{list_name}}</a></li>
|
||||
<li class="tab col s3 chat-tab-li"><a class="chat-tab" href="#all_chat">All</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -279,13 +273,4 @@
|
||||
<div id="playbar">
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
$subdomain = array_shift((explode(".",$_SERVER['HTTP_HOST'])));
|
||||
if($subdomain == "fb"){}
|
||||
else {
|
||||
include("public/php/footer.php");
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||
@@ -1,23 +1,9 @@
|
||||
<?php
|
||||
|
||||
if(isset($_GET['chan'])){
|
||||
$chan = htmlspecialchars($_GET['chan']);
|
||||
header('Location: '.$chan);
|
||||
}
|
||||
|
||||
?>
|
||||
<html lang="en">
|
||||
<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
|
||||
<meta name="robots" content="index, nofollow" />
|
||||
<?php include("header.php"); ?>
|
||||
<script type="text/javascript" src="/public/dist/main.min.js"></script>
|
||||
</head>
|
||||
<body class="noselect cursor-default">
|
||||
<div id="main-container">
|
||||
<header>
|
||||
<nav id="fp-nav">
|
||||
<div class="nav-wrapper">
|
||||
<a href="#" class="brand-logo noselect">
|
||||
<img id="zicon" src="public/images/z.svg" alt="zoff" title="Zoff" />
|
||||
<img id="zicon" src="/assets/images/z.svg" alt="zoff" title="Zoff" />
|
||||
</a>
|
||||
<div id="frontpage-viewer-counter" data-position="bottom" data-delay="5" data-tooltip="Total viewers" class="noselect tooltipped" title="Divided among all channels. Hidden or not"></div>
|
||||
<!--<a href="//zoff.me" class="brand-logo brand-mobile hide-on-med-and-up">Zoff</a>-->
|
||||
@@ -177,13 +163,4 @@ if(isset($_GET['chan'])){
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php
|
||||
$subdomain = array_shift((explode(".",$_SERVER['HTTP_HOST'])));
|
||||
if($subdomain == "fb"){}
|
||||
else {
|
||||
include("public/php/footer.php");
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||