Merge branch 'master' of github.com:designcreateplay/NodeBB

v1.18.x
Julian Lam 11 years ago
commit e3fb996a80

@ -109,11 +109,11 @@
var customTemplates = meta.config['theme:templates'] ? path.join(__dirname, 'node_modules', meta.config['theme:id'], meta.config['theme:templates']) : false;
utils.walk(path.join(__dirname, 'public/templates'), function (err, tplsToLoad) {
templates.init(tplsToLoad, customTemplates);
});
plugins.ready(function() {
templates.ready(webserver.init);
});

@ -7,6 +7,7 @@
"location": "Location",
"age": "Age",
"joined": "Joined",
"lastonline": "Last Online",
"profile_views": "Profile views",
"reputation": "Reputation",
"posts": "Posts",

@ -48,7 +48,6 @@ define(['taskbar'], function(taskbar) {
socket.emit('api:composer.push', {
pid: pid
}, function(threadData) {
console.log(threadData);
push({
pid: pid,
title: threadData.title,
@ -202,7 +201,7 @@ define(['taskbar'], function(taskbar) {
}
});
postContainer.on('click', '.formatting-bar span .fa-picture-o', function() {
postContainer.on('click', '.formatting-bar span .fa-picture-o, .formatting-bar span .fa-upload', function() {
$('#files').click();
});
@ -213,6 +212,7 @@ define(['taskbar'], function(taskbar) {
loadFile(post_uuid, files[i]);
}
}
$('#fileForm')[0].reset();
});
@ -317,7 +317,12 @@ define(['taskbar'], function(taskbar) {
}
if(config.imgurClientIDSet) {
postContainer.find('.upload-instructions').removeClass('hide')
postContainer.find('.upload-instructions').removeClass('hide');
postContainer.find('.img-upload-btn').removeClass('hide');
}
if(config.allowFileUploads) {
postContainer.find('.file-upload-btn').removeClass('hide');
}
postContainer.css('visibility', 'visible');
@ -469,36 +474,41 @@ define(['taskbar'], function(taskbar) {
}
function loadFile(post_uuid, file) {
if (!file.type.match('image.*')) {
return;
}
var reader = new FileReader(),
dropDiv = $('#cmp-uuid-' + post_uuid).find('.imagedrop');
$(reader).on('loadend', function(e) {
var bin = this.result.split(',')[1];
var regex = /^data:.*;base64,(.*)$/;
console.log(file);
var matches = this.result.match(regex);
var img = {
var fileData = {
name: file.name,
data: bin
data: matches[1]
};
createImagePlaceholder(post_uuid, img);
dropDiv.hide();
if(file.type.match('image.*')) {
uploadFile('api:posts.uploadImage', post_uuid, fileData);
} else {
if(file.size > parseInt(config.maximumFileSize, 10) * 1024) {
return composerAlert('File too big', 'Maximum allowed file size is ' + config.maximumFileSize + 'kbs');
}
uploadFile('api:posts.uploadFile', post_uuid, fileData);
}
});
reader.readAsDataURL(file);
}
function createImagePlaceholder(post_uuid, img) {
var postContainer = $('#cmp-uuid-' + post_uuid),
function uploadFile(method, post_uuid, img) {
var linkStart = method === 'api:posts.uploadImage' ? '!' : '',
postContainer = $('#cmp-uuid-' + post_uuid),
textarea = postContainer.find('textarea'),
text = textarea.val(),
imgText = "![" + img.name + "](uploading...)";
imgText = linkStart + '[' + img.name + '](uploading...)';
text += imgText;
textarea.val(text + " ");
@ -509,18 +519,17 @@ define(['taskbar'], function(taskbar) {
composer.posts[post_uuid].uploadsInProgress.push(1);
socket.emit("api:posts.uploadImage", img, function(err, data) {
socket.emit(method, img, function(err, data) {
var currentText = textarea.val();
if(err) {
textarea.val(currentText.replace(imgText, linkStart + '[' + img.name + '](upload error)'));
return app.alertError(err.message);
}
var currentText = textarea.val();
imgText = "![" + data.name + "](uploading...)";
if(!err) {
textarea.val(currentText.replace(imgText, "![" + data.name + "](" + data.url + ")"));
} else {
textarea.val(currentText.replace(imgText, "![" + data.name + "](upload error)"));
}
textarea.val(currentText.replace(imgText, linkStart + '[' + data.name + '](' + data.url + ')'));
composer.posts[post_uuid].uploadsInProgress.pop();
});
}

@ -70,6 +70,10 @@
<span class="timeago" title="{joindate}"></span>
<br/>
<span class="account-bio-label">[[user:lastonline]]</span>
<span class="timeago" title="{lastonline}"></span>
<br/>
<span class="account-bio-label">[[user:profile_views]]</span>
<span class="formatted-number">{profileviews}</span>
<br/>

@ -121,6 +121,17 @@
<input type="checkbox" data-field="useOutgoingLinksPage"> <strong>Use Outgoing Links Warning Page</strong>
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" data-field="disableSocialButtons"> <strong>Disable social buttons on posts</strong>
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" data-field="allowFileUploads"> <strong>Allow users to upload regular files</strong>
</label>
</div>
<strong>Maximum File Size</strong><br /> <input type="text" class="form-control" value="2048" data-field="maximumFileSize"><br />
</div>
</form>

@ -7,10 +7,15 @@
<span class="btn btn-link" tabindex="-1"><i class="fa fa-italic"></i></span>
<span class="btn btn-link" tabindex="-1"><i class="fa fa-list"></i></span>
<span class="btn btn-link" tabindex="-1"><i class="fa fa-link"></i></span>
<span class="btn btn-link" tabindex="-1">
<input type="file" id="files" name="files[]" multiple class="hide"/>
<span class="btn btn-link img-upload-btn hide" tabindex="-1">
<i class="fa fa-picture-o"></i>
</span>
<span class="btn btn-link file-upload-btn hide" tabindex="-1">
<i class="fa fa-upload"></i>
</span>
<form id="fileForm">
<input type="file" id="files" name="files[]" multiple class="hide"/>
</form>
</div>
<!-- <div class="btn btn-link pull-right">Preview</div> -->
</div>

@ -86,9 +86,11 @@
<div class="pull-right">
<div class="btn-group post-tools">
<button class="btn btn-sm btn-default link" type="button" title="[[topic:link]]"><i class="fa fa-link"></i></button>
<!-- IF !disableSocialButtons -->
<button class="btn btn-sm btn-default facebook-share" type="button" title=""><i class="fa fa-facebook"></i></button>
<button class="btn btn-sm btn-default twitter-share" type="button" title=""><i class="fa fa-twitter"></i></button>
<button class="btn btn-sm btn-default google-share" type="button" title=""><i class="fa fa-google-plus"></i></button>
<!-- ENDIF !disableSocialButtons -->
</div>
<!-- IF posts.display_moderator_tools -->

@ -50,13 +50,20 @@
function createCollections() {
db.createCollection('objects', function(err, collection) {
if(err) {
winston.error("Error creating collection " + err.message);
winston.error('Error creating collection ' + err.message);
return;
}
if(collection) {
collection.ensureIndex({_key :1}, {background:true}, function(err, name){
collection.ensureIndex({_key :1}, {background:true}, function(err, name) {
if(err) {
winston.error('Error creating index ' + err.message);
}
});
collection.ensureIndex({'expireAt':1}, {expireAfterSeconds:0, background:true}, function(err, name) {
if(err) {
winston.error("Error creating index " + err.message);
winston.error('Error creating index ' + err.message);
}
});
}
@ -64,13 +71,13 @@
db.createCollection('search', function(err, collection) {
if(err) {
winston.error("Error creating collection " + err.message);
winston.error('Error creating collection ' + err.message);
return;
}
if(collection) {
collection.ensureIndex({content:'text'}, {background:true}, function(err, name){
if(err) {
winston.error("Error creating index " + err.message);
winston.error('Error creating index ' + err.message);
}
});
}
@ -241,6 +248,14 @@
});
}
module.expire = function(key, seconds, callback) {
module.expireAt(key, Math.round(Date.now() / 1000) + seconds, callback);
}
module.expireAt = function(key, timestamp, callback) {
module.setObjectField(key, 'expireAt', new Date(timestamp * 1000), callback);
}
//hashes
module.setObject = function(key, data, callback) {
data['_key'] = key;

@ -211,6 +211,14 @@
redisClient.keys(key, callback);
}
module.expire = function(key, seconds, callback) {
redisClient.expire(key, seconds, callback);
}
module.expireAt = function(key, timestamp, callback) {
redisClient.expireat(key, timestamp, callback);
}
//hashes
module.setObject = function(key, data, callback) {

@ -20,6 +20,7 @@ var request = require('request'),
try {
var response = JSON.parse(body);
if(response.success) {
callback(null, response.data);
} else {

@ -212,6 +212,12 @@ var async = require('async'),
}, {
field: 'allowRegistration',
value: 1
}, {
field: 'allowFileUploads',
value: 0,
}, {
filed: 'maximumFileSize',
value: 2048
}, {
field: 'minimumTitleLength',
value: 3

@ -12,6 +12,8 @@ var db = require('./database'),
meta = require('./meta'),
async = require('async'),
path = require('path'),
fs = require('fs'),
nconf = require('nconf'),
validator = require('validator'),
winston = require('winston'),
@ -358,6 +360,10 @@ var db = require('./database'),
Posts.uploadPostImage = function(image, callback) {
if(!meta.config.imgurClientID) {
return callback('imgurClientID not set', null);
}
if(!image) {
return callback('invalid image', null);
}
@ -374,6 +380,37 @@ var db = require('./database'),
});
}
Posts.uploadPostFile = function(file, callback) {
if(!meta.config.allowFileUploads) {
return callback('File uploads are not allowed');
}
if(!file) {
return callback('invalid file');
}
var buffer = new Buffer(file.data, 'base64');
if(buffer.length > parseInt(meta.config.maximumFileSize, 10) * 1024) {
return callback('File too big');
}
var filename = 'upload-' + utils.generateUUID() + path.extname(file.name);
var uploadPath = path.join(nconf.get('base_dir'), nconf.get('upload_path'), filename);
fs.writeFile(uploadPath, buffer, function (err) {
if(err) {
callback(err.message, null);
} else {
callback(null, {
url: nconf.get('upload_url') + filename,
name: file.name
});
}
});
}
Posts.getPostsByUid = function(uid, start, end, callback) {
user.getPostIds(uid, start, end, function(err, pids) {
if(err) {

@ -40,6 +40,8 @@ var path = require('path'),
config.useOutgoingLinksPage = meta.config.useOutgoingLinksPage;
config.allowGuestPosting = meta.config.allowGuestPosting;
config.allowRegistration = meta.config.allowRegistration || '1';
config.allowFileUploads = meta.config.allowFileUploads;
config.maximumFileSize = meta.config.maximumFileSize;
config.emailSetup = !!meta.config['email:from'];
res.json(200, config);

@ -530,6 +530,11 @@ var fs = require('fs'),
user.getUserData(uid, function (err, data) {
if (data) {
data.joindate = new Date(parseInt(data.joindate, 10)).toISOString();
if(data.lastonline) {
data.lastonline = new Date(parseInt(data.lastonline, 10)).toISOString();
} else {
data.lastonline = data.joindate;
}
if (!data.birthday) {
data.age = '';

@ -667,6 +667,7 @@ var async = require('async'),
'unreplied': parseInt(topicData.postcount, 10) > 1,
'topic_id': tid,
'expose_tools': privileges.editable ? 1 : 0,
'disableSocialButtons': meta.config.disableSocialButtons !== undefined ? parseInt(meta.config.disableSocialButtons, 10) !== 0 : false,
'posts': topicPosts
});
});

@ -14,7 +14,7 @@ var db = require('./database'),
Upgrade.check = function(callback) {
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema
var latestSchema = new Date(2013, 11, 31).getTime();
var latestSchema = new Date(2014, 0, 1).getTime();
db.get('schemaDate', function(err, value) {
if (parseInt(value, 10) >= latestSchema) {

@ -188,6 +188,13 @@ var path = require('path'),
// Authentication Routes
auth.initialize(app);
app.use(function(req, res, next) {
if(req.user) {
user.setUserField(req.user.uid, 'lastonline', Date.now());
}
next();
})
next();
},
function(next) {

@ -638,6 +638,10 @@ websockets.init = function(io) {
posts.uploadPostImage(data, callback);
});
socket.on('api:posts.uploadFile', function(data, callback) {
posts.uploadPostFile(data, callback);
});
socket.on('api:posts.getRawPost', function(data, callback) {
posts.getPostField(data.pid, 'content', function(err, raw) {
callback({

Loading…
Cancel
Save