From c7d649b690fb4459f370b9d1681c97ab07832cf9 Mon Sep 17 00:00:00 2001 From: Boris Paing Date: Wed, 18 Mar 2020 20:41:11 +0100 Subject: [PATCH] Less spammy behavior --- process-likes-g1tx.sh | 374 +++++++++++++++++++++++++++++++----------- 1 file changed, 281 insertions(+), 93 deletions(-) diff --git a/process-likes-g1tx.sh b/process-likes-g1tx.sh index 81deecc..e1b38e2 100755 --- a/process-likes-g1tx.sh +++ b/process-likes-g1tx.sh @@ -8,34 +8,40 @@ # License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/) ########################################################################################### # PREVENT DOUBLE PAYEMENT -# ADD G1 Layer 10 LOVE to message writer you like ! +# ADD Ğ1 Layer 10 LOVE to message writer you like ! ############################################################################################ -# Let's get G1 public and private keys +# Let's get Ğ1 public and private keys g1pub=$(cat ~/.ssb/secret.dunikey | grep "pub" | cut -d ' ' -f 2) g1priv=$(cat ~/.ssb/secret.dunikey | grep "sec" | cut -d ' ' -f 2) # SSB pubkey ssbpub=$(cat ~/.ssb/secret | grep public\" | cut -d ' ' -f 4 | cut -d '.' -f 1 | sed s/\"//g) +amountPerLikeInUD="0.05" +bold=$(tput bold) +normal=$(tput sgr0) + ############################################################################################ #### CHECK LIKE AND SEND LOVE -# Let's get G1 account balance +# Let's get Ğ1 account balance echo "" -echo "Welcome to the G1 SSB like microdonation system!" -echo " -MMMMMMMMMMMMMNk;'cdxxd:,c0WMMMMMMMMMMMMM +echo -e "${bold}Welcome${normal} to the Ğ1/SSB-like microdonation system!\n" +sleep 1 +echo "MMMMMMMMMMMMMNk;'cdxxd:,c0WMMMMMMMMMMMMM MMMMMMMMMMMMMNx,. .;kWMMMMMMMMMMMMM MMMMMMMMMMMMMMMNOdlccld0NMMMMMMMMMMMMMMM MMMMMMMMMMMWXko:,'....',:okXWMMMMMMMMMMM MMMMMMMMMNk:. .cOWMMMMMMMMM -MMMMMMMW0: .c0MMMMMMMM -MMMMMMWk. 'lxkOOkdc' .cOWMMMMMMM +MMMMMMMW0: .c0MMMMMMMM" +sleep 1 +echo "MMMMMMWk. 'lxkOOkdc' .cOWMMMMMMM MMMMMMO' 'kNMMMMMMMMNxcoOXWMMMMMMMMM MMMMMNl '0MMMMMMMMMMMMMMMMMMMMMMMMMM MMMMMX; cNMMMMMMMNOkkkkkkkkkkONMMMMM MMMMMNc ;XMMMMMMMNd' .OMMMMM MMMMMWx. cKMMMMMMMWKc. .OMMMMM -MMMMMMNo. .lkKXNNXKkc. .OMMMMM -MMMMMMMNd. ...... .OMMMMM +MMMMMMNo. .lkKXNNXKkc. .OMMMMM" +sleep 1 +echo "MMMMMMMNd. ...... .OMMMMM MMMMMMMMWKl. 'c:. .OMMMMM MMMMMMMMMMWXkc,.. ..,lkXWWO:;OMMMMM MMMMMMMMMMMMMMWX0OxddxO0XWMMMMMMWXNMMMMM @@ -44,35 +50,30 @@ MMMMMMMMMMMMMMMMK, '0MMMMMMMMMMMMMMMM MMMMMMMMMMMMMMMMNd. .oNMMMMMMMMMMMMMMMM " sleep 1 -echo "" -echo "You know your SSB pubkey:" -echo $ssbpub -sleep 1 -echo "" -echo "...but did you know it is also a valid G1 wallet?" -echo $g1pub +printf "You know your SSB pubkey:\n%s\n\n" $ssbpub sleep 2 -echo "" -echo "Let's check the current balance of your wallet!" +printf "...but did you know it is also a valid Ğ1 wallet?\n%s\n\n" $g1pub sleep 2 -echo "" -echo "We are interrogating the G1 blockchain to check if anyone has already sent G1..." +printf "Let's check the current balance of your wallet!\n\n" sleep 1 -echo "" -echo "A moment please..." -echo "" +printf "We are interrogating the Ğ1 blockchain to check if anyone has already sent you Ğ1...\n\n" +sleep 2 +printf "A moment please...\n\n" sleep 1 +silkajRelativeAmountPattern='Total\sRelative\s+=\s+(.*)\s+UD' + + duniter_server="duniter-g1.p2p.legal:443" echo "Testing server $duniter_server..." echo "" -silkaj -p "$duniter_server" balance $g1pub 2>/dev/null -if [ $? -eq 1 ] +silkajOutput=$(silkaj -p "$duniter_server" balance $g1pub 2>/dev/null) +if [ $? -ne 0 ] then duniter_server="g1.duniter.org:443" echo "Testing server $duniter_server..." echo "" - silkaj -p "$duniter_server" balance $g1pub 2>/dev/null + silkajOutput=$(silkaj -p "$duniter_server" balance $g1pub 2>/dev/null) if [ $? -eq 1 ] then @@ -81,106 +82,293 @@ then fi fi -echo "Have any money? Then let's send G1love. Press ENTER to continue. " && read -########################################################################################### +if [[ $silkajOutput =~ $silkajRelativeAmountPattern ]] +then + balance="${BASH_REMATCH[1]}" +else + echo "Account balance wasn't found." + exit 1 +fi + +printf "You have ${bold}%s UDĞ1${normal} on your Duniter Ğ1 wallet.\n\n" "$balance" +sleep 2 +printf "Want to show your appreciation of your fellow butts' posts while helping spreading awareness about libre currencies?\n\n" +sleep 2 + + +# BEGIN timestamp computation self=$(sbotc whoami | jq -r .id) || exit 1 ssb_dir=~/.${ssb_appname:-ssb} id_part=$(echo "$self" | sed 's/\//_/g' | tail -c +2 | head -c 9) state_file=$ssb_dir/likes-g1-$id_part.ts -if [ -s "$state_file" ] -then last_ts=$(cat "$state_file") || exit 1 -else - last_ts=$(date -u +%s%N | cut -b1-13) - last_ts=$((last_ts - 3600000)) # timestamp from 1h ago +current_ts=$(date -u +%s%N | cut -b1-13) +if [ -s "$state_file" ] +then + last_ts=$(cat "$state_file") || exit 1 +else + last_ts=$((current_ts - 3600000)) # timestamp from 1h ago #else last_ts=null fi +days_from_last_tx=$(( (current_ts - last_ts) / (24*60*60*1000) )) +# END timestamp computation + + +printf "First, let's see how much ❤ you gave lately...\n\n" +sleep 1 + +declare -a liked_authors +declare -A likesNbPerAuthor + +declare -A likedPosts +declare -A likesNbPerPost + +declare -A postsTimestamps + +declare -A excerpts + +totalLikesGiven=0 + process_msg() { + msg=$1 target_id=$(printf %s "$msg" | jq -r '.value?.content?.vote?.link') || return 1 target_msg=$(sbotc -e get "$target_id") || return 1 target_author=$(printf %s "$target_msg" | jq -r .author) || return 1 - author_s_name=$(sbotc query.read '{"query":[{"$filter":{"value":{"author": "'"$target_author"'", "content":{"type":"about", "about": "'"$target_author"'"}}}}]}' | jq .value?.content?.name | grep -v null | tail -n 1) - root_id=$(printf %s "$target_msg" | jq -r .content?.root) || return 1 - [[ $root_id == "null" ]] && root_id=$target_id - g1_author=$(echo $target_author | cut -d '.' -f 1 | cut -d '@' -f2 | base64 -d | base58) - msg_excerpt=$(printf %s "$target_msg" | jq -r .content?.text | head -n 10) || return 1 + + msg_content=$(printf %s "$target_msg" | jq -r .content?.text) || return 1 + + # beware of markdown ! + msg_excerpt=${msg_content:0:10} + + #root_id=$(printf %s "$target_msg" | jq -r .content?.root) || return 1 + #[[ $root_id = "null" ]] && root_id=$target_id } -bold=$(tput bold) -normal=$(tput sgr0) -sbotc query.read '{"query":[{"$filter":{"value":{"author":"'"$self"'","content":{"type":"vote", "vote":{"expression":"Like"}},"timestamp":{"$gt":'"$last_ts"'}}}}]}' | while read -r msg +process_author() { + + author_id=$1 + g1_author=$(echo $author_id | cut -d '.' -f 1 | cut -d '@' -f2 | base64 -d | base58) + author_name=$(sbotc query.read '{"query":[{"$filter":{"value":{"author": "'"$author_id"'", "content":{"type":"about", "about": "'"$author_id"'"}}}}]}' | jq .value?.content?.name | grep -v null | tail -n 1) +} + +authorsNb=0 + +i=0 + +messages=$(sbotc query.read '{"query":[{"$filter":{"value":{"author":"'"$self"'","content":{"type":"vote", "vote":{"expression":"Like"}},"timestamp":{"$gt":'"$last_ts"'}}}}]}') +while read -r msg do + priv=$(printf %s "$msg" | jq .value.content.private) - if [[ $priv == true ]] + if [[ $priv = true ]] then printf "Private message $priv, continue to next one\n" >&2 continue fi - - if ! ts=$(printf %s "$msg" | jq -r .value.timestamp) - then - printf 'Unable to get message timestamp\n' >&2 - exit 1 - fi - - if ! echo "$ts" > "$state_file"~ - then - printf 'Unable to write to backup state file.\n' >&2 - exit 1 - fi if ! process_msg "$msg" then msg_id=$(printf %s "$msg" | jq -r .key) - printf 'Unable to process message %s\n' "$msg_id" >&2 + printf '\nUnable to process message %s\n' "$msg_id" >&2 exit 1 fi - - echo "" - echo "================================================================" - printf "Let's thank ${bold}@%s ${normal}for their message: \n" "${author_s_name:1:-1}" - echo "================================================================" - printf "%s" "$msg_excerpt" - echo "" - echo "----------------------------------------------------------------" + if [[ $g1_author = $g1pub ]]; then - if [[ $g1_author != $g1pub ]]; then - #printf '%s\n' "silkaj -af --file ~/.ssb/secret.dunikey tx --output $g1_author --amountUD 0.1 --comment _SSB:LIKE:$target_id" - #### SEND 10 LOVE = 0.1 DU to $g1_author wallet - silkaj -p "$duniter_server" -af --file ~/.ssb/secret.dunikey tx --output $g1_author --amountUD 0.1 --comment "_SSB:LIKE:$target_id" -y 2>/dev/null - - #### WRITE RESPONSE MESSAGE - if [ ! -f ~/.ssb/db/g1likes ]; then - touch ~/.ssb/db/g1likes - fi - - if ! grep -Fxq $target_author ~/.ssb/db/g1likes; then - echo $target_author >> ~/.ssb/db/g1likes - thank_you_msg=$(printf '[@%s](%s) > Thanks for this post ; I have just sent you G1 libre money. Use it with [Cesium](https://cesium.app). Get it from [https://git.p2p.legal/Axiom-Team/ssb-g1like](https://git.p2p.legal/Axiom-Team/ssb-g1like)' "${author_s_name:1:-1}" "$target_author") - sbotc publish '{"type":"post","text":"'"$thank_you_msg"'", "branch": "'"$target_id"'", "root": "'"$root_id"'"}' 2>&1>/dev/null - echo "----------------------------------------------------------------" - printf "Since it's the first time you sent G1 to %s, he was sent this message: \n\n%s \n" "$author_s_name" "$thank_you_msg" - echo "----------------------------------------------------------------" - fi - - #printf "0.1 G1UD sent to %s!\n" "$author_s_name" - #echo "----------------------------------------------------------------" - echo "" - echo "" - - sleep 20 # DO NOT OVER CHARGE DUNITER - else echo "I LIKE MY MESSAGE $target_id" + + else + + liked_authors[${#liked_authors[@]}]=$target_author + + ((totalLikesGiven++)) + + if [[ ${likesNbPerAuthor[$target_author]} -eq 0 ]] + then + likesNbPerAuthor[$target_author]=1 + likedPosts[$target_author]="" + else + likesNbPerAuthor[$target_author]=$((${likesNbPerAuthor[$target_author]} + 1)) + fi + + + if [[ ${likesNbPerPost[$target_id]} -eq 0 ]] + then + likesNbPerPost[$target_id]=1 + + likedPosts[$target_author]+=$target_id + likedPosts[$target_author]+="\n" + else + ((likesNbPerPost[$target_id]++)) + fi + + + excerpts[$target_id]=$msg_excerpt + + if ! postsTimestamps[$target_id]=$(printf %s "$msg" | jq -r .value.timestamp) + then + printf 'Unable to get message timestamp\n' >&2 + exit 1 + fi + + ((i++)) fi - if ! mv "$state_file"~ "$state_file" +done < <(printf '%s\n' "$messages") + +liked_authors_nb=${#liked_authors[@]} + +if [[ $totalLikesGiven -eq 0 ]] +then + printf "You did not give any like during the past %s days or they have already been processed.\n\n" "$days_from_last_tx" + printf "Try again in a few days.\n\n" +fi + +printf "You gave ${bold}%s❤${normal} during the past %s days.\n\n" "$totalLikesGiven" "$days_from_last_tx" +sleep 2 + +printf "How many UDĞ1 do you want to send per each like you gave? (default is ${bold}%s UDĞ1${normal}) " "$amountPerLikeInUD" +read a +echo "" + +amountPerLikeInUD=$a + +amountGiven=$(echo "$totalLikesGiven * $amountPerLikeInUD" | bc -l) + +if (( $(echo "$amountGiven <= $balance" | bc -l) )); then + newBalance=$(echo "$balance - $amountGiven" | bc -l) + printf "${bold}%s UDĞ1${normal} will be given.\n\n" "$amountGiven" + sleep 1 + printf "After sending transactions, your new balance will be ${bold}%s UDĞ1${normal}\n\n" "$newBalance" + sleep 1 + printf "Press ENTER to continue: " && read + printf "\n" +else + printf "You don't have enough UDĞ1 to send all transactions.\n\n" + sleep 1 + printf "${bold}%s UDĞ1${normal} are needed.\n\n" "$amountGiven" + sleep 1 + printf "Try again with a different amount per like.\n\n" + maxAmountPerLike=$(awk -vp=$balance -vq=$totalLikesGiven 'BEGIN{printf "%.2f" ,p / q}') + sleep 1 + printf "Maximum amount per like possible: ${bold}%s UDĞ1${normal}\n\n" "$maxAmountPerLike" + exit 1 +fi + +# Let's construct thank you message and send transactions! + +output="" +output+=$(printf "Huge thanks to the ScuttleButt community for all the fascinating posts you allowed me to read in the past %s days." "$days_from_last_tx") +output+="\n\nAs a means to thank you further, I have just sent you #Ğ1 libre money.\n\n" +output+="These messages, though they might feel spammy (sorry) are also a way for the Ğ1 community to spread awareness about [libre currencies](https://libre-currency.org/) so we can build #resilience at every level.\n\n" +output+="You can learn how to spend your freshly earned money at [https://git.p2p.legal/Axiom-Team/ssb-g1like](https://git.p2p.legal/Axiom-Team/ssb-g1like)\n\n" +output+="Below is the list of SSB users whose content I liked recently, and the amount each one was given:\n\n" +output+='| thanks to | for their posts | given |\n' +output+='| --- | --- | ---- |\n' + +for author_id in ${!likesNbPerAuthor[@]} +do + process_author $author_id + + # (Legacy) saving authors we have already mentionned in a message + likedAuthorsFile=$ssb_dir/db/g1likes + if [ ! -f $likedAuthorsFile ]; then + touch $likedAuthorsFile + fi + + if ! grep -Fxq $author_id $likedAuthorsFile; then + echo $author_id >> $likedAuthorsFile + fi + + author_amount=$(bc <<< "${likesNbPerAuthor[$author_id]} * $amountPerLikeInUD") + output+=$(printf "| [@%s](%s) " "${author_name:1:-1}" "$author_id") + output+="| " + + posts=${likedPosts[$author_id]} + thisAuthorLikedPosts=( ${posts//\\n/ } ) + + j=0 + + for post_id in ${thisAuthorLikedPosts[@]} + do + if [[ $j -gt 0 ]] + then + output+=", " + fi + + output+=$(printf " %s❤" "${likesNbPerPost[$post_id]}") + #output+=$(printf "[%s](%s)" "${post_id:0:9}" "$post_id") + output+=$(printf "[\`%s\`](%s)" "${excerpts[$post_id]}" "$post_id") + + ((j++)) + done + + output+=$(printf "| %s UDĞ1 " $author_amount) + + output+="|\n" + + #printf '%s\n' "silkaj -af --file ~/.ssb/secret.dunikey tx --output $g1_author --amountUD $author_amount --comment "Thx for your cool posts on ScuttleButt" + #silkaj -p "$duniter_server" -af --file ~/.ssb/secret.dunikey tx --output $g1_author --amountUD $author_amount --comment "Thx for your cool posts on ScuttleButt" -y 2>/dev/null + + printf "\n${bold}%s UDĞ1${normal} sent to %s!\n\n" "$author_amount" "${author_name:1:-1}" + + # Let's save the timestamp of the last processed message + if ! echo "${postsTimestamps[$target_id]}" > "$state_file"~ then - msg_id=$(printf %s "$msg" | jq -r .key) - printf 'Unable to write to state file. Update state file manually to prevent %s from being processed twice.\n' "$msg_id" >&2 + printf 'Unable to write to backup state file.\n' >&2 exit 1 fi + + #if ! mv "$state_file"~ "$state_file" + #then + # msg_id=$(printf %s "$msg" | jq -r .key) + # printf 'Unable to write to state file. Update state file manually to prevent %s from being processed twice.\n' "$msg_id" >&2 + # exit 1 + #fi + + #sleep 20 # DO NOT OVER CHARGE DUNITER done + +printf "\n%s UDĞ1 sent to %s butts!\n\n" "$amountGiven" "$liked_authors_nb" + +# Let's publicly thank everyone! +#echo -e "$output" + +# the following produces error: +# "sbotc: unexpected end of parent stream" +# must be a non-escaped quote problem... +#thank_you_msg=$(printf "%q" "$output") +#sbotc publish '{"type":"post","text":"'"$thank_you_msg"'"}' 2>&1>/dev/null + + +msg_file=~/thank-your-butts-$last_ts.md +echo -e $output > $msg_file + +printf "What now ?\n\n" + +sleep 1 + +printf "A surprise is awaiting in your home dir (~).\n\n" + +sleep 2 + +printf "It's a file.\n\n" + +sleep 2 + +printf "It's called thank-your-butts-$last_ts.md.\n\n" + +sleep 2 + +printf "Customize it to your needs to thank you fellow butts publicly and help spread awareness about libre currencies :-)\n\n" + +sleep 3 + +printf "Then delete it.\n\n" + +sleep 2 + +printf "...because it won't self-destruct, haha :D \n\n"