2018-08-16 17:25:16 -05:00
|
|
|
# -*- coding: utf-8 -*-
|
2018-11-22 13:35:19 -06:00
|
|
|
from __future__ import absolute_import
|
2019-06-06 11:52:23 -05:00
|
|
|
from __future__ import unicode_literals
|
|
|
|
from future import standard_library
|
|
|
|
standard_library.install_aliases()
|
|
|
|
from builtins import str
|
|
|
|
from builtins import chr
|
|
|
|
from builtins import range
|
2018-08-16 17:25:16 -05:00
|
|
|
import platform
|
|
|
|
system = platform.system()
|
2018-11-22 13:35:19 -06:00
|
|
|
from . import utils
|
2018-08-16 17:25:16 -05:00
|
|
|
import re
|
2019-06-06 11:52:23 -05:00
|
|
|
import html.entities
|
2018-08-16 17:25:16 -05:00
|
|
|
import time
|
|
|
|
import output
|
|
|
|
import languageHandler
|
|
|
|
import arrow
|
|
|
|
import logging
|
|
|
|
import config
|
2018-11-22 13:35:19 -06:00
|
|
|
from .long_tweets import twishort, tweets
|
2018-08-16 17:25:16 -05:00
|
|
|
log = logging.getLogger("compose")
|
|
|
|
|
|
|
|
def StripChars(s):
|
|
|
|
"""Converts any html entities in s to their unicode-decoded equivalents and returns a string."""
|
|
|
|
entity_re = re.compile(r"&(#\d+|\w+);")
|
|
|
|
def matchFunc(match):
|
|
|
|
"""Nested function to handle a match object.
|
|
|
|
If we match &blah; and it's not found, &blah; will be returned.
|
|
|
|
if we match #\d+, unichr(digits) will be returned.
|
|
|
|
Else, a unicode string will be returned."""
|
2019-06-06 11:52:23 -05:00
|
|
|
if match.group(1).startswith('#'): return chr(int(match.group(1)[1:]))
|
|
|
|
replacement = html.entities.entitydefs.get(match.group(1), "&%s;" % match.group(1))
|
|
|
|
return replacement
|
|
|
|
return str(entity_re.sub(matchFunc, s))
|
2018-08-16 17:25:16 -05:00
|
|
|
|
|
|
|
chars = "abcdefghijklmnopqrstuvwxyz"
|
|
|
|
|
|
|
|
def compose_tweet(tweet, db, relative_times, show_screen_names=False, session=None):
|
|
|
|
""" It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is."""
|
|
|
|
if system == "Windows":
|
2021-01-04 11:14:55 -06:00
|
|
|
original_date = arrow.get(tweet.created_at, locale="en")
|
2018-08-16 17:25:16 -05:00
|
|
|
if relative_times == True:
|
2019-10-03 22:47:19 -05:00
|
|
|
ts = original_date.humanize(locale=languageHandler.curLang[:2])
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
2019-10-03 22:47:19 -05:00
|
|
|
ts = original_date.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2])
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
2020-12-22 17:29:33 -06:00
|
|
|
ts = tweet.created_at
|
|
|
|
if hasattr(tweet, "message"):
|
2018-08-16 17:25:16 -05:00
|
|
|
value = "message"
|
2020-12-22 17:29:33 -06:00
|
|
|
elif hasattr(tweet, "full_text"):
|
2018-08-16 17:25:16 -05:00
|
|
|
value = "full_text"
|
|
|
|
else:
|
|
|
|
value = "text"
|
2020-12-22 17:29:33 -06:00
|
|
|
if hasattr(tweet, "retweeted_status") and value != "message":
|
|
|
|
text = StripChars(getattr(tweet.retweeted_status, value))
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
2020-12-22 17:29:33 -06:00
|
|
|
text = StripChars(getattr(tweet, value))
|
2018-08-16 17:25:16 -05:00
|
|
|
if show_screen_names:
|
2020-12-22 17:29:33 -06:00
|
|
|
user = tweet.user.screen_name
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
2020-12-22 17:29:33 -06:00
|
|
|
user = tweet.user.name
|
|
|
|
source = re.sub(r"(?s)<.*?>", "", tweet.source)
|
|
|
|
if hasattr(tweet, "retweeted_status"):
|
|
|
|
if (hasattr(tweet, "message")) == False and tweet.retweeted_status.is_quote_status == False:
|
|
|
|
text = "RT @%s: %s" % (tweet.retweeted_status.user.screen_name, text)
|
|
|
|
elif tweet.retweeted_status.is_quote_status:
|
2018-08-16 17:25:16 -05:00
|
|
|
text = "%s" % (text)
|
|
|
|
else:
|
2020-12-22 17:29:33 -06:00
|
|
|
text = "RT @%s: %s" % (tweet.retweeted_status.user.screen_name, text)
|
|
|
|
if not hasattr(tweet, "message"):
|
2020-06-09 11:34:02 -05:00
|
|
|
|
2020-12-22 17:29:33 -06:00
|
|
|
if hasattr(tweet, "retweeted_status"):
|
|
|
|
text = utils.expand_urls(text, tweet.retweeted_status.entities)
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
2020-12-22 17:29:33 -06:00
|
|
|
text = utils.expand_urls(text, tweet.entities)
|
2018-08-16 17:25:16 -05:00
|
|
|
if config.app['app-settings']['handle_longtweets']: pass
|
|
|
|
return [user+", ", text, ts+", ", source]
|
|
|
|
|
|
|
|
def compose_direct_message(item, db, relative_times, show_screen_names=False, session=None):
|
|
|
|
# for a while this function will be together with compose_dm.
|
|
|
|
# this one composes direct messages based on events (new API Endpoints).
|
|
|
|
if system == "Windows":
|
|
|
|
# Let's remove the last 3 digits in the timestamp string.
|
|
|
|
# Twitter sends their "epoch" timestamp with 3 digits for milliseconds and arrow doesn't like it.
|
2020-12-22 17:29:33 -06:00
|
|
|
original_date = arrow.get(int(item.created_timestamp[:-3]))
|
2018-08-16 17:25:16 -05:00
|
|
|
if relative_times == True:
|
2019-10-03 22:47:19 -05:00
|
|
|
ts = original_date.humanize(locale=languageHandler.curLang[:2])
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
2019-10-03 22:47:19 -05:00
|
|
|
ts = original_date.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2])
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
2020-12-22 17:29:33 -06:00
|
|
|
ts = item.created_timestamp
|
|
|
|
text = StripChars(item.message_create.message_data.text)
|
2018-08-16 17:25:16 -05:00
|
|
|
source = "DM"
|
2021-01-05 11:04:06 -06:00
|
|
|
sender = session.get_user(item.message_create["sender_id"])
|
|
|
|
if db["user_name"] == sender["screen_name"]:
|
2018-08-16 17:25:16 -05:00
|
|
|
if show_screen_names:
|
2021-01-05 11:04:06 -06:00
|
|
|
user = _(u"Dm to %s ") % (session.get_user(item.message_create["target"]["recipient_id"]).screen_name)
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
2021-01-05 11:04:06 -06:00
|
|
|
user = _(u"Dm to %s ") % (session.get_user(item["message_create"]["target"]["recipient_id"]).name)
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
|
|
|
if show_screen_names:
|
2021-01-05 11:04:06 -06:00
|
|
|
user = sender["screen_name"]
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
2021-01-05 11:04:06 -06:00
|
|
|
user = sender["name"]
|
2018-08-16 17:25:16 -05:00
|
|
|
if text[-1] in chars: text=text+"."
|
2021-01-05 11:04:06 -06:00
|
|
|
text = utils.expand_urls(text, item.message_create["message_data"]["entities"])
|
2018-08-16 17:25:16 -05:00
|
|
|
return [user+", ", text, ts+", ", source]
|
|
|
|
|
|
|
|
def compose_quoted_tweet(quoted_tweet, original_tweet, show_screen_names=False, session=None):
|
|
|
|
""" It receives a tweet and returns a list with the user, text for the tweet or message, date and the client where user is."""
|
2020-12-22 17:29:33 -06:00
|
|
|
if hasattr(quoted_tweet, "retweeted_status"):
|
|
|
|
if hasattr(quoted_tweet.retweeted_status, "full_text"):
|
2018-08-16 17:25:16 -05:00
|
|
|
value = "full_text"
|
|
|
|
else:
|
|
|
|
value = "text"
|
2020-12-22 17:29:33 -06:00
|
|
|
text = StripChars(getattr(quoted_tweet.retweeted_status, value))
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
2020-12-22 17:29:33 -06:00
|
|
|
if hasattr(quoted_tweet, "full_text"):
|
2018-08-16 17:25:16 -05:00
|
|
|
value = "full_text"
|
|
|
|
else:
|
|
|
|
value = "text"
|
2020-12-22 17:29:33 -06:00
|
|
|
text = StripChars(getattr(quoted_tweet, value))
|
2018-08-16 17:25:16 -05:00
|
|
|
if show_screen_names:
|
2020-12-22 17:29:33 -06:00
|
|
|
quoting_user = quoted_tweet.user.screen_name
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
2020-12-22 17:29:33 -06:00
|
|
|
quoting_user = quoted_tweet.user.name
|
2021-01-05 11:04:06 -06:00
|
|
|
source = quoted_tweet.source
|
2020-12-22 17:29:33 -06:00
|
|
|
if hasattr(quoted_tweet, "retweeted_status"):
|
|
|
|
text = "rt @%s: %s" % (quoted_tweet.retweeted_status.user.screen_name, text)
|
2018-08-16 17:25:16 -05:00
|
|
|
if text[-1] in chars: text=text+"."
|
2020-12-22 17:29:33 -06:00
|
|
|
original_user = original_tweet.user.screen_name
|
|
|
|
if hasattr(original_tweet, "message"):
|
|
|
|
original_text = original_tweet.message
|
|
|
|
elif hasattr(original_tweet, "full_text"):
|
|
|
|
original_text = StripChars(original_tweet.full_text)
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
2020-12-22 17:29:33 -06:00
|
|
|
original_text = StripChars(original_tweet.text)
|
|
|
|
quoted_tweet.message = _(u"{0}. Quoted tweet from @{1}: {2}").format( text, original_user, original_text)
|
2018-08-16 17:25:16 -05:00
|
|
|
quoted_tweet = tweets.clear_url(quoted_tweet)
|
2021-01-04 11:14:55 -06:00
|
|
|
quoted_tweet.entities["urls"].extend(original_tweet.entities["urls"])
|
2018-08-16 17:25:16 -05:00
|
|
|
return quoted_tweet
|
|
|
|
|
|
|
|
def compose_followers_list(tweet, db, relative_times=True, show_screen_names=False, session=None):
|
|
|
|
if system == "Windows":
|
2021-01-05 11:04:06 -06:00
|
|
|
original_date = arrow.get(tweet.created_at, locale="en")
|
2018-08-16 17:25:16 -05:00
|
|
|
if relative_times == True:
|
2019-10-03 22:47:19 -05:00
|
|
|
ts = original_date.humanize(locale=languageHandler.curLang[:2])
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
2019-10-03 22:47:19 -05:00
|
|
|
ts = original_date.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2])
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
2020-12-22 17:29:33 -06:00
|
|
|
ts = tweet.created_at
|
|
|
|
if hasattr(tweet, "status"):
|
|
|
|
if len(tweet.status) > 4 and system == "Windows":
|
2021-01-05 11:04:06 -06:00
|
|
|
original_date2 = arrow.get(tweet.status.created_at, locale="en")
|
2018-08-16 17:25:16 -05:00
|
|
|
if relative_times:
|
2019-10-03 22:47:19 -05:00
|
|
|
ts2 = original_date2.humanize(locale=languageHandler.curLang[:2])
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
2019-10-03 22:47:19 -05:00
|
|
|
ts2 = original_date2.shift(seconds=db["utc_offset"]).format(_(u"dddd, MMMM D, YYYY H:m:s"), locale=languageHandler.curLang[:2])
|
2018-08-16 17:25:16 -05:00
|
|
|
else:
|
|
|
|
ts2 = _("Unavailable")
|
|
|
|
else:
|
|
|
|
ts2 = _("Unavailable")
|
2020-12-22 17:29:33 -06:00
|
|
|
return [_(u"%s (@%s). %s followers, %s friends, %s tweets. Last tweeted %s. Joined Twitter %s") % (tweet.name, tweet.screen_name, tweet.followers_count, tweet.friends_count, tweet.statuses_count, ts2, ts)]
|
2018-08-16 17:25:16 -05:00
|
|
|
|
|
|
|
def compose_list(list):
|
2020-12-22 17:29:33 -06:00
|
|
|
name = list.name
|
|
|
|
if list.description == None: description = _(u"No description available")
|
|
|
|
else: description = list.description
|
|
|
|
user = list.user.name
|
|
|
|
members = str(list.member_count)
|
|
|
|
if list.mode == "private": status = _(u"private")
|
2018-08-16 17:25:16 -05:00
|
|
|
else: status = _(u"public")
|
|
|
|
return [name, description, user, members, status]
|