forked from Mapan/odoo17e
157 lines
5.6 KiB
Python
157 lines
5.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
import ast
|
|
import logging
|
|
import re
|
|
import requests
|
|
|
|
from odoo import models, fields, api
|
|
from odoo.exceptions import UserError
|
|
from werkzeug.urls import url_join
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class SocialLivePostTwitter(models.Model):
|
|
_inherit = 'social.live.post'
|
|
|
|
twitter_tweet_id = fields.Char('Twitter tweet id')
|
|
|
|
def _compute_live_post_link(self):
|
|
twitter_live_posts = self._filter_by_media_types(['twitter']).filtered(
|
|
lambda post: post.state == 'posted' and post.account_id.twitter_user_id
|
|
)
|
|
super(SocialLivePostTwitter, (self - twitter_live_posts))._compute_live_post_link()
|
|
|
|
for post in twitter_live_posts:
|
|
post.live_post_link = 'https://www.twitter.com/%s/statuses/%s' % (
|
|
post.account_id.twitter_user_id, post.twitter_tweet_id
|
|
)
|
|
|
|
def _refresh_statistics(self):
|
|
super()._refresh_statistics()
|
|
accounts = self.env['social.account'].search([('media_type', '=', 'twitter')])
|
|
for account in accounts:
|
|
existing_live_posts = self.env['social.live.post'].sudo().search(
|
|
[('account_id', '=', account.id), ('twitter_tweet_id', '!=', False)],
|
|
order='create_date DESC', limit=100)
|
|
|
|
if not existing_live_posts:
|
|
continue
|
|
|
|
tweets_endpoint_url = url_join(self.env['social.media']._TWITTER_ENDPOINT, '/2/tweets')
|
|
query_params = {
|
|
'ids': ','.join(existing_live_posts.mapped('twitter_tweet_id')),
|
|
'tweet.fields': 'public_metrics',
|
|
}
|
|
headers = account._get_twitter_oauth_header(
|
|
tweets_endpoint_url,
|
|
params=query_params,
|
|
method='GET'
|
|
)
|
|
result = requests.get(
|
|
tweets_endpoint_url,
|
|
params=query_params,
|
|
headers=headers,
|
|
timeout=5
|
|
)
|
|
if not result.ok:
|
|
_logger.error('Failed to fetch the account (%i) metrics: %r.', account.id, result.text)
|
|
|
|
result_tweets = result.json().get('data', [])
|
|
if isinstance(result_tweets, dict) and result_tweets.get('errors'):
|
|
account._action_disconnect_accounts(result_tweets)
|
|
return
|
|
|
|
existing_live_posts_by_tweet_id = {
|
|
live_post.twitter_tweet_id: live_post for live_post in existing_live_posts
|
|
}
|
|
|
|
for tweet in result_tweets:
|
|
existing_live_post = existing_live_posts_by_tweet_id.get(tweet.get('id'))
|
|
if existing_live_post:
|
|
public_metrics = tweet.get('public_metrics', {})
|
|
likes_count = public_metrics.get('like_count', 0)
|
|
retweets_count = public_metrics.get('retweet_count', 0)
|
|
existing_live_post.engagement = likes_count + retweets_count
|
|
|
|
def _post(self):
|
|
twitter_live_posts = self._filter_by_media_types(['twitter'])
|
|
super(SocialLivePostTwitter, (self - twitter_live_posts))._post()
|
|
|
|
twitter_live_posts._post_twitter()
|
|
|
|
def _post_twitter(self):
|
|
post_endpoint_url = url_join(self.env['social.media']._TWITTER_ENDPOINT, '/2/tweets')
|
|
|
|
for live_post in self:
|
|
account = live_post.account_id
|
|
post = live_post.post_id
|
|
|
|
params = {
|
|
'text': live_post.message,
|
|
}
|
|
|
|
try:
|
|
images_attachments_ids = account._format_attachments_to_images_twitter(post.image_ids)
|
|
except UserError as e:
|
|
live_post.write({
|
|
'state': 'failed',
|
|
'failure_reason': str(e)
|
|
})
|
|
continue
|
|
if images_attachments_ids:
|
|
params['media'] = {'media_ids': images_attachments_ids}
|
|
|
|
headers = account._get_twitter_oauth_header(post_endpoint_url)
|
|
result = requests.post(
|
|
post_endpoint_url,
|
|
json=params,
|
|
headers=headers,
|
|
timeout=5
|
|
)
|
|
|
|
if result.ok:
|
|
live_post.twitter_tweet_id = result.json()['data']['id']
|
|
values = {
|
|
'state': 'posted',
|
|
'failure_reason': False
|
|
}
|
|
else:
|
|
values = {
|
|
'state': 'failed',
|
|
'failure_reason': result.text
|
|
}
|
|
|
|
live_post.write(values)
|
|
|
|
@api.model
|
|
def _remove_mentions(self, message, ignore_mentions=None):
|
|
"""Remove mentions in the Tweet message.
|
|
|
|
:param message: text message in which we will look for mention
|
|
:param ignore_mentions: do not remove those mentions if found
|
|
"""
|
|
if not ast.literal_eval(self.env['ir.config_parameter'].sudo().get_param(
|
|
'social_twitter.disable_mentions', 'False')):
|
|
return message
|
|
|
|
if ignore_mentions:
|
|
# keep only safe (mention consistent) chars in `ignore_mention`
|
|
ignore_mentions = [
|
|
re.sub(r'[^\w]', '', mention).lower()
|
|
for mention in ignore_mentions
|
|
]
|
|
|
|
mention_regex = r'(^|[^\w#])@(%s)\b'
|
|
|
|
remove_mentions = [
|
|
match[2] for match in re.finditer(mention_regex % r'\w+', message)
|
|
if not ignore_mentions or match[2].lower() not in ignore_mentions
|
|
]
|
|
|
|
for mention in remove_mentions:
|
|
message = re.sub(mention_regex % mention, r'\1@ \2', message)
|
|
return message
|