website_forum/populate/forum_post.py

85 lines
3.5 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
from odoo import fields, models
from odoo.tools import populate
QA_WEIGHTS = {0: 25, 1: 35, 2: 20, 3: 10, 4: 4, 5: 3, 6: 2, 7: 1}
_logger = logging.getLogger(__name__)
class Post(models.Model):
_inherit = 'forum.post'
# Include an additional average of 2 post answers for each given size
# e.g.: 100 posts as populated_model_records = ~300 actual forum.posts records
_populate_sizes = {'small': 100, 'medium': 1000, 'large': 90000}
_populate_dependencies = ['forum.forum', 'res.users']
def _populate_factories(self):
forum_ids = self.env.registry.populated_models['forum.forum']
hours = [_ for _ in range(1, 49)]
random = populate.Random('forum_posts')
def create_answers(values=None, **kwargs):
"""Create random number of answers
We set the `last_activity_date` to convert it to `create_date` in `_populate`
as the ORM prevents setting these.
"""
return [
fields.Command.create({
'name': f"reply to {values['name']}",
'forum_id': values['forum_id'],
'content': 'Answer content',
'last_activity_date': fields.Datetime.add(values['last_activity_date'], hours=random.choice(hours)),
})
for _ in range(random.choices(*zip(*QA_WEIGHTS.items()))[0])
]
def get_last_activity_date(iterator, *args):
days = [_ for _ in range(3, 93)]
now = fields.Datetime.now()
for values in iterator:
values.update(last_activity_date=fields.Datetime.subtract(now, days=random.choice(days)))
yield values
return [
('forum_id', populate.randomize(forum_ids)),
('name', populate.constant('post_{counter}')),
('last_activity_date', get_last_activity_date), # Must be before call to 'create_answers'
('child_ids', populate.compute(create_answers)),
]
def _populate(self, size):
records = super()._populate(size)
user_ids = self.env.registry.populated_models['res.users']
# Overwrite auto-fields: use last_activity_date to update create date
_logger.info('forum.post: update create date and uid')
question_ids = tuple(records.ids)
query = """
SELECT setseed(0.5);
UPDATE forum_post
SET create_date = last_activity_date,
create_uid = floor(random() * (%(max_value)s - %(min_value)s + 1) + %(min_value)s)
WHERE id in %(question_ids)s or parent_id in %(question_ids)s
"""
self.env.cr.execute(query, {'question_ids': question_ids, 'min_value': user_ids[0], 'max_value': user_ids[-1]})
_logger.info('forum.post: update last_activity_date of questions with answers')
query = """
WITH latest_answer AS(
SELECT parent_id, max(last_activity_date) as answer_date
FROM forum_post
WHERE parent_id in %(question_ids)s
GROUP BY parent_id
)
UPDATE forum_post fp
SET last_activity_date = latest_answer.answer_date
FROM latest_answer
WHERE fp.id = latest_answer.parent_id
"""
self.env.cr.execute(query, {'question_ids': question_ids})
return records