Merge branch 'master' into dev

This commit is contained in:
calzoneman 2013-08-19 00:23:13 -05:00
commit d62931098d
15 changed files with 212 additions and 156 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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 == "--:--") {

View File

@ -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"
},

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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();
});

View File

@ -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 */

View File

@ -758,7 +758,7 @@ Callbacks = {
}
makeAlert("Error", data, "alert-error")
.addClass("span12")
.insertAfter($("#mediaurl").parent());
.insertBefore($("#extended_controls"));
},
setTemp: function(data) {

View File

@ -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;

View File

@ -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() {

View File

@ -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>

View File

@ -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>