+#!/bin/bash
+# Copyright (C) 2019 Ian Kelling
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+# meant to be sourced.
+
+PATH="$HOME/.local/bin:$PATH"
+
+# usage: rbow [-PROFILE_NAME] [COMMAND]
+#
+# Wrapper for rainbowstream to use multiple logins and tweet directly
+# from the command line. PROFILE_NAME can be anything you want.
+rbow() {
+ local oath
+ oath=$HOME/.rainbow_oauth
+ if [[ $1 == -* ]]; then
+ rm -f $oath
+ ln -s $oath$1 $oath
+ shift
+ fi
+ source ~/src/rainbowstream/venv/bin/activate
+ if (($#)); then
+ f=$(mktemp)
+ cat >$f <<'EOF'
+# adds a short delay after each send for more reliable operation
+set force_conservative 0
+spawn "rainbowstream"
+# wait for prompt
+expect -nocase timeout {exit 1} "@*]: "
+set cmd [lindex $argv 0];
+send "$cmd\r\rq\r"
+interact
+EOF
+ expect $f "$*" || { deactivate; rm -f $f; return 1; }
+ rm -f $f
+ else
+ rainbowstream
+ fi
+ deactivate
+}
+
+diaspora() {
+ source ~/src/diaspy/venv/bin/activate
+ python3 ~/src/jan-pona-mute/jan-pona-mute.py "$@" || { deactivate; return 1; }
+ deactivate
+}
+
+# usage: toot [-PROFILE_NAME] [TOOT_ARGS]
+toot() {
+ source ~/src/toot/venv/bin/activate
+ if [[ $1 == -* ]]; then
+ account=${1#-}
+ shift
+ command toot activate --quiet $account || { deactivate; return 1; }
+ fi
+ command toot "$@" || { deactivate; return 1; }
+ deactivate
+}
+
+
+# post to mastodon + twitter + gnu social post + diaspora
+#
+# usage: pdt [--dbd] [-m MEDIA_FILE] [POST]
+pdt() {
+ if [[ $pdttest ]]; then
+ rbow_account=iank
+ gs_account=fsfes
+ mastodon_account=iank@hostux.social
+ else
+ rbow_account=fsf
+ gs_account=fsf
+ mastodon_account=fsf@hostux.social
+ fi
+ dbd=false
+ while [[ $1 == -* ]]; do
+ case $1 in
+ -m)
+ media="$2"
+ shift 2
+ if [[ ! -e $media ]]; then
+ echo "error: file not found $media"
+ return 1
+ fi
+ if [[ $media == *\ * ]]; then
+ echo "error: file path contains a space. move it to non-space path"
+ return 1
+ fi
+ rbow_arg=" --i $media"
+ toot_arg="--media $media"
+ dia_arg="-p $media "
+ gs_arg="-F media=@$media"
+ ;;
+ --dbd)
+ dbd=true
+ rbow_account=dbd
+ gs_account=dbd
+ mastodon_account=endDRM@hostux.social
+ shift
+ ;;
+ esac
+ done
+ # if we have no argument
+ if (( ! $# )); then
+ read -r -p "input PDT text: " input
+ set -- "$input"
+ fi
+ if [[ $- == *i* ]]; then
+ echo "About to PDT the following line. Press enter to confirm or ctrl-c to quit:"
+ echo "$input"
+ read
+ fi
+ fails=()
+ if ! rbow -$rbow_account t "$*" $rbow_arg; then
+ fails+=(tweet)
+ fi
+ if ! toot -$mastodon_account post "$*" $toot_arg; then
+ fails+=(toot)
+ fi
+ if [[ ! $dbd ]]; then
+ if ! printf "post %s\n" "${dia_arg}$*" | diaspora; then
+ fails+=(diaspora)
+ fi
+ fi
+ # https://gnusocial.net/doc/twitterapi
+ if ! curl -o /dev/null -sS -u "$gs_account:$(cat ~/.gnusocial_login-$gs_account)" \
+ $gs_arg -F "status=$*" https://status.fsf.org/api/statuses/update.xml; then
+ fails+=(gnu-social)
+ fi
+ if (( ${#fails[@]} )); then
+ printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}"); echo
+ echo "FSF ERROR: ${fails[*]} might not have posted" >&2
+ fi
+}
+
+pdt-setup() {
+
+ if [[ $pdttest ]]; then
+ mastodon_accounts=(iank)
+ else
+ mastodon_accounts=(fsf endDRM)
+ fi
+
+ mkdir -p ~/src
+ cd ~/src
+ for repo in errhandle rainbowstream diaspy jan-pona-mute; do
+ if [[ -e $repo ]]; then
+ cd $repo
+ git fetch
+ git reset --hard origin/master
+ git clean -xfffd
+ cd ..
+ else
+ git clone https://vcs.fsf.org/git/$repo.git
+ fi
+ done
+ source ~/src/errhandle/err
+ cp ~/src/rainbowstream/rainbowstream/colorset/config ~/.rainbow_config.json
+
+ if [[ ! -e ~/.local/bin/pip ]]; then
+ tmp=$(mktemp)
+ wget -O$tmp https://bootstrap.pypa.io/get-pip.py
+ python3 $tmp --user
+ hash -r
+ fi
+
+
+ if [[ ! -e ~/.local/bin/virtualenv ]]; then
+ python3 -m pip install --user virtualenv
+ fi
+
+ cd ~/src/rainbowstream
+ python3 -m virtualenv -p python3 venv
+ source venv/bin/activate
+ python3 -m pip install -r requirements.txt
+ python3 -m pip install -e .
+ deactivate
+
+
+ # This repo's upstream is https://alexschroeder.ch/cgit/diaspy which is
+ # recommended in the install instructions here:
+ # https://alexschroeder.ch/cgit/jan-pona-mute/about/
+ cd ~/src/diaspy
+ python3 -m virtualenv -p python3 venv
+ source venv/bin/activate
+ python3 -m pip install -r requirements.txt
+ python3 -m pip install -e .
+ deactivate
+
+ rm -rf ~/src/toot
+ mkdir -p ~/src/toot
+ cd ~/src/toot
+ python3 -m virtualenv -p python3 venv
+ source venv/bin/activate
+ # pip freeze after a pip install.
+ cat >requirements.txt <<'EOF'
+beautifulsoup4==4.8.2
+certifi==2019.11.28
+chardet==3.0.4
+idna==2.8
+requests==2.22.0
+soupsieve==1.9.5
+toot==0.25.2
+urllib3==1.25.8
+urwid==2.1.0
+wcwidth==0.1.8
+EOF
+ python3 -m pip install -r requirements.txt
+ deactivate
+
+
+ if [[ ! -s ~/.config/jan-pona-mute/login ]]; then
+ mkdir ~/.config/jan-pona-mute
+ account=fsf@framasphere.org
+ read -r -p "enter the password for $account > " pass
+ # background: format for this found using the save command
+ cat >~/.config/jan-pona-mute/login <<EOF
+account $account
+password $pass
+login
+EOF
+ fi
+
+ for account in dbd fsf; do
+ if [[ ! -s ~/.rainbow_oauth-$account ]]; then
+ printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}");
+ echo "Please login to $account on twitter in your main browser then press enter. After rainbowstream prompt loads, quit with command q"
+ read -r
+ rbow -$account
+ fi
+ if [[ ! -s ~/.gnusocial_login-$account ]]; then
+ printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}");
+ read -r -p "please enter the password for $account@status.fsf.org > " pass
+ touch ~/.gnusocial_login-$account
+ chmod 600 ~/.gnusocial_login-$account
+ printf "%s\n" "$pass" > ~/.gnusocial_login-$account
+ fi
+ done
+
+ for account in ${mastodon_accounts[@]}; do
+ if ! toot activate $account@hostux.social &>/dev/null; then
+ printf "$(tput setaf 5)█$(tput sgr0)%.0s" $(eval echo "{1..${COLUMNS:-60}}");
+ echo "Please login to $account on https://hostux.social in your main browser then press enter."
+ read -r
+ toot login -i hostux.social
+ fi
+ done
+ err-allow
+}