remove unused var, add file for alt text
[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() {
9667049b 62 local mast_profile
c0e2704f
IK
63 source ~/src/toot/venv/bin/activate
64 if [[ $1 == -* ]]; then
9667049b 65 mast_profile=${1#-}
c0e2704f 66 shift
9667049b 67 command toot activate --quiet $mast_profile || { deactivate; return 1; }
c0e2704f
IK
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#
9667049b
IK
79# Alt text only goes to mastodon.
80#
c95a2b7e 81# usage: pdt [-s mastodon|twitter|gnusocial] [--dbd] [-m IMAGE_FILE] [-a ALT_TEXT] [-v VIDEO_PATH] [POST]
9667049b 82# -s = post to single social network supplied by argument.
c95a2b7e
IK
83# -m IMAGE_FILE = Uploads IMAGE_FILE. if MEDIA_FILE.txt exists, the last line of that file will be used as ALT_TEXT
84# unless -a has been used.
c0e2704f 85pdt() {
9667049b
IK
86 local video media rbow_account gs_account mastodon_account dbd video rbow_arg gs_arg alt_text
87 local -a toot_args
c0e2704f
IK
88 if [[ $pdttest ]]; then
89 rbow_account=iank
90 gs_account=fsfes
9667049b 91 mastodon_account=fsftest@hostux.social
c0e2704f
IK
92 else
93 rbow_account=fsf
94 gs_account=fsf
95 mastodon_account=fsf@hostux.social
96 fi
9c8eb6e7 97 video=false
9667049b
IK
98 do_mastodon=true
99 do_twitter=true
100 do_gnusocial=true
c0e2704f
IK
101 while [[ $1 == -* ]]; do
102 case $1 in
9667049b
IK
103 -s)
104 network="$2"
105 do_mastodon=false
106 do_twitter=false
107 do_gnusocial=false
108 case $network in
109 mastodon)
110 do_mastodon=true
111 ;;
112 twitter)
113 do_twitter=true
114 ;;
115 gnusocial)
116 do_gnusocial=true
117 ;;
118 *)
119 echo "pdt: error: expected -s mastodon|twitter|gnusocial"
120 return 1
121 ;;
122 esac
123 shift 2
124 ;;
125 -a)
126 alt_text="$2"
127 toot_args+=(--description "$alt_text" )
128 shift 2
129 ;;
c0e2704f
IK
130 -m)
131 media="$2"
132 shift 2
c0e2704f 133 rbow_arg=" --i $media"
9667049b 134 toot_args+=(--media "$media" )
c0e2704f
IK
135 gs_arg="-F media=@$media"
136 ;;
137 --dbd)
c0e2704f
IK
138 rbow_account=dbd
139 gs_account=dbd
140 mastodon_account=endDRM@hostux.social
141 shift
142 ;;
9c8eb6e7
IK
143 -v)
144 video=true
145 media="$2"
146 shift 2
147 ;;
c0e2704f
IK
148 esac
149 done
9c8eb6e7
IK
150 if [[ $media ]]; then
151 if [[ ! -e $media ]]; then
152 echo "error: file not found $media"
153 return 1
154 fi
155 if [[ $media == *\ * ]]; then
156 echo "error: file path contains a space. move it to non-space path"
157 return 1
158 fi
c95a2b7e
IK
159 if [[ ! $alt_text && -r $media.txt && -s $media.txt ]]; then
160 alt_text=$(tail -n1 $media.txt)
161 fi
9c8eb6e7 162 fi
c0e2704f
IK
163 # if we have no argument
164 if (( ! $# )); then
165 read -r -p "input PDT text: " input
166 set -- "$input"
167 fi
168 if [[ $- == *i* ]]; then
169 echo "About to PDT the following line. Press enter to confirm or ctrl-c to quit:"
9667049b
IK
170 echo "$*"
171 read -r
c0e2704f 172 fi
9c8eb6e7
IK
173 if $video; then
174 local oath
175 oath=$HOME/.rainbow_oauth
9c8eb6e7 176 rm -f $oath
9667049b 177 ln -s ${oath}-$rbow_account $oath
4b26c43d 178 python3 ~/src/video-tweet/async-upload.py "$media" "$*"
9c8eb6e7
IK
179 return
180 fi
c0e2704f 181 fails=()
9667049b
IK
182 if $do_twitter; then
183 if ! rbow -$rbow_account t "$*" $rbow_arg; then
184 fails+=(tweet)
185 fi
c0e2704f 186 fi
9667049b
IK
187 if $do_mastodon; then
188 if ! toot -$mastodon_account post "$*" "${toot_args[@]}"; then
189 fails+=(toot)
190 fi
c0e2704f 191 fi
9667049b
IK
192 if $do_gnusocial; then
193 # https://gnusocial.net/doc/twitterapi
194 if ! curl -o /dev/null -sS -u "$gs_account:$(cat ~/.gnusocial_login-$gs_account)" \
195 $gs_arg -F "status=$*" https://status.fsf.org/api/statuses/update.xml; then
196 fails+=(gnu-social)
197 fi
c0e2704f
IK
198 fi
199 if (( ${#fails[@]} )); then
200 printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}"); echo
201 echo "FSF ERROR: ${fails[*]} might not have posted" >&2
202 fi
203}
204
9667049b
IK
205# Usage: toot-setup
206#
207# Only run manually for testing.
208#
209# this expects pdt-pip-setup has been run already, and it doesn't setup
210# errhandle.
211#
212# note: auth info is stored at ~/.config/toot/config.json
213toot-setup() {
c0e2704f 214 if [[ $pdttest ]]; then
9667049b 215 mastodon_accounts=(fsftest)
c0e2704f
IK
216 else
217 mastodon_accounts=(fsf endDRM)
218 fi
219
9667049b
IK
220 rm -rf ~/src/toot
221 mkdir -p ~/src/toot
222 cd ~/src/toot
223 # on t11, got myself into a situation where when doing pip install virtualenv,
224 # it gave an error that /usr/bin/pip didn't exist, so i did
225 # sudo ln -s /home/iank/.local/bin/pip /usr/bin
226 #
227 python3 -m virtualenv -p python3 venv
228 source venv/bin/activate
229 # pip freeze after a pip install, as of 2022-11-28
230 cat >requirements.txt <<'EOF'
231beautifulsoup4==4.11.1
232certifi==2022.9.24
233charset-normalizer==2.1.1
234idna==2.8
235requests==2.22.0
236soupsieve==2.3.2.post1
237toot==0.29.0
238urllib3==1.25.8
239urwid==2.1.2
240wcwidth==0.2.5
241EOF
242
243 # new 2022-11 packages
244 # beautifulsoup4==4.11.1
245 # certifi==2022.9.24
246 # charset-normalizer==2.1.1
247 # idna==3.4
248 # requests==2.28.1
249 # soupsieve==2.3.2.post1
250 # toot==0.29.0
251 # urllib3==1.26.13
252 # urwid==2.1.2
253 # wcwidth==0.2.5
254
255 # old 2019 packages
256 # beautifulsoup4==4.8.2
257 # certifi==2019.11.28
258 # chardet==3.0.4
259 # idna==2.8
260 # requests==2.22.0
261 # soupsieve==1.9.5
262 # toot==0.25.2
263 # urllib3==1.25.8
264 # urwid==2.1.0
265 # wcwidth==0.1.8
266
267 # i mixed in some old packages to get newer toot working on t9.
268
269 python3 -m pip install -r requirements.txt
270 deactivate
271 for account in ${mastodon_accounts[@]}; do
272 if ! toot activate $account@hostux.social &>/dev/null; then
273 printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}");
274 echo "Please login to the account named \"$account\" on https://hostux.social in your main browser then press enter."
275 echo "WARNING: if you log into an account other than \"$account\", this won't work"
276 read -r
277 toot login -i hostux.social
278 fi
279 done
280}
281
282# Usage: pdt-pip-setup
283pdt-pip-setup() {
284 if [[ ! -e ~/.local/bin/pip ]]; then
285 tmp=$(mktemp)
286 pyver=$(python3 --version | sed -r 's/.*(3\.[0-9]+).*/\1/')
287 echo fyi: detected pyver: $pyver. this should look something like 3.6
288
289 if dpkg --compare-versions 3.6 ge $pyver; then
290 # The bootstrap script at https://bootstrap.pypa.io/get-pip.py required 3.7+
291 # when i wrote this.
292 wget -O$tmp https://bootstrap.pypa.io/pip/$pyver/get-pip.py
293 else
294 wget -O$tmp https://bootstrap.pypa.io/get-pip.py
295 fi
296 python3 $tmp --user
297 hash -r
298 fi
299 python3 -m pip install --user -U virtualenv
300}
301
302# Usage: pdt-setup
303pdt-setup() {
304
c0e2704f
IK
305 mkdir -p ~/src
306 cd ~/src
4b6dbb81 307 for repo in errhandle rainbowstream video-tweet; do
c0e2704f
IK
308 if [[ -e $repo ]]; then
309 cd $repo
310 git fetch
311 git reset --hard origin/master
312 git clean -xfffd
313 cd ..
314 else
315 git clone https://vcs.fsf.org/git/$repo.git
316 fi
317 done
318 source ~/src/errhandle/err
319 cp ~/src/rainbowstream/rainbowstream/colorset/config ~/.rainbow_config.json
320
9667049b 321 pdt-pip-setup
c0e2704f 322
9667049b 323 toot-setup
c0e2704f
IK
324
325 cd ~/src/rainbowstream
326 python3 -m virtualenv -p python3 venv
327 source venv/bin/activate
328 python3 -m pip install -r requirements.txt
329 python3 -m pip install -e .
330 deactivate
331
c0e2704f
IK
332 for account in dbd fsf; do
333 if [[ ! -s ~/.rainbow_oauth-$account ]]; then
334 printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}");
335 echo "Please login to $account on twitter in your main browser then press enter. After rainbowstream prompt loads, quit with command q"
336 read -r
337 rbow -$account
338 fi
9667049b
IK
339 done
340 for account in dbd fsf; do
341 if [[ ! -s $HOME/.rainbow_oauth-$account ]]; then
342 echo "pdt-setup error: expected non-empty file at $HOME/.rainbow_oauth-$account by this point. try reruning pdt-setup and logging in to the correct twitter account in browser or contact ian"
7d2ea7b7
IK
343 return 1
344 fi
9667049b
IK
345 done
346 if diff -q $HOME/.rainbow_oauth-fsf $HOME/.rainbow_oauth-dbd &>/dev/null; then
347 echo "pdt-setup error: error, $HOME/.rainbow_oauth-fsf $HOME/.rainbow_oauth-dbd are the same. Did you follow the instructions closely and log into fsf and then dbd when prompted? try reruning pdt-setup and doing that"
348 return 1
349 fi
7d2ea7b7 350
9667049b 351 for account in dbd fsf; do
c0e2704f
IK
352 if [[ ! -s ~/.gnusocial_login-$account ]]; then
353 printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}");
354 read -r -p "please enter the password for $account@status.fsf.org > " pass
355 touch ~/.gnusocial_login-$account
356 chmod 600 ~/.gnusocial_login-$account
357 printf "%s\n" "$pass" > ~/.gnusocial_login-$account
358 fi
359 done
360
c0e2704f 361 err-allow
c70ad097 362 echo "pdt-setup complete"
c0e2704f 363}