From 7f2d4f2ce57d9564baf789278012dfa4bb355a38 Mon Sep 17 00:00:00 2001 From: tpa-odoo Date: Wed, 17 Sep 2014 11:48:04 +0530 Subject: [PATCH] [ADD] website_forum: added new funtionality to post Articles and Discussions also on forum insted of only questions. On articles and discussions users kan post multiple reply on each post insted on only one reply per post and users will able to post reply on any other reply. in list posts will be default sorted by relevancy. show introduction message when people not logged in. --- addons/website_forum/controllers/main.py | 111 +++--- addons/website_forum/data/forum_data.xml | 4 +- addons/website_forum/models/forum.py | 26 ++ .../static/src/js/website_forum.js | 34 +- addons/website_forum/views/forum.xml | 3 + addons/website_forum/views/website_forum.xml | 360 ++++++++++++------ 6 files changed, 365 insertions(+), 173 deletions(-) diff --git a/addons/website_forum/controllers/main.py b/addons/website_forum/controllers/main.py index ea68250b986..b263cd96312 100644 --- a/addons/website_forum/controllers/main.py +++ b/addons/website_forum/controllers/main.py @@ -5,6 +5,8 @@ import werkzeug.urls import werkzeug.wrappers import re import simplejson +import lxml +from urllib2 import urlopen from openerp import tools from openerp import SUPERUSER_ID @@ -40,6 +42,7 @@ class WebsiteForum(http.Controller): 'notifications': self._get_notifications(), 'header': kwargs.get('header', dict()), 'searches': kwargs.get('searches', dict()), + 'no_introduction_message': request.session.get('no_introduction_message', False), } if forum: values['forum'] = forum @@ -76,7 +79,7 @@ class WebsiteForum(http.Controller): '''/forum//tag//tag//ask'], type='http', auth="public", website=True) - def question_ask(self, forum, **post): - if not request.session.uid: - return login_redirect() - values = self._prepare_forum_values(forum=forum, searches={}, header={'ask_hide': True}) - return request.website.render("website_forum.ask_question", values) + @http.route('/forum/get_url_title', type='json', auth="user", methods=['POST'], website=True) + def get_url_title(self, **kwargs): + arch = lxml.html.parse(urlopen(kwargs.get('url'))) + return arch.find(".//title").text - @http.route('/forum//question/new', type='http', auth="user", methods=['POST'], website=True) - def question_create(self, forum, **post): - cr, uid, context = request.cr, request.uid, request.context - Tag = request.registry['forum.tag'] - question_tag_ids = [] - if post.get('question_tags').strip('[]'): - tags = post.get('question_tags').strip('[]').replace('"', '').split(",") - for tag in tags: - tag_ids = Tag.search(cr, uid, [('name', '=', tag)], context=context) - if tag_ids: - question_tag_ids.append((4, tag_ids[0])) - else: - question_tag_ids.append((0, 0, {'name': tag, 'forum_id': forum.id})) - - new_question_id = request.registry['forum.post'].create( - request.cr, request.uid, { - 'forum_id': forum.id, - 'name': post.get('question_name'), - 'content': post.get('content'), - 'tag_ids': question_tag_ids, - }, context=context) - return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), new_question_id)) + @http.route('/forum/remove_introduction_message', type='json', auth="public", methods=['POST'], website=True) + def remove_introduction_message(self, **kwargs): + request.session['no_introduction_message'] = True + return True @http.route(['''/forum//question//question//edit_answer', type='http', auth="user", website=True) def question_edit_answer(self, forum, question, **kwargs): @@ -274,21 +267,45 @@ class WebsiteForum(http.Controller): # Post # -------------------------------------------------- - @http.route('/forum//post//new', type='http', auth="public", methods=['POST'], website=True) - def post_new(self, forum, post, **kwargs): + @http.route(['/forum//'], type='http', auth="public", website=True) + def forum_post(self, forum, post_type, **post): if not request.session.uid: return login_redirect() cr, uid, context = request.cr, request.uid, request.context user = request.registry['res.users'].browse(cr, SUPERUSER_ID, uid, context=context) if not user.email or not tools.single_email_re.match(user.email): return werkzeug.utils.redirect("/forum/%s/user/%s/edit?email_required=1" % (slug(forum), uid)) - request.registry['forum.post'].create( - request.cr, request.uid, { + values = self._prepare_forum_values(forum=forum, searches={}, header={'ask_hide': True}) + return request.website.render("website_forum.%s" % post_type, values) + + @http.route(['/forum///new', + '/forum///reply'] + , type='http', auth="public", methods=['POST'], website=True) + def post_create(self, forum, post_parent='', post_type='', **post): + cr, uid, context = request.cr, request.uid, request.context + if not request.session.uid: + return login_redirect() + + post_tag_ids = [] + Tag = request.registry['forum.tag'] + if post.get('post_tags', False) and post.get('post_tags').strip('[]'): + tags = post.get('post_tags').strip('[]').replace('"', '').split(",") + for tag in tags: + tag_ids = Tag.search(cr, uid, [('name', '=', tag)], context=context) + if tag_ids: + post_tag_ids.append((4, tag_ids[0])) + else: + post_tag_ids.append((0, 0, {'name': tag, 'forum_id': forum.id})) + + new_question_id = request.registry['forum.post'].create(cr, uid, { 'forum_id': forum.id, - 'parent_id': post.id, - 'content': kwargs.get('content'), - }, context=request.context) - return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), slug(post))) + 'name': post.get('post_name', ''), + 'content': post.get('content'), + 'parent_id': post_parent and post_parent.id or False, + 'tag_ids': post_tag_ids, + 'type': post_parent and post_parent.type or post_type, + }, context=context) + return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), post_parent and slug(post_parent) or new_question_id)) @http.route('/forum//post//comment', type='http', auth="public", methods=['POST'], website=True) def post_comment(self, forum, post, **kwargs): @@ -344,20 +361,20 @@ class WebsiteForum(http.Controller): @http.route('/forum//post//save', type='http', auth="user", methods=['POST'], website=True) def post_save(self, forum, post, **kwargs): cr, uid, context = request.cr, request.uid, request.context - question_tags = [] - if kwargs.get('question_tag') and kwargs.get('question_tag').strip('[]'): + post_tags = [] + if kwargs.get('post_tag') and kwargs.get('post_tag').strip('[]'): Tag = request.registry['forum.tag'] - tags = kwargs.get('question_tag').strip('[]').replace('"', '').split(",") + tags = kwargs.get('post_tag').strip('[]').replace('"', '').split(",") for tag in tags: tag_ids = Tag.search(cr, uid, [('name', '=', tag)], context=context) if tag_ids: - question_tags += tag_ids + post_tags += tag_ids else: new_tag = Tag.create(cr, uid, {'name': tag, 'forum_id': forum.id}, context=context) - question_tags.append(new_tag) + post_tags.append(new_tag) vals = { - 'tag_ids': [(6, 0, question_tags)], - 'name': kwargs.get('question_name'), + 'tag_ids': [(6, 0, post_tags)], + 'name': kwargs.get('post_name'), 'content': kwargs.get('content'), } request.registry['forum.post'].write(cr, uid, [post.id], vals, context=context) diff --git a/addons/website_forum/data/forum_data.xml b/addons/website_forum/data/forum_data.xml index 61bb7ee0fb4..1b08846160e 100644 --- a/addons/website_forum/data/forum_data.xml +++ b/addons/website_forum/data/forum_data.xml @@ -76,7 +76,7 @@ - duplicate question + duplicate post off-topic or not relevant @@ -85,7 +85,7 @@ too subjective and argumentative - not a real question + not a real post not relevant or out dated diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py index 92fd1f62efc..f9f55cba292 100644 --- a/addons/website_forum/models/forum.py +++ b/addons/website_forum/models/forum.py @@ -26,6 +26,9 @@ class Forum(osv.Model): 'name': fields.char('Name', required=True, translate=True), 'faq': fields.html('Guidelines'), 'description': fields.html('Description'), + 'introduction_message': fields.html('Introduction Message'), + 'relevancy_option_first': fields.float('First Relevancy Parameter'), + 'relevancy_option_second': fields.float('Second Relevancy Parameter'), # karma generation 'karma_gen_question_new': fields.integer('Karma earned for new questions'), 'karma_gen_question_upvote': fields.integer('Karma earned for upvoting a question'), @@ -69,6 +72,13 @@ class Forum(osv.Model): _defaults = { 'description': 'This community is for professionals and enthusiasts of our products and services.', 'faq': _get_default_faq, + 'introduction_message': """

Welcome to Odoo Forum

+

This community is for professionals and enthusiasts of our products and services. + Share and discuss the best content and new marketing ideas, + build your professional profile and become a better marketer together. +

""", + 'relevancy_option_first': 0.8, + 'relevancy_option_second': 1.8, 'karma_gen_question_new': 2, 'karma_gen_question_upvote': 5, 'karma_gen_question_downvote': -2, @@ -114,6 +124,14 @@ class Post(osv.Model): _inherit = ['mail.thread', 'website.seo.metadata'] _order = "is_correct DESC, vote_count DESC, write_date DESC" + def _get_post_relevancy(self, cr, uid, ids, field_name, arg, context): + res = dict.fromkeys(ids, 0) + for post in self.browse(cr, uid, ids, context=context): + days = (datetime.today() - datetime.strptime(post.create_date, tools.DEFAULT_SERVER_DATETIME_FORMAT)).days + relavency = abs(post.vote_count - 1) ** post.forum_id.relevancy_option_first / ( days + 2) ** post.forum_id.relevancy_option_second + res[post.id] = relavency if (post.vote_count - 1) >= 0 else -relavency + return res + def _get_user_vote(self, cr, uid, ids, field_name, arg, context): res = dict.fromkeys(ids, 0) vote_ids = self.pool['forum.post.vote'].search(cr, uid, [('post_id', 'in', ids), ('user_id', '=', uid)], context=context) @@ -220,6 +238,13 @@ class Post(osv.Model): 'state': fields.selection([('active', 'Active'), ('close', 'Close'), ('offensive', 'Offensive')], 'Status'), 'views': fields.integer('Number of Views'), 'active': fields.boolean('Active'), + 'type': fields.selection([('question', 'Question'), ('link', 'Article'), ('discussion', 'Discussion')], 'Type'), + 'relevancy': fields.function( + _get_post_relevancy, string="Relevancy", type='float', + store={ + 'forum.post': (lambda self, cr, uid, ids, c={}: ids, ['vote_ids'], 10), + 'forum.post.vote': (_get_post_from_vote, [], 10), + }), 'is_correct': fields.boolean('Valid Answer', help='Correct Answer or Answer on this question accepted.'), 'website_message_ids': fields.one2many( 'mail.message', 'res_id', @@ -304,6 +329,7 @@ class Post(osv.Model): 'state': 'active', 'views': 0, 'active': True, + 'type': 'question', 'vote_ids': list(), 'favourite_ids': list(), 'child_ids': list(), diff --git a/addons/website_forum/static/src/js/website_forum.js b/addons/website_forum/static/src/js/website_forum.js index de4e1b2b9db..6e9ab6b6ac4 100644 --- a/addons/website_forum/static/src/js/website_forum.js +++ b/addons/website_forum/static/src/js/website_forum.js @@ -109,6 +109,33 @@ $(document).ready(function () { return true; }); + $('.close_introduction_message').on('click', function (ev) { + ev.preventDefault(); + var $link = $(ev.currentTarget); + openerp.jsonRpc("/forum/remove_introduction_message", 'call', {}) + return true; + }); + + $('.link_url').on('change', function (ev) { + ev.preventDefault(); + var $link = $(ev.currentTarget); + if ($link.attr("value").search("^http(s?)://.*")) { + var $warning = $('
'+ + ''+ + 'Please enter valid URl.'+ + '
'); + $link.parent().append($warning); + $link.parent().find("button#btn_post_your_article")[0].disabled = true; + $link.parent().find("input[name='content']")[0].value = ''; + } else { + openerp.jsonRpc("/forum/get_url_title", 'call', {'url': $link.attr("value")}).then(function (data) { + $link.parent().find("input[name='content']")[0].value = data; + $('button').prop('disabled', false); + $('input').prop('readonly', false); + }); + } + }); + if($('input.load_tags').length){ var tags = $("input.load_tags").val(); $("input.load_tags").val(""); @@ -174,8 +201,11 @@ $(document).ready(function () { } if ($('textarea.load_editor').length) { - var editor = CKEDITOR.instances['content']; - editor.on('instanceReady', CKEDITORLoadComplete); + $('textarea.load_editor').each(function () { + if (this['id']) { + CKEDITOR.replace(this['id']).on('instanceReady', CKEDITORLoadComplete); + } + }); } } }); diff --git a/addons/website_forum/views/forum.xml b/addons/website_forum/views/forum.xml index a2d7c093a7f..33d246b6916 100644 --- a/addons/website_forum/views/forum.xml +++ b/addons/website_forum/views/forum.xml @@ -24,6 +24,8 @@ + + @@ -107,6 +109,7 @@ + diff --git a/addons/website_forum/views/website_forum.xml b/addons/website_forum/views/website_forum.xml index 995c12708f5..860ce8192ee 100644 --- a/addons/website_forum/views/website_forum.xml +++ b/addons/website_forum/views/website_forum.xml @@ -48,6 +48,15 @@
+
+
+ +
+
+ Sign in +
+
+