From 026344f11e0412a32e9417d3ba9d77abc7f1594c Mon Sep 17 00:00:00 2001 From: Ian Kelling Date: Tue, 21 Nov 2023 18:51:12 -0500 Subject: [PATCH] extra twitter operations, general cleanup --- pdt.sh | 134 +++++++++++++++++++++++++++++++++++++++------------------ t.py | 48 ++++++++++++++------- 2 files changed, 123 insertions(+), 59 deletions(-) diff --git a/pdt.sh b/pdt.sh index 4278abf..01d5998 100644 --- a/pdt.sh +++ b/pdt.sh @@ -30,6 +30,12 @@ _pdtsh_blocks=██████████████████████ # Uses variables as input: # $media for image file path. # $alt_text for image alt text. +# +# -PROFILE_NAME Either dbd or fsf. Defaults to whatever was used last. +# +# Note retweeting cannot be done with the gratis api level. I suggest +# posting a message like: 'Retweet: +# https://nitter.net/fsf/status/1726382360826958325' tweet() { local keys_file keys_file=$_pdtsh_dir/twitter_keys.py @@ -53,28 +59,67 @@ tweet() { deactivate } -# usage: tweetrm [-PROFILE_NAME] POST_ID -# -# Delete twitter post. Post id is the number at end of a url like: -# https://nitter.net/user/status/1725640623149969527 -# -# -PROFILE_NAME Either dbd or fsf. -# -tweetrm() { - local keys_file +_pdtsh-tweet-option() { + local keys_file option + option=$1 + shift keys_file=$_pdtsh_dir/twitter_keys.py if [[ $1 == -* ]]; then rm -f $keys_file ln -s $keys_file$1 $keys_file shift fi - # shellcheck disable=SC1090 # not relevant to this script source ~/src/tweepy/venv/bin/activate - $_pdtsh_tweet $1 || { deactivate; return 1; } + $_pdtsh_tweet $option $1 || { deactivate; return 1; } deactivate } +# usage: tweetrm [-PROFILE_NAME] POST_ID +# +# Delete twitter post. Post id is the number at end of a url like: +# https://nitter.net/user/status/1725640623149969527 +# +# -PROFILE_NAME Either dbd or fsf. Defaults to whatever was used last. +tweetrm() { + _pdtsh-tweet-option --delete "$@" +} + + + +# usage: pin-tweet [-PROFILE_NAME] POST_ID +# +# Pin twitter post. Post id is the number at end of a url like: +# https://nitter.net/user/status/1725640623149969527 +# +# -PROFILE_NAME Either dbd or fsf. Defaults to whatever was used last. +# +pin-tweet() { + _pdtsh-tweet-option --pin "$@" +} + +# usage: unpin-tweet [-PROFILE_NAME] POST_ID +# +# Unpin twitter post. Post id is the number at end of a url like: +# https://nitter.net/user/status/1725640623149969527 +# +# -PROFILE_NAME Either dbd or fsf. Defaults to whatever was used last. +# +unpin-tweet() { + _pdtsh-tweet-option --unpin "$@" +} + + +# usage: twitter-banner [-PROFILE_NAME] IMAGE_PATH +# +# IMAGE_PATH Path to jpg or png, 1500 px by 500px. +# +# -PROFILE_NAME Either dbd or fsf. Defaults to whatever was used last. +# +twitter-banner() { + _pdtsh-tweet-option --banner "$@" +} + # usage: toot [-PROFILE_NAME] [TOOT_ARGS] toot() { @@ -91,30 +136,42 @@ toot() { } -# post to mastodon + twitter. -# -# Gnu Social posting code exists, but we aren't using it. You would need -# to run pdt-gnusocial-setup beforehand. Alt text does not work on -# gnusocial. +# post to mastodon and/org twitter. # # usage: # pdt [-s mastodon|twitter|gnusocial] [--dbd] [-m IMAGE_FILE] [-a ALT_TEXT] [POST] # -# -s mastodon|twitter|gnusocial = post to a single social network. -# -m IMAGE_FILE = Uploads IMAGE_FILE. if MEDIA_FILE.txt exists, the last line of that file will be used as ALT_TEXT -# unless -a has been used. +# -s mastodon|twitter|gnusocial Post to a single social network. +# +# -m IMAGE_FILE Uploads IMAGE_FILE. if MEDIA_FILE.txt exists, the last +# line of that file will be used as ALT_TEXT unless -a +# has been used. # # POST can have have some special markup for twitter to deal with the 280 character limit: -# /tnt/ short for "twitter next tweet", The /tnt/ will be removed, and the tweet split into 2 at that point. -# /teof/ means twitter end of file. It will be removed, and text after it won't be posted to twitter. # -# If you have some pdt arguments in a file, FILE, and you want to test if they are under 280 chars, you can run: +# * /tnt/ short for "twitter next tweet". /tnt/ will be removed, and the +# tweet will be split into 2 at that point. +# +# * /teof/ short for "twitter end of file." It will be removed and text +# after it won't be posted to twitter. An example of how this is +# useful: You write a post which is 284 characters. Instead of +# splitting it in 2 for twitter, you could put the least important +# hash tag and the end and omit it on twitter. +# +# Twitter considers all urls to be 23 characters. To measure the length +# of arguments in a file, run this (replace FILE). # -# sed -r 's,/teof/.*,,;s/-(m|a|-dbd) [^ ]*//;s,https?://[^ ]*,https://xxxxxxxxxxxxxxx,g' FILE | awk '$0 !~ /\/tnt\// && length > 280 {print length, $0}' +# sed -r 's,/teof/.*,,;s/ *-(m|a|-dbd) [^ ]*//;s,https?://[^ ]*,https://xxxxxxxxxxxxxxx,g' FILE | awk '$0 !~ /\/tnt\// && length > 280 {print length, $0}' # # broken usage: # pdt [-v VIDEO_PATH] [POST] # +# Outdated usage: +# +# Gnu Social posting code exists, but we aren't using it. You would need +# to run pdt-gnusocial-setup beforehand. Alt text does not work on +# gnusocial. +# pdt() { local video media twitter_account gs_account mastodon_account video gs_arg network local do_mastodon do_twitter do_gnusocial @@ -272,7 +329,7 @@ pdt-toot-setup() { # sudo ln -s /home/iank/.local/bin/pip /usr/bin # python3 -m virtualenv -p python3 venv - # shellcheck disable=SC1090 # not relevant to this script + # shellcheck disable=SC1091 # not relevant to this script source venv/bin/activate # pip freeze after a pip install, as of 2022-11-28 cat >requirements.txt <<'EOF' @@ -354,7 +411,7 @@ pdt-twitter-setup() { ( cd ~/src/tweepy python3 -m virtualenv -p python3 venv - # shellcheck disable=SC1090 # not relevant to this script + # shellcheck disable=SC1091 # not relevant to this script source venv/bin/activate python3 -m pip install . ) @@ -413,29 +470,20 @@ pdt-setup() { mkdir -p ~/src for repo in errhandle video-tweet; do - if [[ -e ~/src/$repo ]]; then - ( - cd ~/src/$repo - git fetch - git reset --hard origin/master - git clean -xfffd - ) + if [[ -e ~/src/$repo/.git ]]; then + if git -C ~/src/$repo remote -v | grep -E "^origin[[:space:]]+git@vcs.fsf.org:$repo.git" &>/dev/null; then + git -C ~/src/$repo fetch + git -C ~/src/$repo reset --hard origin/master + git -C ~/src/$repo clean -xfffd + else + rm -rf ~/src/$repo + git clone https://vcs.fsf.org/git/$repo.git ~/src/$repo + fi else git clone https://vcs.fsf.org/git/$repo.git ~/src/$repo fi done - if [[ -e ~/src/tweepy ]]; then - ( - cd ~/src/tweepy - git fetch - git reset --hard f32d12dbddbd877470446657812a10a04292d0c9 - git clean -xfffd - ) - else - git clone https://github.com/tweepy/tweepy.git ~/src/tweepy - fi - # shellcheck disable=SC1090 # tested separately source ~/src/errhandle/err diff --git a/t.py b/t.py index 9148987..bbe7860 100755 --- a/t.py +++ b/t.py @@ -19,10 +19,13 @@ # Usage: see pdt.sh example. import sys -import tweepy import time +import tweepy from twitter_keys import * +# for debugging: +# import logging +# logging.basicConfig(level=logging.DEBUG) auth = tweepy.OAuth1UserHandler( consumer_key, consumer_secret, access_token, access_token_secret @@ -34,9 +37,23 @@ client = tweepy.Client( consumer_key=consumer_key, consumer_secret=consumer_secret, access_token=access_token, access_token_secret=access_token_secret ) - -if len(sys.argv) == 2: - response = client.delete_tweet(sys.argv[1]) +verbose = False + +if len(sys.argv) == 2 and sys.argv[1] == "-v": + verbose = True + +if len(sys.argv) == 3: + if sys.argv[1] == '--delete': + client.delete_tweet(sys.argv[2]) + elif sys.argv[1] == '--pin': + api.pin_tweet(sys.argv[2]) + elif sys.argv[1] == '--unpin': + api.unpin_tweet(sys.argv[2]) + elif sys.argv[1] == '--banner': + api.update_profile_banner(sys.argv[2]) + else: + print("t.py: error: unexpected argument. exiting without doing anything") + sys.exit(1) else: input_text = input() @@ -48,19 +65,18 @@ else: if post_count > 1: tweet_text=tweet_text + f" 1/{post_count}" - have_image = False + have_image = True try: image_path = input() - have_image = True - except: - pass + except EOFError: + have_image = False - have_alt = False + have_alt = True try: alt = input() - have_alt = True - except: - pass + except EOFError: + have_alt = False + if have_image: media = api.media_upload(image_path) media_id = media.media_id_string @@ -72,13 +88,13 @@ else: if have_image: response = client.create_tweet(text=tweet_text, media_ids=[media_id]) else: - #print(tweet_text) response = client.create_tweet(text=tweet_text) - print(f"https://nitter.net/user/status/{response.data['id']}") + if verbose: + print(f"https://nitter.net/user/status/{response.data['id']}") if post_count > 1: for x in range(1, post_count): time.sleep(1) tweet_text=posts[x].strip() + f" {x+1}/{post_count}" response = client.create_tweet(text=tweet_text, in_reply_to_tweet_id=response.data['id']) - print(f"{x+1}/{post_count} https://nitter.net/user/status/{response.data['id']}") - #print(tweet_text) + if verbose: + print(f"{x+1}/{post_count} https://nitter.net/USER/status/{response.data['id']}") -- 2.25.1