21cb00fae96c60907bfe7c2bbf179a8e7669e958
[pdt.git] / pdt.sh
1 #!/bin/bash
2 # Copyright (C) 2019 Ian Kelling
3 # SPDX-License-Identifier: AGPL-3.0-or-later
4
5 # meant to be sourced.
6
7 PATH="$HOME/.local/bin:$PATH"
8
9 # usage: rbow [-PROFILE_NAME] [COMMAND]
10 #
11 # Wrapper for rainbowstream to use multiple logins and tweet directly
12 # from the command line. PROFILE_NAME can be anything you want.
13 rbow() {
14 local oath f
15 oath=$HOME/.rainbow_oauth
16 if [[ $1 == -* ]]; then
17 rm -f $oath
18 ln -s $oath$1 $oath
19 shift
20 fi
21 source ~/src/rainbowstream/venv/bin/activate
22 if (($#)); then
23 f=$(mktemp)
24 cat >$f <<'EOF'
25 # adds a short delay after each send for more reliable operation
26 set force_conservative 0
27 spawn "rainbowstream"
28 # wait for prompt
29 expect -nocase timeout {exit 1} "@*]: "
30 set cmd [lindex $argv 0];
31 send "$cmd\r\rq\r"
32 interact
33 EOF
34 expect $f "$*" || { deactivate; rm -f $f; return 1; }
35 rm -f $f
36 else
37 rainbowstream
38 fi
39 deactivate
40 }
41
42 diaspora() {
43 source ~/src/diaspy/venv/bin/activate
44 python3 ~/src/jan-pona-mute/jan-pona-mute.py "$@" || { deactivate; return 1; }
45 deactivate
46 }
47
48 # usage: toot [-PROFILE_NAME] [TOOT_ARGS]
49 toot() {
50 local account
51 source ~/src/toot/venv/bin/activate
52 if [[ $1 == -* ]]; then
53 account=${1#-}
54 shift
55 command toot activate --quiet $account || { deactivate; return 1; }
56 fi
57 command toot "$@" || { deactivate; return 1; }
58 deactivate
59 }
60
61
62 # post to mastodon + twitter + gnu social post + diaspora
63 #
64 # usage: pdt [--dbd] [-m MEDIA_FILE] [-v VIDEO_PATH] [POST]
65 pdt() {
66 local video media rbow_account gs_account mastodon_account dbd video rbow_arg toot_arg dia_arg gs_arg
67 if [[ $pdttest ]]; then
68 rbow_account=iank
69 gs_account=fsfes
70 mastodon_account=iank@hostux.social
71 else
72 rbow_account=fsf
73 gs_account=fsf
74 mastodon_account=fsf@hostux.social
75 fi
76 dbd=false
77 video=false
78 while [[ $1 == -* ]]; do
79 case $1 in
80 -m)
81 media="$2"
82 shift 2
83 rbow_arg=" --i $media"
84 toot_arg="--media $media"
85 dia_arg="-p $media "
86 gs_arg="-F media=@$media"
87 ;;
88 --dbd)
89 dbd=true
90 rbow_account=dbd
91 gs_account=dbd
92 mastodon_account=endDRM@hostux.social
93 shift
94 ;;
95 -v)
96 video=true
97 media="$2"
98 shift 2
99 ;;
100 esac
101 done
102 if [[ $media ]]; then
103 if [[ ! -e $media ]]; then
104 echo "error: file not found $media"
105 return 1
106 fi
107 if [[ $media == *\ * ]]; then
108 echo "error: file path contains a space. move it to non-space path"
109 return 1
110 fi
111 fi
112 # if we have no argument
113 if (( ! $# )); then
114 read -r -p "input PDT text: " input
115 set -- "$input"
116 fi
117 if [[ $- == *i* ]]; then
118 echo "About to PDT the following line. Press enter to confirm or ctrl-c to quit:"
119 echo "$input"
120 read
121 fi
122 if $video; then
123 local oath
124 oath=$HOME/.rainbow_oauth
125 account=fsf
126 if $dbd; then
127 account=dbd
128 fi
129 rm -f $oath
130 ln -s ${oath}-$account $oath
131 python3 ~/src/video-tweet/async-upload.py "$media" "$*"
132 return
133 fi
134 fails=()
135 if ! rbow -$rbow_account t "$*" $rbow_arg; then
136 fails+=(tweet)
137 fi
138 if ! toot -$mastodon_account post "$*" $toot_arg; then
139 fails+=(toot)
140 fi
141 if ! $dbd; then
142 if ! printf "post %s\n" "${dia_arg}$*" | diaspora; then
143 fails+=(diaspora)
144 fi
145 fi
146 # https://gnusocial.net/doc/twitterapi
147 if ! curl -o /dev/null -sS -u "$gs_account:$(cat ~/.gnusocial_login-$gs_account)" \
148 $gs_arg -F "status=$*" https://status.fsf.org/api/statuses/update.xml; then
149 fails+=(gnu-social)
150 fi
151 if (( ${#fails[@]} )); then
152 printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}"); echo
153 echo "FSF ERROR: ${fails[*]} might not have posted" >&2
154 fi
155 }
156
157 pdt-setup() {
158
159 if [[ $pdttest ]]; then
160 mastodon_accounts=(iank)
161 else
162 mastodon_accounts=(fsf endDRM)
163 fi
164
165 mkdir -p ~/src
166 cd ~/src
167 for repo in errhandle rainbowstream diaspy jan-pona-mute video-tweet; do
168 if [[ -e $repo ]]; then
169 cd $repo
170 git fetch
171 git reset --hard origin/master
172 git clean -xfffd
173 cd ..
174 else
175 git clone https://vcs.fsf.org/git/$repo.git
176 fi
177 done
178 source ~/src/errhandle/err
179 cp ~/src/rainbowstream/rainbowstream/colorset/config ~/.rainbow_config.json
180
181 if [[ ! -e ~/.local/bin/pip ]]; then
182 tmp=$(mktemp)
183 wget -O$tmp https://bootstrap.pypa.io/get-pip.py
184 python3 $tmp --user
185 hash -r
186 fi
187
188
189 if [[ ! -e ~/.local/bin/virtualenv ]]; then
190 python3 -m pip install --user virtualenv
191 fi
192
193 cd ~/src/rainbowstream
194 python3 -m virtualenv -p python3 venv
195 source venv/bin/activate
196 python3 -m pip install -r requirements.txt
197 python3 -m pip install -e .
198 deactivate
199
200
201 # This repo's upstream is https://alexschroeder.ch/cgit/diaspy which is
202 # recommended in the install instructions here:
203 # https://alexschroeder.ch/cgit/jan-pona-mute/about/
204 cd ~/src/diaspy
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 rm -rf ~/src/toot
212 mkdir -p ~/src/toot
213 cd ~/src/toot
214 python3 -m virtualenv -p python3 venv
215 source venv/bin/activate
216 # pip freeze after a pip install.
217 cat >requirements.txt <<'EOF'
218 beautifulsoup4==4.8.2
219 certifi==2019.11.28
220 chardet==3.0.4
221 idna==2.8
222 requests==2.22.0
223 soupsieve==1.9.5
224 toot==0.25.2
225 urllib3==1.25.8
226 urwid==2.1.0
227 wcwidth==0.1.8
228 EOF
229 python3 -m pip install -r requirements.txt
230 deactivate
231
232
233 if [[ ! -s ~/.config/jan-pona-mute/login ]]; then
234 mkdir ~/.config/jan-pona-mute
235 account=fsf@framasphere.org
236 read -r -p "enter the password for $account > " pass
237 # background: format for this found using the save command
238 cat >~/.config/jan-pona-mute/login <<EOF
239 account $account
240 password $pass
241 login
242 EOF
243 fi
244
245 for account in dbd fsf; do
246 if [[ ! -s ~/.rainbow_oauth-$account ]]; then
247 printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}");
248 echo "Please login to $account on twitter in your main browser then press enter. After rainbowstream prompt loads, quit with command q"
249 read -r
250 rbow -$account
251 fi
252 if [[ ! -s ~/.gnusocial_login-$account ]]; then
253 printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}");
254 read -r -p "please enter the password for $account@status.fsf.org > " pass
255 touch ~/.gnusocial_login-$account
256 chmod 600 ~/.gnusocial_login-$account
257 printf "%s\n" "$pass" > ~/.gnusocial_login-$account
258 fi
259 done
260
261 for account in ${mastodon_accounts[@]}; do
262 if ! toot activate $account@hostux.social &>/dev/null; then
263 printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}");
264 echo "Please login to $account on https://hostux.social in your main browser then press enter."
265 read -r
266 toot login -i hostux.social
267 fi
268 done
269 err-allow
270 }