Merge branch 'next-gen' into Win11Keymap

This commit is contained in:
Manuel Cortez 2021-12-21 15:45:06 -06:00 committed by GitHub
commit ed765117a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 17 additions and 17 deletions

View File

@ -1,8 +1,12 @@
TWBlue Changelog TWBlue Changelog
## changes in this version ## changes in this version
* In the Windows 11 Keymap, the default shortcut to open the keystrokes editor is now CTRL plus Alt plus Windows plus K to avoid conflicts with the new global mute microphone shortcut. * We have restored conversation and threads support powered by Twitter API V2 thanks to a set of improvements we have done in the application, as well as more generous limits to Tweet monthly cap by Twitter.
* In the Windows 11 Keymap, the default shortcut to open the keystrokes editor is now CTRL+Alt+Windows+K to avoid conflicts with the new global mute microphone shortcut.
* Fixed issue when uploading attachments (images, videos or gif files) while sending tweets or replies.
## Changes in version 2021.11.12
* Now it is possible to create a tweet from a trending topics buffer again. * Now it is possible to create a tweet from a trending topics buffer again.
* TWBlue now includes a completely new set of dialogs to handle tweeting, replying and sending direct messages that takes advantage of more Twitter features. * TWBlue now includes a completely new set of dialogs to handle tweeting, replying and sending direct messages that takes advantage of more Twitter features.
* It is possible to add videos in tweets and direct messages by using the new "add" button, located in every dialog where media can be added. Twitter suggests to add videos from 5 seconds up to 2 minutes lenght, in mp4 format (video Codec H.264 and audio codec AAC). Currently, TWBlue does not check if the uploaded video complies with Twitter media requirements. You can add only a video in a tweet or direct message. No other kind of media can be added after a video is in a tweet. If the video was unable to be uploaded successfully, the tweet or direct message won't be created. * It is possible to add videos in tweets and direct messages by using the new "add" button, located in every dialog where media can be added. Twitter suggests to add videos from 5 seconds up to 2 minutes lenght, in mp4 format (video Codec H.264 and audio codec AAC). Currently, TWBlue does not check if the uploaded video complies with Twitter media requirements. You can add only a video in a tweet or direct message. No other kind of media can be added after a video is in a tweet. If the video was unable to be uploaded successfully, the tweet or direct message won't be created.

View File

@ -64,12 +64,16 @@ class SearchPeopleBuffer(people.PeopleBuffer):
return False return False
class ConversationBuffer(SearchBuffer): class ConversationBuffer(SearchBuffer):
last_thread_id = None
last_reply_id = None
def start_stream(self, start=False, mandatory=False, play_sound=True, avoid_autoreading=False): def start_stream(self, start=False, mandatory=False, play_sound=True, avoid_autoreading=False):
current_time = time.time() current_time = time.time()
if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory == True: if self.execution_time == 0 or current_time-self.execution_time >= 180 or mandatory == True:
self.execution_time = current_time self.execution_time = current_time
results = self.get_replies_v1(self.tweet) log.debug("Retrieving conversation. Last thread ID is {}, last reply ID is {}".format(self.last_thread_id, self.last_reply_id))
results = self.get_replies(self.tweet)
log.debug("Retrieved {} items before filters.".format(len(results)))
number_of_items = self.session.order_buffer(self.name, results) number_of_items = self.session.order_buffer(self.name, results)
log.debug("Number of items retrieved: %d" % (number_of_items,)) log.debug("Number of items retrieved: %d" % (number_of_items,))
self.put_items_on_list(number_of_items) self.put_items_on_list(number_of_items)
@ -117,12 +121,12 @@ class ConversationBuffer(SearchBuffer):
# find all tweets replying to the original thread only. Those tweets are sent by the same author who originally posted the first tweet. # find all tweets replying to the original thread only. Those tweets are sent by the same author who originally posted the first tweet.
try: try:
term = "conversation_id:{} from:{} to:{}".format(conversation_id, original_tweet.data.author_id, original_tweet.data.author_id) term = "conversation_id:{} from:{} to:{}".format(conversation_id, original_tweet.data.author_id, original_tweet.data.author_id)
thread_tweets = self.session.twitter_v2.search_recent_tweets(term, user_auth=True, max_results=98, tweet_fields=["in_reply_to_user_id", "author_id", "conversation_id"]) thread_tweets = self.session.twitter_v2.search_recent_tweets(term, user_auth=True, max_results=98, since_id=self.last_thread_id, tweet_fields=["in_reply_to_user_id", "author_id", "conversation_id"])
if thread_tweets.data != None: if thread_tweets.data != None:
thread_results.extend(thread_tweets.data) thread_results.extend(thread_tweets.data)
# Search only replies to conversation_id. # Search only replies to conversation_id.
term = "conversation_id:{}".format(conversation_id, original_tweet.data.author_id) term = "conversation_id:{}".format(conversation_id, original_tweet.data.author_id)
reply_tweets = self.session.twitter_v2.search_recent_tweets(term, user_auth=True, max_results=50, tweet_fields=["in_reply_to_user_id", "author_id", "conversation_id"]) reply_tweets = self.session.twitter_v2.search_recent_tweets(term, user_auth=True, max_results=50, since_id=self.last_reply_id, tweet_fields=["in_reply_to_user_id", "author_id", "conversation_id"])
if reply_tweets.data != None: if reply_tweets.data != None:
reply_results.extend(reply_tweets.data) reply_results.extend(reply_tweets.data)
except TweepyException as e: except TweepyException as e:
@ -135,6 +139,7 @@ class ConversationBuffer(SearchBuffer):
try: try:
thread_results = self.session.twitter.lookup_statuses(ids, include_ext_alt_text=True, tweet_mode="extended") thread_results = self.session.twitter.lookup_statuses(ids, include_ext_alt_text=True, tweet_mode="extended")
thread_results.sort(key=lambda x: x.id) thread_results.sort(key=lambda x: x.id)
self.last_thread_id = thread_results[-1].id
results.extend(thread_results) results.extend(thread_results)
except TweepyException as e: except TweepyException as e:
log.exception("There was an error attempting to retrieve tweets for Twitter API V1.1, in conversation buffer {}".format(self.name)) log.exception("There was an error attempting to retrieve tweets for Twitter API V1.1, in conversation buffer {}".format(self.name))
@ -144,6 +149,7 @@ class ConversationBuffer(SearchBuffer):
try: try:
reply_results = self.session.twitter.lookup_statuses(ids, include_ext_alt_text=True, tweet_mode="extended") reply_results = self.session.twitter.lookup_statuses(ids, include_ext_alt_text=True, tweet_mode="extended")
reply_results.sort(key=lambda x: x.id) reply_results.sort(key=lambda x: x.id)
self.last_reply_id = reply_results[-1].id
results.extend(reply_results) results.extend(reply_results)
except TweepyException as e: except TweepyException as e:
log.exception("There was an error attempting to retrieve tweets for Twitter API V1.1, in conversation buffer {}".format(self.name)) log.exception("There was an error attempting to retrieve tweets for Twitter API V1.1, in conversation buffer {}".format(self.name))

View File

@ -631,7 +631,7 @@ class Session(base.baseSession):
if i["type"] == "photo": if i["type"] == "photo":
self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"])
media_ids.append(img.media_id) media_ids.append(img.media_id)
item = self.api_call_v2(call_name="create_tweet", status=obj["text"], _sound="tweet_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, media_ids=media_ids, poll_duration_minutes=obj["poll_period"], poll_options=obj["poll_options"], quote_tweet_id=obj.get("quote_tweet_id")) item = self.api_call_v2(call_name="create_tweet", text=obj["text"], _sound="tweet_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, media_ids=media_ids, poll_duration_minutes=obj["poll_period"], poll_options=obj["poll_options"], quote_tweet_id=obj.get("quote_tweet_id"))
in_reply_to_status_id = item.data["id"] in_reply_to_status_id = item.data["id"]
def reply(self, text="", in_reply_to_status_id=None, attachments=[], *args, **kwargs): def reply(self, text="", in_reply_to_status_id=None, attachments=[], *args, **kwargs):
@ -644,7 +644,7 @@ class Session(base.baseSession):
if i["type"] == "photo": if i["type"] == "photo":
self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"]) self.api_call(call_name="create_media_metadata", media_id=img.media_id, alt_text=i["description"])
media_ids.append(img.media_id) media_ids.append(img.media_id)
item = self.api_call(call_name="update_status", status=text, _sound="reply_send.ogg", tweet_mode="extended", in_reply_to_status_id=in_reply_to_status_id, media_ids=media_ids, *args, **kwargs) item = self.api_call_v2(call_name="create_tweet", text=text, _sound="reply_send.ogg", in_reply_to_tweet_id=in_reply_to_status_id, media_ids=media_ids, *args, **kwargs)
def direct_message(self, text, recipient, attachment=None, *args, **kwargs): def direct_message(self, text, recipient, attachment=None, *args, **kwargs):
if attachment == None: if attachment == None:

View File

@ -1,11 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import re import re
import output import output
import config
import logging import logging
import requests import requests
import time import time
import sound
from tweepy.errors import TweepyException, NotFound, Forbidden from tweepy.errors import TweepyException, NotFound, Forbidden
log = logging.getLogger("twitter.utils") log = logging.getLogger("twitter.utils")
""" Some utilities for the twitter interface.""" """ Some utilities for the twitter interface."""

View File

@ -28,11 +28,3 @@ file2 = open("..\\scripts\\twblue.nsi", "w", encoding="utf-8")
file2.write(contents) file2.write(contents)
file2.close() file2.close()
print("done") print("done")
print("Writing keys to module...")
file3 = open("appkeys.py", "w")
keys = """twitter_api_key = "{}"
twitter_api_secret = "{}"
""".format(os.environ.get("TWITTER_API_KEY"), os.environ.get("TWITTER_API_SECRET"))
file3.write(keys)
file3.close()
print("Wrote set of keys for consumer of {}".format(os.environ.get("TWITTER_API_KEY")))