diff --git a/src/install.js b/src/install.js
index 14d368c422..889d5e2639 100644
--- a/src/install.js
+++ b/src/install.js
@@ -217,6 +217,9 @@ var async = require('async'),
}, {
field: 'allowGuestSearching',
value: 0
+ }, {
+ field: 'allowTopicsThumbnail',
+ value: 0
}, {
field: 'allowRegistration',
value: 1
diff --git a/src/meta.js b/src/meta.js
index fd344b460e..2be4df4b20 100644
--- a/src/meta.js
+++ b/src/meta.js
@@ -4,6 +4,7 @@ var fs = require('fs'),
winston = require('winston'),
nconf = require('nconf'),
+ translator = require('../public/src/translator'),
utils = require('./../public/src/utils'),
db = require('./database'),
plugins = require('./plugins'),
diff --git a/src/postTools.js b/src/postTools.js
index c01e0f4a8f..303ab53dcf 100644
--- a/src/postTools.js
+++ b/src/postTools.js
@@ -64,7 +64,9 @@ var winston = require('winston'),
}
- PostTools.edit = function(uid, pid, title, content) {
+ PostTools.edit = function(uid, pid, title, content, options) {
+ options || (options = {});
+
var websockets = require('./socket.io'),
success = function() {
posts.setPostFields(pid, {
@@ -85,6 +87,12 @@ var winston = require('winston'),
topics.setTopicField(tid, 'title', title);
topics.setTopicField(tid, 'slug', slug);
+
+ topics.setTopicField(tid, 'thumb', options.topic_thumb);
+
+ db.searchRemove('topic', tid, function() {
+ db.searchIndex('topic', title, tid);
+ });
}
posts.getPostData(pid, function(err, postData) {
diff --git a/src/posts.js b/src/posts.js
index 7103db2047..441b638e82 100644
--- a/src/posts.js
+++ b/src/posts.js
@@ -2,9 +2,7 @@ var db = require('./database'),
utils = require('./../public/src/utils'),
user = require('./user'),
topics = require('./topics'),
- categories = require('./categories'),
favourites = require('./favourites'),
- threadTools = require('./threadTools'),
postTools = require('./postTools'),
categories = require('./categories'),
plugins = require('./plugins'),
diff --git a/src/routes/api.js b/src/routes/api.js
index 1817cc15db..57336503df 100644
--- a/src/routes/api.js
+++ b/src/routes/api.js
@@ -11,7 +11,7 @@ var path = require('path'),
ThreadTools = require('../threadTools'),
posts = require('../posts'),
categories = require('../categories'),
- categoryTools = require('../categoryTools')
+ categoryTools = require('../categoryTools'),
meta = require('../meta'),
Plugins = require('../plugins'),
utils = require('../../public/src/utils'),
@@ -57,6 +57,7 @@ var path = require('path'),
config.useOutgoingLinksPage = parseInt(meta.config.useOutgoingLinksPage, 10) === 1;
config.allowGuestPosting = parseInt(meta.config.allowGuestPosting, 10) === 1;
config.allowFileUploads = parseInt(meta.config.allowFileUploads, 10) === 1;
+ config.allowTopicsThumbnail = parseInt(meta.config.allowTopicsThumbnail, 10) === 1;
config.usePagination = parseInt(meta.config.usePagination, 10) === 1;
config.topicsPerPage = meta.config.topicsPerPage || 20;
config.postsPerPage = meta.config.postsPerPage || 20;
@@ -424,7 +425,7 @@ var path = require('path'),
}
});
- app.post('/post/upload', function(req, res, next) {
+ function upload(req, res, filesIterator, next) {
if(!req.user) {
return res.json(403, {message:'not allowed'});
}
@@ -445,21 +446,33 @@ var path = require('path'),
}
}
- async.map(files, function(file, next) {
+ async.map(files, filesIterator, function(err, images) {
+ deleteTempFiles();
+ if(err) {
+ return res.json(500, err.message);
+ }
+ res.json(200, images);
+ });
+ }
+
+ app.post('/post/upload', function(req, res, next) {
+ upload(req, res, function(file, next) {
if(file.type.match('image.*')) {
posts.uploadPostImage(file, next);
} else {
posts.uploadPostFile(file, next);
}
- }, function(err, images) {
- deleteTempFiles();
+ }, next)
+ });
- if(err) {
- return res.json(500, err.message);
+ app.post('/topic/thumb/upload', function(req, res, next) {
+ upload(req, res, function(file, next) {
+ if(file.type.match('image.*')) {
+ topics.uploadTopicThumb(file, next);
+ } else {
+ res.json(500, {message: 'Invalid File'});
}
-
- res.json(200, images);
- });
+ }, next);
});
app.get('/reset', function (req, res) {
diff --git a/src/socket.io/modules.js b/src/socket.io/modules.js
index a222f51d93..c5e23dc92b 100644
--- a/src/socket.io/modules.js
+++ b/src/socket.io/modules.js
@@ -29,19 +29,21 @@ SocketModules.composer.push = function(socket, pid, callback) {
posts.getPostFields(pid, ['content'], next);
},
function(next) {
- topics.getTitleByPid(pid, function(title) {
- next(null, title);
- });
+ topics.getTopicDataByPid(pid, next);
+ },
+ function(next) {
+ posts.getPidIndex(pid, next);
}
], function(err, results) {
if(err) {
return callback(err);
}
-
callback(null, {
- title: results[1],
pid: pid,
- body: results[0].content
+ body: results[0].content,
+ title: results[1].title,
+ topic_thumb: results[1].thumb,
+ index: results[2]
});
});
}
diff --git a/src/socket.io/posts.js b/src/socket.io/posts.js
index b0685b371d..2d10ec91b1 100644
--- a/src/socket.io/posts.js
+++ b/src/socket.io/posts.js
@@ -148,7 +148,7 @@ SocketPosts.edit = function(socket, data, callback) {
return callback(new Error('content-too-short'));
}
- postTools.edit(socket.uid, data.pid, data.title, data.content);
+ postTools.edit(socket.uid, data.pid, data.title, data.content, {topic_thumb: data.topic_thumb});
callback();
};
diff --git a/src/socket.io/topics.js b/src/socket.io/topics.js
index 310a924b22..0950e9fd6c 100644
--- a/src/socket.io/topics.js
+++ b/src/socket.io/topics.js
@@ -24,7 +24,7 @@ SocketTopics.post = function(socket, data, callback) {
return callback(new Error('not-logged-in'));
}
- topics.post(socket.uid, data.title, data.content, data.category_id, function(err, result) {
+ topics.post({uid: socket.uid, title: data.title, content: data.content, cid: data.category_id, thumb: data.topic_thumb}, function(err, result) {
if(err) {
if (err.message === 'title-too-short') {
module.parent.exports.emitAlert(socket, 'Title too short', 'Please enter a longer title. At least ' + meta.config.minimumTitleLength + ' characters.');
diff --git a/src/topics.js b/src/topics.js
index 35cc490fb0..3d6f1ebff1 100644
--- a/src/topics.js
+++ b/src/topics.js
@@ -1,5 +1,6 @@
var async = require('async'),
gravatar = require('gravatar'),
+ path = require('path'),
nconf = require('nconf'),
validator = require('validator'),
S = require('string'),
@@ -8,6 +9,7 @@ var async = require('async'),
db = require('./database'),
posts = require('./posts'),
utils = require('./../public/src/utils'),
+ plugins = require('./plugins'),
user = require('./user'),
categories = require('./categories'),
categoryTools = require('./categoryTools'),
@@ -21,7 +23,12 @@ var async = require('async'),
(function(Topics) {
- Topics.create = function(uid, title, cid, callback) {
+ Topics.create = function(data, callback) {
+ var uid = data.uid,
+ title = data.title,
+ cid = data.cid,
+ thumb = data.thumb;
+
db.incrObjectField('global', 'nextTid', function(err, tid) {
if(err) {
return callback(err);
@@ -42,7 +49,8 @@ var async = require('async'),
'viewcount': 0,
'locked': 0,
'deleted': 0,
- 'pinned': 0
+ 'pinned': 0,
+ 'thumb': thumb || ''
}, function(err) {
if(err) {
return callback(err);
@@ -62,7 +70,13 @@ var async = require('async'),
});
};
- Topics.post = function(uid, title, content, cid, callback) {
+ Topics.post = function(data, callback) {
+ var uid = data.uid,
+ title = data.title,
+ content = data.content,
+ cid = data.cid,
+ thumb = data.thumb;
+
if (title) {
title = title.trim();
}
@@ -99,7 +113,7 @@ var async = require('async'),
user.isReadyToPost(uid, next);
},
function(next) {
- Topics.create(uid, title, cid, next);
+ Topics.create({uid: uid, title: title, cid: cid, thumb: thumb}, next);
},
function(tid, next) {
Topics.reply(tid, uid, content, next);
@@ -211,7 +225,7 @@ var async = require('async'),
posts.getCidByPid(mainPid, callback);
}
}, function(err, results) {
- Topics.create(results.postData.uid, title, results.cid, function(err, tid) {
+ Topics.create({uid: results.postData.uid, title: title, cid: results.cid}, function(err, tid) {
if(err) {
return callback(err);
}
@@ -807,6 +821,7 @@ var async = require('async'),
'pinned': topicData.pinned,
'timestamp': topicData.timestamp,
'slug': topicData.slug,
+ 'thumb': topicData.thumb,
'postcount': topicData.postcount,
'viewcount': topicData.viewcount,
'pageCount': pageCount,
@@ -895,13 +910,43 @@ var async = require('async'),
};
Topics.getTitleByPid = function(pid, callback) {
+ Topics.getTopicFieldByPid('title', pid, callback);
+ };
+
+ Topics.getTopicFieldByPid = function(field, pid, callback) {
posts.getPostField(pid, 'tid', function(err, tid) {
- Topics.getTopicField(tid, 'title', function(err, title) {
- callback(title);
- });
+ Topics.getTopicField(tid, field, callback);
});
};
+ Topics.getTopicDataByPid = function(pid, callback) {
+ posts.getPostField(pid, 'tid', function(err, tid) {
+ Topics.getTopicData(tid, callback);
+ });
+ };
+
+ Topics.uploadTopicThumb = function(image, callback) {
+
+ if(plugins.hasListeners('filter:uploadImage')) {
+ plugins.fireHook('filter:uploadImage', image, callback);
+ } else {
+ if (meta.config.allowTopicsThumbnail) {
+ var filename = 'upload-' + utils.generateUUID() + path.extname(image.name);
+ require('./file').saveFileToLocal(filename, image.path, function(err, upload) {
+ if(err) {
+ return callback(err);
+ }
+ callback(null, {
+ url: upload.url,
+ name: image.name
+ });
+ });
+ } else {
+ callback(new Error('Topic Thumbnails are disabled!'));
+ }
+ }
+ };
+
Topics.markAsUnreadForAll = function(tid, callback) {
db.delete('tid:' + tid + ':read_by_uid', function(err) {
if(err) {
diff --git a/src/webserver.js b/src/webserver.js
index f1404651b0..01a779e972 100644
--- a/src/webserver.js
+++ b/src/webserver.js
@@ -677,7 +677,7 @@ module.exports.server = server;
posts: topicData
});
});
- },
+ }
], function (err, data) {
if (err) {
if (err.message === 'not-enough-privileges') {
@@ -927,7 +927,7 @@ module.exports.server = server;
return custom_routes.templates.map(function(tpl) {
return tpl.template.split('.tpl')[0];
});
- }
+ };
plugins.ready(function() {
plugins.fireHook('filter:server.create_routes', custom_routes, function(err, custom_routes) {
diff --git a/tests/topics.js b/tests/topics.js
index 9d27db8cf7..92404ee393 100644
--- a/tests/topics.js
+++ b/tests/topics.js
@@ -25,7 +25,7 @@ describe('Topic\'s', function() {
describe('.post', function() {
it('should create a new topic with proper parameters', function(done) {
- Topics.post(topic.userId, topic.title, topic.content, topic.categoryId, function(err, result) {
+ Topics.post({uid: topic.userId, title: topic.title, content: topic.content, cid: topic.categoryId}, function(err, result) {
assert.equal(err, null, 'was created with error');
assert.ok(result);
@@ -36,7 +36,7 @@ describe('Topic\'s', function() {
it('should fail to create new topic with wrong parameters', function(done) {
topic.userId = null;
- Topics.post(topic.userId, topic.title, topic.content, topic.categoryId, function(err, result) {
+ Topics.post({uid: topic.userId, title: topic.title, content: topic.content, cid: topic.categoryId}, function(err, result) {
assert.equal(err.message, 'invalid-user');
done();
});
@@ -48,7 +48,7 @@ describe('Topic\'s', function() {
var newPost;
beforeEach(function(done){
- Topics.post(topic.userId, topic.title, topic.content, topic.categoryId, function(err, result) {
+ Topics.post({uid: topic.userId, title: topic.title, content: topic.content, cid: topic.categoryId}, function(err, result) {
newTopic = result.topicData;
newPost = result.postData;
done();