fixes for python upstream breaking us
[pdt.git] / pdt.sh
CommitLineData
c0e2704f 1#!/bin/bash
f22362c9
IK
2# pdt: post to FSF social media via command line
3# Copyright (C) 2021 Ian Kelling
c0e2704f
IK
4# SPDX-License-Identifier: AGPL-3.0-or-later
5
f22362c9
IK
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU Affero General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU Affero General Public License for more details.
15
16# You should have received a copy of the GNU Affero General Public License
17# along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19# This is meant to be sourced.
c0e2704f
IK
20
21PATH="$HOME/.local/bin:$PATH"
22
23# usage: rbow [-PROFILE_NAME] [COMMAND]
24#
25# Wrapper for rainbowstream to use multiple logins and tweet directly
26# from the command line. PROFILE_NAME can be anything you want.
27rbow() {
b62d284c 28 local oath f
c0e2704f
IK
29 oath=$HOME/.rainbow_oauth
30 if [[ $1 == -* ]]; then
31 rm -f $oath
32 ln -s $oath$1 $oath
33 shift
34 fi
35 source ~/src/rainbowstream/venv/bin/activate
36 if (($#)); then
37 f=$(mktemp)
38 cat >$f <<'EOF'
39# adds a short delay after each send for more reliable operation
1d6422a8 40set force_conservative 1
c0e2704f
IK
41spawn "rainbowstream"
42# wait for prompt
43expect -nocase timeout {exit 1} "@*]: "
44set cmd [lindex $argv 0];
1d6422a8
IK
45send "$cmd\r\r"
46expect -nocase timeout {exit 1} "@*]: "
47# this may not be needed. didnt test
48sleep 2
49send "q\r"
c0e2704f
IK
50interact
51EOF
1d6422a8 52 expect $f "$*" || { echo error: expect failed; deactivate; rm -f $f; return 1; }
c0e2704f
IK
53 rm -f $f
54 else
55 rainbowstream
56 fi
57 deactivate
58}
59
c0e2704f
IK
60# usage: toot [-PROFILE_NAME] [TOOT_ARGS]
61toot() {
b62d284c 62 local account
c0e2704f
IK
63 source ~/src/toot/venv/bin/activate
64 if [[ $1 == -* ]]; then
65 account=${1#-}
66 shift
67 command toot activate --quiet $account || { deactivate; return 1; }
68 fi
69 command toot "$@" || { deactivate; return 1; }
70 deactivate
71}
72
73
4b6dbb81 74# post to mastodon + twitter + gnu social post
0d7441e0
IK
75#
76# If posting video, it only goes to twitter. Other accounts can be
77# posted to manually with free software.
78#
9c8eb6e7 79# usage: pdt [--dbd] [-m MEDIA_FILE] [-v VIDEO_PATH] [POST]
c0e2704f 80pdt() {
b62d284c 81 local video media rbow_account gs_account mastodon_account dbd video rbow_arg toot_arg dia_arg gs_arg
c0e2704f
IK
82 if [[ $pdttest ]]; then
83 rbow_account=iank
84 gs_account=fsfes
85 mastodon_account=iank@hostux.social
86 else
87 rbow_account=fsf
88 gs_account=fsf
89 mastodon_account=fsf@hostux.social
90 fi
91 dbd=false
9c8eb6e7 92 video=false
c0e2704f
IK
93 while [[ $1 == -* ]]; do
94 case $1 in
95 -m)
96 media="$2"
97 shift 2
c0e2704f
IK
98 rbow_arg=" --i $media"
99 toot_arg="--media $media"
100 dia_arg="-p $media "
101 gs_arg="-F media=@$media"
102 ;;
103 --dbd)
104 dbd=true
105 rbow_account=dbd
106 gs_account=dbd
107 mastodon_account=endDRM@hostux.social
108 shift
109 ;;
9c8eb6e7
IK
110 -v)
111 video=true
112 media="$2"
113 shift 2
114 ;;
c0e2704f
IK
115 esac
116 done
9c8eb6e7
IK
117 if [[ $media ]]; then
118 if [[ ! -e $media ]]; then
119 echo "error: file not found $media"
120 return 1
121 fi
122 if [[ $media == *\ * ]]; then
123 echo "error: file path contains a space. move it to non-space path"
124 return 1
125 fi
126 fi
c0e2704f
IK
127 # if we have no argument
128 if (( ! $# )); then
129 read -r -p "input PDT text: " input
130 set -- "$input"
131 fi
132 if [[ $- == *i* ]]; then
133 echo "About to PDT the following line. Press enter to confirm or ctrl-c to quit:"
134 echo "$input"
135 read
136 fi
9c8eb6e7
IK
137 if $video; then
138 local oath
139 oath=$HOME/.rainbow_oauth
140 account=fsf
141 if $dbd; then
142 account=dbd
143 fi
144 rm -f $oath
145 ln -s ${oath}-$account $oath
4b26c43d 146 python3 ~/src/video-tweet/async-upload.py "$media" "$*"
9c8eb6e7
IK
147 return
148 fi
c0e2704f
IK
149 fails=()
150 if ! rbow -$rbow_account t "$*" $rbow_arg; then
151 fails+=(tweet)
152 fi
153 if ! toot -$mastodon_account post "$*" $toot_arg; then
154 fails+=(toot)
155 fi
c0e2704f
IK
156 # https://gnusocial.net/doc/twitterapi
157 if ! curl -o /dev/null -sS -u "$gs_account:$(cat ~/.gnusocial_login-$gs_account)" \
158 $gs_arg -F "status=$*" https://status.fsf.org/api/statuses/update.xml; then
159 fails+=(gnu-social)
160 fi
161 if (( ${#fails[@]} )); then
162 printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}"); echo
163 echo "FSF ERROR: ${fails[*]} might not have posted" >&2
164 fi
165}
166
0d7441e0 167# Usage: pdt-setup
c0e2704f 168pdt-setup() {
c0e2704f
IK
169 if [[ $pdttest ]]; then
170 mastodon_accounts=(iank)
171 else
172 mastodon_accounts=(fsf endDRM)
173 fi
174
175 mkdir -p ~/src
176 cd ~/src
4b6dbb81 177 for repo in errhandle rainbowstream video-tweet; do
c0e2704f
IK
178 if [[ -e $repo ]]; then
179 cd $repo
180 git fetch
181 git reset --hard origin/master
182 git clean -xfffd
183 cd ..
184 else
185 git clone https://vcs.fsf.org/git/$repo.git
186 fi
187 done
188 source ~/src/errhandle/err
189 cp ~/src/rainbowstream/rainbowstream/colorset/config ~/.rainbow_config.json
190
191 if [[ ! -e ~/.local/bin/pip ]]; then
192 tmp=$(mktemp)
ce8c0f46
IK
193 pyver=$(python3 --version | sed -r 's/.*(3\.[0-9]+).*/\1/')
194 echo fyi: detected pyver: $pyver. this should look something like 3.6
195 # the bootstrap script at https://bootstrap.pypa.io/get-pip.py requires 3.7+
196 # as I write this.
197 wget -O$tmp https://bootstrap.pypa.io/pip/$pyver/get-pip.py
c0e2704f
IK
198 python3 $tmp --user
199 hash -r
200 fi
201
ce8c0f46 202 python3 -m pip install --user -U virtualenv
c0e2704f
IK
203
204 cd ~/src/rainbowstream
205 python3 -m virtualenv -p python3 venv
206 source venv/bin/activate
207 python3 -m pip install -r requirements.txt
208 python3 -m pip install -e .
209 deactivate
210
211
c0e2704f
IK
212 rm -rf ~/src/toot
213 mkdir -p ~/src/toot
214 cd ~/src/toot
215 python3 -m virtualenv -p python3 venv
216 source venv/bin/activate
217 # pip freeze after a pip install.
218 cat >requirements.txt <<'EOF'
219beautifulsoup4==4.8.2
220certifi==2019.11.28
221chardet==3.0.4
222idna==2.8
223requests==2.22.0
224soupsieve==1.9.5
225toot==0.25.2
226urllib3==1.25.8
227urwid==2.1.0
228wcwidth==0.1.8
229EOF
230 python3 -m pip install -r requirements.txt
231 deactivate
232
c0e2704f
IK
233 for account in dbd fsf; do
234 if [[ ! -s ~/.rainbow_oauth-$account ]]; then
235 printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}");
236 echo "Please login to $account on twitter in your main browser then press enter. After rainbowstream prompt loads, quit with command q"
237 read -r
238 rbow -$account
239 fi
240 if [[ ! -s ~/.gnusocial_login-$account ]]; then
241 printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}");
242 read -r -p "please enter the password for $account@status.fsf.org > " pass
243 touch ~/.gnusocial_login-$account
244 chmod 600 ~/.gnusocial_login-$account
245 printf "%s\n" "$pass" > ~/.gnusocial_login-$account
246 fi
247 done
248
249 for account in ${mastodon_accounts[@]}; do
250 if ! toot activate $account@hostux.social &>/dev/null; then
251 printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}");
252 echo "Please login to $account on https://hostux.social in your main browser then press enter."
253 read -r
254 toot login -i hostux.social
255 fi
256 done
257 err-allow
c70ad097 258 echo "pdt-setup complete"
c0e2704f 259}