1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/social/models/social_stream.py
2024-12-10 09:04:09 +07:00

91 lines
4.2 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
import requests
from odoo import models, fields, api
_logger = logging.getLogger(__name__)
class SocialStream(models.Model):
""""social.streams are used to fill the 'Feed' view that allows users to follow the social.media activity
based on their interest (a Facebook Page, a Twitter hashtag, ...).
They use the social.media third party API to fetch the stream data and create social.stream.posts
that are displayed on the Feed kanban view. """
_name = 'social.stream'
_description = 'Social Stream'
_order = 'sequence asc, id asc'
name = fields.Char("Title", translate=True)
media_id = fields.Many2one('social.media', string="Social Media", required=True)
media_image = fields.Binary(related='media_id.image', string="The related Social Media's image")
sequence = fields.Integer('Sequence', help="Sequence used to order streams (mainly for the 'Feed' kanban view)")
account_id = fields.Many2one('social.account', 'Social Account', required=True, ondelete='cascade')
stream_type_id = fields.Many2one('social.stream.type', string="Type", required=True, ondelete='cascade')
stream_type_type = fields.Char(related='stream_type_id.stream_type')
stream_post_ids = fields.One2many('social.stream.post', 'stream_id', 'Posts')
company_id = fields.Many2one('res.company', 'Company', related='account_id.company_id', store=True)
@api.onchange('media_id', 'account_id')
def _onchange_media_id(self):
for stream in self:
if stream.account_id and stream.account_id.media_id != stream.media_id:
stream.account_id = False
# Set stream_type_ids by default if only one type for the media.
stream_type_ids = self.env['social.stream.type'].search([('media_id', '=', stream.media_id.id)], limit=2)
stream.stream_type_id = stream_type_ids.id if len(stream_type_ids) == 1 else False
@api.model_create_multi
def create(self, vals_list):
res = super(SocialStream, self).create(vals_list)
res._apply_default_name()
for stream in res:
stream._fetch_stream_data()
return res
@api.model
def refresh_all(self):
""" Fetches the stream.post based on third party API endpoints (Facebook/Twitter/...) and inserts new stream.posts into database.
If any post is inserted into a stream created by the current user, the method returns 'True' to indicate caller that
changes were made and a refresh is required.
That means it will not always match the filter used on the view but it's the most common use case so it's not an issue.
(For cases when it does not match the user's filter, the view will need simple to be refreshed manually). """
new_content = False
for stream in self.env['social.stream'].search([]):
# as refreshing the streams is a recurring task, we ignore occasional "read timeouts"
# from the third party services, as it would most likely mean a temporary slow connection
# and/or a slow response from their side
try:
new_content |= stream._fetch_stream_data()
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
_logger.warning("Failed to fetch %s data.", stream.name, exc_info=True)
return new_content
def _fetch_stream_data(self):
""" Every social module should override this method.
This is the method responsible for creating the social.stream.posts using the social.media
third party API.
It will be called manually every time we need to refresh the social.stream data:
- social.stream creation/edition
- 'Feed' kanban loading
- 'Refresh' button on 'Feed' kanban
- ...
This method should return 'True' if new social.posts are inserted, please check the 'refresh_all' method for
further implementation instructions. """
self.ensure_one()
def _apply_default_name(self):
for stream in self:
stream.write({'name': stream.stream_type_id.name})