mirror of https://github.com/calzoneman/sync.git
Merge branch 'master' into dev
This commit is contained in:
commit
d62931098d
214
channel.js
214
channel.js
|
@ -142,112 +142,130 @@ Channel.prototype.hasPermission = function(user, key) {
|
|||
|
||||
/* REGION Channel data */
|
||||
Channel.prototype.loadDump = function() {
|
||||
fs.readFile("chandump/" + this.name, function(err, data) {
|
||||
if(err) {
|
||||
if(err.code == "ENOENT") {
|
||||
Logger.errlog.log("WARN: missing dump for " + this.name);
|
||||
this.initialized = true;
|
||||
this.saveDump();
|
||||
var self = this;
|
||||
if(self.name === "")
|
||||
return;
|
||||
fs.stat("chandump/" + self.name, function (err, stats) {
|
||||
if(!err) {
|
||||
var mb = stats.size / 1048576;
|
||||
mb = parseInt(mb * 100) / 100;
|
||||
if(mb > 1) {
|
||||
Logger.errlog.log("Large chandump detected: " + self.name +
|
||||
" (" + mb + " MB)");
|
||||
self.updateMotd("Your channel file has exceeded the " +
|
||||
"maximum size of 1MB and cannot be " +
|
||||
"loaded. Please ask an administrator " +
|
||||
"for assistance in restoring it.");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
Logger.errlog.log("Failed to open channel dump " + this.name);
|
||||
Logger.errlog.log(err);
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.logger.log("*** Loading channel dump from disk");
|
||||
data = JSON.parse(data);
|
||||
/* Load the playlist */
|
||||
|
||||
// Old
|
||||
if(data.queue) {
|
||||
if(data.position < 0)
|
||||
data.position = 0;
|
||||
for(var i = 0; i < data.queue.length; i++) {
|
||||
var e = data.queue[i];
|
||||
var m = new Media(e.id, e.title, e.seconds, e.type);
|
||||
var p = this.playlist.makeItem(m);
|
||||
p.queueby = data.queue[i].queueby ? data.queue[i].queueby
|
||||
: "";
|
||||
p.temp = e.temp;
|
||||
this.playlist.items.append(p);
|
||||
if(i == data.position)
|
||||
this.playlist.current = p;
|
||||
}
|
||||
this.sendAll("playlist", this.playlist.items.toArray());
|
||||
this.broadcastPlaylistMeta();
|
||||
this.playlist.startPlayback();
|
||||
}
|
||||
// Current
|
||||
else if(data.playlist) {
|
||||
var chan = this;
|
||||
this.playlist.load(data.playlist, function() {
|
||||
chan.sendAll("playlist", chan.playlist.items.toArray());
|
||||
chan.broadcastPlaylistMeta();
|
||||
chan.playlist.startPlayback(data.playlist.time);
|
||||
});
|
||||
}
|
||||
for(var key in data.opts) {
|
||||
// Gotta love backwards compatibility
|
||||
if(key == "customcss" || key == "customjs") {
|
||||
var k = key.substring(6);
|
||||
this.opts[k] = data.opts[key];
|
||||
fs.readFile("chandump/" + self.name, function(err, data) {
|
||||
if(err) {
|
||||
if(err.code == "ENOENT") {
|
||||
Logger.errlog.log("WARN: missing dump for " + self.name);
|
||||
self.initialized = true;
|
||||
self.saveDump();
|
||||
}
|
||||
else {
|
||||
this.opts[key] = data.opts[key];
|
||||
Logger.errlog.log("Failed to open channel dump " + self.name);
|
||||
Logger.errlog.log(err);
|
||||
}
|
||||
return;
|
||||
}
|
||||
for(var key in data.permissions) {
|
||||
this.permissions[key] = data.permissions[key];
|
||||
}
|
||||
this.sendAll("setPermissions", this.permissions);
|
||||
this.broadcastOpts();
|
||||
this.users.forEach(function (u) {
|
||||
u.autoAFK();
|
||||
});
|
||||
if(data.filters) {
|
||||
for(var i = 0; i < data.filters.length; i++) {
|
||||
var f = data.filters[i];
|
||||
// Backwards compatibility
|
||||
if(f[0] != undefined) {
|
||||
var filt = new Filter("", f[0], "g", f[1]);
|
||||
filt.active = f[2];
|
||||
this.updateFilter(filt, false);
|
||||
try {
|
||||
self.logger.log("*** Loading channel dump from disk");
|
||||
data = JSON.parse(data);
|
||||
/* Load the playlist */
|
||||
|
||||
// Old
|
||||
if(data.queue) {
|
||||
if(data.position < 0)
|
||||
data.position = 0;
|
||||
for(var i = 0; i < data.queue.length; i++) {
|
||||
var e = data.queue[i];
|
||||
var m = new Media(e.id, e.title, e.seconds, e.type);
|
||||
var p = self.playlist.makeItem(m);
|
||||
p.queueby = data.queue[i].queueby ? data.queue[i].queueby
|
||||
: "";
|
||||
p.temp = e.temp;
|
||||
self.playlist.items.append(p);
|
||||
if(i == data.position)
|
||||
self.playlist.current = p;
|
||||
}
|
||||
self.sendAll("playlist", self.playlist.items.toArray());
|
||||
self.broadcastPlaylistMeta();
|
||||
self.playlist.startPlayback();
|
||||
}
|
||||
// Current
|
||||
else if(data.playlist) {
|
||||
var chan = self;
|
||||
self.playlist.load(data.playlist, function() {
|
||||
chan.sendAll("playlist", chan.playlist.items.toArray());
|
||||
chan.broadcastPlaylistMeta();
|
||||
chan.playlist.startPlayback(data.playlist.time);
|
||||
});
|
||||
}
|
||||
for(var key in data.opts) {
|
||||
// Gotta love backwards compatibility
|
||||
if(key == "customcss" || key == "customjs") {
|
||||
var k = key.substring(6);
|
||||
self.opts[k] = data.opts[key];
|
||||
}
|
||||
else {
|
||||
var filt = new Filter(f.name, f.source, f.flags, f.replace);
|
||||
filt.active = f.active;
|
||||
filt.filterlinks = f.filterlinks;
|
||||
this.updateFilter(filt, false);
|
||||
self.opts[key] = data.opts[key];
|
||||
}
|
||||
}
|
||||
this.broadcastChatFilters();
|
||||
for(var key in data.permissions) {
|
||||
self.permissions[key] = data.permissions[key];
|
||||
}
|
||||
self.sendAll("setPermissions", self.permissions);
|
||||
self.broadcastOpts();
|
||||
self.users.forEach(function (u) {
|
||||
u.autoAFK();
|
||||
});
|
||||
if(data.filters) {
|
||||
for(var i = 0; i < data.filters.length; i++) {
|
||||
var f = data.filters[i];
|
||||
// Backwards compatibility
|
||||
if(f[0] != undefined) {
|
||||
var filt = new Filter("", f[0], "g", f[1]);
|
||||
filt.active = f[2];
|
||||
self.updateFilter(filt, false);
|
||||
}
|
||||
else {
|
||||
var filt = new Filter(f.name, f.source, f.flags, f.replace);
|
||||
filt.active = f.active;
|
||||
filt.filterlinks = f.filterlinks;
|
||||
self.updateFilter(filt, false);
|
||||
}
|
||||
}
|
||||
self.broadcastChatFilters();
|
||||
}
|
||||
if(data.motd) {
|
||||
self.motd = data.motd;
|
||||
self.broadcastMotd();
|
||||
}
|
||||
self.setLock(!(data.openqueue || false));
|
||||
self.chatbuffer = data.chatbuffer || [];
|
||||
for(var i = 0; i < self.chatbuffer.length; i++) {
|
||||
self.sendAll("chatMsg", self.chatbuffer[i]);
|
||||
}
|
||||
self.css = data.css || "";
|
||||
self.js = data.js || "";
|
||||
self.sendAll("channelCSSJS", {css: self.css, js: self.js});
|
||||
self.initialized = true;
|
||||
setTimeout(function() { incrementalDump(self); }.bind(self), 300000);
|
||||
}
|
||||
if(data.motd) {
|
||||
this.motd = data.motd;
|
||||
this.broadcastMotd();
|
||||
catch(e) {
|
||||
Logger.errlog.log("Channel dump load failed: ");
|
||||
Logger.errlog.log(e.stack);
|
||||
}
|
||||
this.setLock(!(data.openqueue || false));
|
||||
this.chatbuffer = data.chatbuffer || [];
|
||||
for(var i = 0; i < this.chatbuffer.length; i++) {
|
||||
this.sendAll("chatMsg", this.chatbuffer[i]);
|
||||
}
|
||||
this.css = data.css || "";
|
||||
this.js = data.js || "";
|
||||
this.sendAll("channelCSSJS", {css: this.css, js: this.js});
|
||||
this.initialized = true;
|
||||
setTimeout(function() { incrementalDump(this); }.bind(this), 300000);
|
||||
}
|
||||
catch(e) {
|
||||
Logger.errlog.log("Channel dump load failed: ");
|
||||
Logger.errlog.log(e.stack);
|
||||
}
|
||||
}.bind(this));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Channel.prototype.saveDump = function() {
|
||||
if(!this.initialized)
|
||||
if(!this.initialized || this.name === "")
|
||||
return;
|
||||
var filts = new Array(this.filters.length);
|
||||
for(var i = 0; i < this.filters.length; i++) {
|
||||
|
@ -1139,7 +1157,19 @@ Channel.prototype.tryQueue = function(user, data) {
|
|||
|
||||
if(user.rank < Rank.Moderator
|
||||
&& this.leader != user
|
||||
&& user.noflood("queue", 1.5)) {
|
||||
&& user.noflood("queue", 3)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var count = this.playlist.count(data.id);
|
||||
|
||||
if(user.rank < Rank.Moderator && count >= 5) {
|
||||
user.socket.emit("queueFail", "That video is already on the " +
|
||||
"playlist 5 times.");
|
||||
return;
|
||||
} else if(user.rank < Rank.Siteadmin && count >= 20) {
|
||||
user.socket.emit("queueFail", "That video is already on the " +
|
||||
"playlist 20 times.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
20
database.js
20
database.js
|
@ -41,12 +41,22 @@ function getConnection() {
|
|||
Logger.errlog.log("DB connection failed");
|
||||
return false;
|
||||
}
|
||||
if(CONFIG["debug"]) {
|
||||
db._querySync = db.querySync;
|
||||
db.querySync = function(q) {
|
||||
Logger.syslog.log("DEBUG: " + q);
|
||||
return this._querySync(q);
|
||||
db._querySync = db.querySync;
|
||||
db.querySync = function(q) {
|
||||
if(!this.connectedSync()) {
|
||||
db = false;
|
||||
return false;
|
||||
}
|
||||
var res = this._querySync(q);
|
||||
if(!res) {
|
||||
try {
|
||||
db.closeSync();
|
||||
} catch(e) {
|
||||
// already disconnected
|
||||
}
|
||||
db = false;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
|
32
get-info.js
32
get-info.js
|
@ -11,13 +11,23 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|||
|
||||
var http = require("http");
|
||||
var https = require("https");
|
||||
var domain = require("domain");
|
||||
var Logger = require("./logger.js");
|
||||
var Media = require("./media.js").Media;
|
||||
var CustomEmbedFilter = require("./customembed").filter;
|
||||
|
||||
module.exports = function (Server) {
|
||||
function urlRetrieve(transport, options, callback) {
|
||||
try {
|
||||
var urlRetrieve = function (transport, options, callback) {
|
||||
// Catch any errors that crop up along the way of the request
|
||||
// in order to prevent them from reaching the global handler.
|
||||
// This should cut down on needing to restart the server
|
||||
var d = domain.create();
|
||||
d.on("error", function (err) {
|
||||
Logger.errlog.log("urlRetrieve failed: " + err);
|
||||
Logger.errlog.log("Request was: " + options.host + options.path);
|
||||
callback(503, err);
|
||||
});
|
||||
d.run(function () {
|
||||
var req = transport.request(options, function (res) {
|
||||
var buffer = "";
|
||||
res.setEncoding("utf-8");
|
||||
|
@ -30,10 +40,8 @@ module.exports = function (Server) {
|
|||
});
|
||||
|
||||
req.end();
|
||||
} catch(e) {
|
||||
callback(503, "");
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var Getters = {
|
||||
/* youtube.com */
|
||||
|
@ -65,6 +73,9 @@ module.exports = function (Server) {
|
|||
} else if(status === 403) {
|
||||
callback("Private video", null);
|
||||
return;
|
||||
} else if(status === 503) {
|
||||
callback("API failure", null);
|
||||
return;
|
||||
} else if(status !== 200) {
|
||||
callback(true, null);
|
||||
return;
|
||||
|
@ -177,6 +188,9 @@ module.exports = function (Server) {
|
|||
} else if(status === 403) {
|
||||
callback("Playlist is private", null);
|
||||
return;
|
||||
} else if(status === 503) {
|
||||
callback("API failure", null);
|
||||
return;
|
||||
} else if(status !== 200) {
|
||||
callback(true, null);
|
||||
}
|
||||
|
@ -278,6 +292,9 @@ module.exports = function (Server) {
|
|||
} else if(status === 403) {
|
||||
callback("Private video", null);
|
||||
return;
|
||||
} else if(status === 503) {
|
||||
callback("API failure", null);
|
||||
return;
|
||||
} else if(status !== 200) {
|
||||
callback(true, null);
|
||||
return;
|
||||
|
@ -362,6 +379,9 @@ module.exports = function (Server) {
|
|||
if(status === 404) {
|
||||
callback("Sound not found", null);
|
||||
return;
|
||||
} else if(status === 503) {
|
||||
callback("API failure", null);
|
||||
return;
|
||||
} else if(status !== 302) {
|
||||
callback(true, null);
|
||||
return;
|
||||
|
|
2
media.js
2
media.js
|
@ -45,6 +45,8 @@ exports.formatTime = formatTime;
|
|||
var Media = function(id, title, seconds, type) {
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
if(this.title.length > 100)
|
||||
this.title = this.title.substring(0, 97) + "...";
|
||||
this.seconds = seconds == "--:--" ? "--:--" : parseInt(seconds);
|
||||
this.duration = formatTime(this.seconds);
|
||||
if(seconds == "--:--") {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"author": "Calvin Montgomery",
|
||||
"name": "CyTube",
|
||||
"description": "Online media synchronizer and chat",
|
||||
"version": "2.3.2",
|
||||
"version": "2.3.3",
|
||||
"repository": {
|
||||
"url": "http://github.com/calzoneman/sync"
|
||||
},
|
||||
|
|
|
@ -450,6 +450,15 @@ Playlist.prototype.clear = function() {
|
|||
clearInterval(this._leadInterval);
|
||||
}
|
||||
|
||||
Playlist.prototype.count = function (id) {
|
||||
var count = 0;
|
||||
this.items.forEach(function (i) {
|
||||
if(i.media.id === id)
|
||||
count++;
|
||||
});
|
||||
return count;
|
||||
}
|
||||
|
||||
Playlist.prototype.lead = function(lead) {
|
||||
this.leading = lead;
|
||||
var pl = this;
|
||||
|
|
|
@ -6,7 +6,7 @@ var Logger = require("./logger");
|
|||
var Channel = require("./channel");
|
||||
var User = require("./user");
|
||||
|
||||
const VERSION = "2.3.2";
|
||||
const VERSION = "2.3.3";
|
||||
|
||||
function getIP(req) {
|
||||
var raw = req.connection.remoteAddress;
|
||||
|
@ -63,6 +63,7 @@ var Server = {
|
|||
}
|
||||
}
|
||||
chan.name = "";
|
||||
chan.canonical_name = "";
|
||||
},
|
||||
stats: null,
|
||||
app: null,
|
||||
|
|
|
@ -161,4 +161,13 @@ ULList.prototype.toArray = function(pack) {
|
|||
return arr;
|
||||
}
|
||||
|
||||
/* iterate across the playlist */
|
||||
ULList.prototype.forEach = function (fn) {
|
||||
var item = this.first;
|
||||
while(item !== null) {
|
||||
fn(item);
|
||||
item = item.next;
|
||||
}
|
||||
};
|
||||
|
||||
exports.ULList = ULList;
|
||||
|
|
59
update.js
59
update.js
|
@ -1,38 +1,14 @@
|
|||
var Config = require("./config.js");
|
||||
var Database = require("./database.js");
|
||||
|
||||
//Config.DEBUG = true;
|
||||
Database.setup(Config);
|
||||
Database.init();
|
||||
var query;
|
||||
var db = Database.getConnection();
|
||||
var x = {};
|
||||
Config.load(x, "cfg.json", function () {
|
||||
Database.setup(x.cfg);
|
||||
Database.init();
|
||||
var query;
|
||||
var db = Database.getConnection();
|
||||
|
||||
// Check for already existing
|
||||
query = "SELECT owner FROM channels WHERE 1";
|
||||
if(!db.querySync(query)) {
|
||||
query = "ALTER TABLE channels ADD owner VARCHAR(20) NOT NULL";
|
||||
var res = db.querySync(query);
|
||||
if(!res) {
|
||||
console.log(db);
|
||||
console.log("Update failed!");
|
||||
}
|
||||
else {
|
||||
populateChannelOwners();
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Fixing user playlist bug");
|
||||
query = "ALTER TABLE user_playlists DROP PRIMARY KEY, ADD PRIMARY KEY (user, name)";
|
||||
if(!db.querySync(query)) {
|
||||
console.log("Something went wrong");
|
||||
}
|
||||
else {
|
||||
console.log("fixed");
|
||||
}
|
||||
db.closeSync();
|
||||
process.exit(0);
|
||||
|
||||
function populateChannelOwners() {
|
||||
query = "SELECT * FROM channels WHERE 1";
|
||||
var res = db.querySync(query);
|
||||
if(!res) {
|
||||
|
@ -44,27 +20,16 @@ function populateChannelOwners() {
|
|||
var channels = res.fetchAllSync();
|
||||
channels.forEach(function(chan) {
|
||||
chan = chan.name;
|
||||
query = "SELECT name FROM `chan_"+chan+"_ranks` WHERE rank>=10 ORDER BY rank";
|
||||
query = "UPDATE `chan_" + chan + "_library` SET title=CONCAT(" +
|
||||
"SUBSTRING(title FROM 0 FOR 97), '...') WHERE " +
|
||||
"LENGTH(title) > 100";
|
||||
console.log(query);
|
||||
res = db.querySync(query);
|
||||
if(!res) {
|
||||
console.log(db);
|
||||
console.log("failed to fix "+chan);
|
||||
return;
|
||||
}
|
||||
|
||||
var results = res.fetchAllSync();
|
||||
if(results.length == 0) {
|
||||
console.log("bad channel: " + chan);
|
||||
return;
|
||||
}
|
||||
var owner = results[0].name;
|
||||
query = "UPDATE channels SET owner='"+owner+"' WHERE name='"+chan+"'";
|
||||
console.log("setting owner=" + owner + " for /r/" + chan);
|
||||
res = db.querySync(query);
|
||||
if(!res) {
|
||||
console.log(db);
|
||||
console.log("Update failed!");
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
db.closeSync();
|
||||
});
|
||||
|
|
|
@ -159,7 +159,7 @@ html, body {
|
|||
}
|
||||
|
||||
#messagebuffer div, #messagebuffer code, #filteredit code,
|
||||
#channeldata td, #currenttitle {
|
||||
#channeldata td, #currenttitle, .profile-box {
|
||||
white-space: pre-wrap; /* css-3 */
|
||||
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
|
||||
white-space: -pre-wrap; /* Opera 4-6 */
|
||||
|
|
|
@ -758,7 +758,7 @@ Callbacks = {
|
|||
}
|
||||
makeAlert("Error", data, "alert-error")
|
||||
.addClass("span12")
|
||||
.insertAfter($("#mediaurl").parent());
|
||||
.insertBefore($("#extended_controls"));
|
||||
},
|
||||
|
||||
setTemp: function(data) {
|
||||
|
|
|
@ -117,7 +117,8 @@ var USEROPTS = {
|
|||
ignore_channelcss : getOrDefault("ignore_channelcss", false),
|
||||
ignore_channeljs : getOrDefault("ignore_channeljs", false),
|
||||
sort_rank : getOrDefault("sort_rank", false),
|
||||
sort_afk : getOrDefault("sort_afk", false)
|
||||
sort_afk : getOrDefault("sort_afk", false),
|
||||
default_quality : getOrDefault("default_quality", "#quality_auto")
|
||||
};
|
||||
|
||||
var NO_WEBSOCKETS = USEROPTS.altsocket;
|
||||
|
|
|
@ -224,10 +224,15 @@ $("#userpl_save").click(function() {
|
|||
});
|
||||
|
||||
/* video controls */
|
||||
function selectQuality(select, preset) {
|
||||
|
||||
}
|
||||
(function() {
|
||||
function qualHandler(select, preset) {
|
||||
$(select).click(function() {
|
||||
VIDEOQUALITY = preset;
|
||||
USEROPTS.default_quality = select;
|
||||
saveOpts();
|
||||
var btn = $("#qualitywrap .btn.dropdown-toggle");
|
||||
var caret = btn.find(".caret").detach();
|
||||
btn.text($(select).text());
|
||||
|
@ -236,11 +241,14 @@ $("#userpl_save").click(function() {
|
|||
PLAYER.player.setPlaybackQuality(VIDEOQUALITY);
|
||||
});
|
||||
}
|
||||
qualHandler("#quality_auto", "");
|
||||
qualHandler("#quality_240p", "small");
|
||||
qualHandler("#quality_360p", "medium");
|
||||
qualHandler("#quality_480p", "large");
|
||||
qualHandler("#quality_720p", "hd720");
|
||||
qualHandler("#quality_1080p", "hd1080");
|
||||
if($(USEROPTS.default_quality).length > 0)
|
||||
$(USEROPTS.default_quality).click();
|
||||
})();
|
||||
|
||||
$("#mediarefresh").click(function() {
|
||||
|
|
|
@ -149,6 +149,7 @@
|
|||
Quality <span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a id="quality_auto" href="javascript:void(0)">Quality: Auto</a></li>
|
||||
<li><a id="quality_240p" href="javascript:void(0)">240p</a></li>
|
||||
<li><a id="quality_360p" href="javascript:void(0)">360p</a></li>
|
||||
<li><a id="quality_480p" href="javascript:void(0)">480p</a></li>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
</div>
|
||||
<div class="row">
|
||||
<div class="span8">
|
||||
<h3>Loaded Channels</h3>
|
||||
<h3>Public Channels</h3>
|
||||
<table id="channeldata" class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
Loading…
Reference in New Issue