forked from Mapan/odoo17e
91 lines
4.2 KiB
Python
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})
|