#!/bin/sh if [ -z "$instance" ]; then instance=$(jj -i config.json instance) fi alias default_auth_browser=links export main_basedir=$(dirname $0) proxy_init() { main_proxy=$(jj -i config.json main_proxy) if [ -n "$main_proxy" ]; then default_connect_protocol=$(jj -i config.json connect_protocol_via_main_proxy) ALL_PROXY="$main_proxy" elif [ $(echo "$instance" | grep -q 'i2p$' ; echo $?) -eq 0 ]; then default_connect_protocol='http' ALL_PROXY=$(jj -i config.json i2p_http_proxy_addr) elif [ $(echo "$instance" | grep -q 'onion$'; echo $?) -eq 0 ]; then default_connect_protocol='https' ALL_PROXY=$(jj -i config.json tor_proxy_addr) else default_connect_protocol='https' ALL_PROXY='' fi export default_connect_protocol export ALL_PROXY } proxy_init instance_point="$default_connect_protocol://$instance/api/v1" instance_point_pleroma="$default_connect_protocol://$instance/api/pleroma" instance_hist='instance.hist' enabled_nsfw=$(jj -i config.json enabled_nsfw) nsfw_only=$(jj -i config.json nsfw_only) hide_reblogs=$(jj -i config.json hide_reblogs) max_statuses=$(jj -i config.json max_statuses) default_visibility=$(jj -i config.json default_visibility) default_content_type=$(jj -i config.json default_content_type) format_time=$(jj -i config.json format_time) boost_symbol=$(jj -i config.json boost_symbol) statuses_separator=$(jj -i config.json statuses_separator) reversed_statuses=$(jj -i config.json reversed_statuses) quoting_reply=$(jj -i config.json quoting_reply) copy_mentions=$(jj -i config.json copy_mentions) per_status_mode=$(jj -i config.json per_status_mode) default_media_player=$(jj -i config.json default_media_player) #[AUTH SECTION] mkdir -m 711 -p .app_sessions touch .auth.json chmod 600 .auth.json make_login() { auth="$(jj -i .auth.json "$(echo "$instance" | sed 's/\./\\\./g')")" echo "Instance: $instance" if [ -n "$auth" ]; then default_curl_opt() { curl -s --compressed -H "Authorization: Bearer $auth" "$@" } post_request() { curl -s --compressed -X POST -H "Authorization: Bearer $auth" "$@" } put_request() { curl -s --compressed -X PUT -H "Authorization: Bearer $auth" "$@" } delete_request() { curl -s --compressed -X DELETE -H "Authorization: Bearer $auth" "$@" } echo '+Authorized account+' export default_curl_opt export post_request export put_request export delete_request else default_curl_opt() { curl -s --compressed "$1" } export default_curl_opt export post_request= echo 'Please make auth and restart' fi } make_login auth_api_create_client() { if [ ! -e ".app_sessions/$instance" ]; then curl -s --compressed --url "$instance_point/apps" \ --data-urlencode 'client_name=pleroma-cli' \ --data-urlencode 'redirect_uris=urn:ietf:wg:oauth:2.0:oob' \ --data-urlencode 'scopes=read write follow' \ --data-urlencode 'website=https://gitea.phreedom.club/localhost_frssoft/pleroma-cli' \ --output ".app_sessions/$instance" \ --create-file-mode 0600 fi } auth_api_get_code() { auth_api_create_client client_id=$(jj -i ".app_sessions/$instance" client_id) default_auth_browser "https://$instance/oauth/authorize?client_id=$client_id&response_type=code&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=read+write+follow" echo 'Input token-code:' read pass } auth_api_get_token() { auth_api_get_code clear client_id=$(jj -i ".app_sessions/$instance" client_id) client_secret=$(jj -i ".app_sessions/$instance" client_secret) token=$(curl -s --compressed --url "https://$instance/oauth/token" \ --data-urlencode 'grant_type=authorization_code' \ --data-urlencode "client_id=$client_id" \ --data-urlencode "client_secret=$client_secret" \ --data-urlencode "redirect_uri=urn:ietf:wg:oauth:2.0:oob" \ --data-urlencode 'scope=read write follow' \ --data-urlencode "code=$pass" | jj access_token) jj -p -i .auth.json -v "$token" "$(echo "$instance" | sed 's/\./\\\./g')" -o .auth.json } #[AUTH SECTION END] #[MIGRATION SECTION] backup_restore_menu() { clear echo "Backup/Restore menu Backups will be placed to folder backups_$instance Hint: For restore create folder 'restore' and copy 'friends.csv, blocks.csv, mutes.csv' in to folder Note: check selected instance before backup/restore" sub_menu_lvl=1 entry1='Backup followings' entry2='Backup blocks' entry3='Backup mutes' entry4='Backup all' entry5='Restore followings' entry6='Restore blocks' entry7='Restore mutes' entry8='Restore all' while [ $sub_menu_lvl -eq 1 ]; do choice=$(echo "Main menu\n$entry1\n$entry2\n$entry3\n$entry4\n$entry5\n$entry6\n$entry7\n$entry8" | fzy) case $choice in "Main menu") sub_menu_lvl=0 ;; "$entry1") follow_api_export ;; "$entry2") blocks_api_export ;; "$entry3") mutes_api_export ;; "$entry4") echo 'Initialized... Please wait...' follow_api_export sleep 3 blocks_api_export sleep 3 mutes_api_export ;; "$entry5") follow_api_import ;; "$entry6") blocks_api_import ;; "$entry7") mutes_api_import ;; "$entry8") echo 'Initialized... Please wait...' follow_api_import sleep 5 blocks_api_import sleep 5 mutes_api_import ;; esac done } backup_api_create() { post_request "$instance_point/pleroma/backups" } backup_api_list() { default_curl_opt "$instance_point/pleroma/backups" } legacy_addr_preprocess() { sed -E "/^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+$/! s/$/@$instance/" } follow_api_export() { count=40 mkdir -m 711 -p backups_"$instance" account_info=$(account_api_me) acc_id=$(echo "$account_info" | jj id) acc_following_count=$(echo "$account_info" | jj following_count) while [ $count -gt 0 ]; do followings=$(followings_api_get "$acc_id") count=$(echo "$followings" | jj \#) if [ "$count" -eq 0 ]; then echo "$acc_following_count followings exported" elif [ "$count" -lt 40 ]; then countindex=$(expr "$count" - 1) echo "$followings" | jj -l \#.acct | delq | legacy_addr_preprocess >> "backups_$instance"/friends.csv offset=$(echo "$followings" | jj "$countindex".id) echo "+$count follows" count=0 echo "$acc_following_count followings exported" elif [ $count -gt 0 ]; then countindex=$(expr $count - 1) echo "$followings" | jj -l \#.acct | delq | legacy_addr_preprocess >> "backups_$instance"/friends.csv offset=$(echo "$followings" | jj "$countindex".id) echo "+$count follows" fi sleep 1 done } blocks_api_export() { count=40 mkdir -m 711 -p "backups_$instance" while [ $count -gt 0 ]; do blocks=$(blocks_api_get) count=$(echo "$blocks" | jj \#) if [ "$count" -eq 0 ]; then echo "Blocks exported" elif [ "$count" -lt 40 ]; then countindex=$(expr "$count" - 1) echo "$blocks" | jj -l \#.acct | delq | legacy_addr_preprocess >> "backups_$instance"/blocks.csv offset=$(echo "$blocks" | jj "$countindex".id) echo "+$count blocks" count=0 echo "Blocks exported" elif [ $count -gt 0 ]; then echo "$blocks" | jj -l \#.acct | delq | legacy_addr_preprocess >> "backups_$instance"/blocks.csv offset=$(echo "$blocks" | jj "$countindex".id) echo "+$count blocks" fi sleep 1 done } mutes_api_export() { count=40 mkdir -m 711 -p "backups_$instance" while [ $count -gt 0 ]; do mutes=$(mutes_api_get) count=$(echo "$mutes" | jj \#) if [ "$count" -eq 0 ]; then echo "Mutes exported" elif [ "$count" -lt 40 ]; then countindex=$(expr "$count" - 1) echo "$mutes" | jj -l \#.acct | delq | legacy_addr_preprocess >> "backups_$instance"/mutes.csv offset=$(echo "$mutes" | jj "$countindex".id) echo "+$count mutes" count=0 echo "Mutes exported" elif [ $count -gt 0 ]; then echo "$mutes" | jj -l \#.acct | delq| legacy_addr_preprocess >> "backups_$instance"/mutes.csv offset=$(echo "$mutes" | jj "$countindex".id) echo "+$count mutes" fi sleep 1 done } follow_api_import() { post_request "$instance_point_pleroma/follow_import" \ --form 'list=@restore/friends.csv' } blocks_api_import() { post_request "$instance_point_pleroma/blocks_import" \ --form 'list=@restore/blocks.csv' } mutes_api_import() { post_request "$instance_point_pleroma/mutes_import" \ --form 'list=@restore/mutes.csv' } #[MIGRATION SECTION END] account_api_me() { default_curl_opt "$instance_point/accounts/verify_credentials" } me_acct=$(account_api_me | jj acct) followings_api_get() { default_curl_opt "$instance_point/accounts/$1/following?limit=40&max_id=$offset" } followings_menu() { account_info=$(account_api_me) acc_id=$(echo "$account_info" | jj id) acc_following_count=$(echo "$account_info" | jj following_count) echo "Followers: $acc_following_count" sub_menu_lvl=1 while [ $sub_menu_lvl -eq 1 ]; do followings=$(followings_api_get "$acc_id") accts=$(echo "$followings" | jj -l \#.acct | nl -s: -v0 -w1) choice=$(echo "Main menu\n$accts\nNext" | fzy) case $choice in "Main menu") sub_menu_lvl=0 ;; "Next") offset=$(echo "$followings" | jj $(expr $(echo "$followings" | jj \#) - 1).id) ;; *) index=$(echo "$choice" | cut -f 1 -d:) case "$1" in 'Remove following') unfollow_account "$(echo "$followings" | jj "$index".id)" ;; '') statuses_view_menu "$(echo "$followings" | jj "$index".acct)" ;; esac ;; esac done } following_requests() { default_curl_opt "$instance_point/follow_requests" } accept_follow_request() { post_request "$instance_point/follow_requests/$1/authorize" } reject_follow_request() { post_request "$instance_point/follow_requests/$1/reject" } follow_account() { acct_id=$(account_api_get "$1" | jj id) post_request "$instance_point/accounts/$acct_id/follow" } unfollow_account() { post_request "$instance_point/accounts/$1/unfollow" } menu_follow_requests() { follow_req=$(following_requests) count=$(echo "$follow_req" | jj \#) ids=$(echo "$follow_req" | jj -l \#.id | delq) clear echo "Follow requests: $count" for id in $ids; do whoacct=$(echo "$follow_req" | jj "#[id=$id].acct") datecreate=$(echo "$follow_req" | jj "#[id=$id].created_at") acct_display=$(echo "$follow_req" | jj "#[id=$id].display_name") acct_bot=$(echo "$follow_req" | jj "#[id=$id].bot") note=$(echo "$follow_req" | jj "#[id=$id].note" | html_to_txt_render) echo "$acct_display $whoacct" echo "Account creation date: $(date -d "$datecreate" "$format_time")" echo "Bot: $acct_bot" echo "Note:\n $note" nonexit=1 while [ "$nonexit" -eq 1 ]; do choice=$(echo 'Accept\nReject\nShow statuses\nNothing' | fzy) case "$choice" in "Accept") accept_follow_request "$id" && nonexit=0 ;; "Reject") reject_follow_request "$id" && nonexit=0 ;; "Show statuses") statuses_view_menu "$whoacct" ;; "Nothing") nonexit=0 ;; esac done clear done } blocks_api_get() { default_curl_opt "$instance_point/blocks?limit=40&max_id=$offset" } mutes_api_get() { default_curl_opt "$instance_point/mutes?limit=40&max_id=$offset" } thread_api_statuses() { default_curl_opt "$instance_point/statuses/$1/context" } html_to_txt_render() { sed -e "s/]*>/\n/g ; s/]*>/\n/g ; s/<[^>]*>//g ; s/>*/>/g ; s/<*/ attachments.m3u8 clear offset=$(echo "$json" | jj "$indexator".id) json=$(statuses_api_account "$1" "$offset") ;; "Next") echo '#EXTM3U' > attachments.m3u8 clear offset=$(echo "$json" | jj 0.id) json=$(statuses_api_account "$1" '' "$offset") ;; "Reverse") offset=1 json=$(statuses_api_account "$1" '' "$offset") ;; "Reply") reply_mode ;; "Share") share_mode ;; "Favorite") favourite_mode ;; "Share and favorite") share_and_favorite_mode ;; "Thread") thread_open ;; esac done } timeline_api() { timelines_params="limit=$max_statuses&max_id=$1&min_id=$2" case "$timeline" in "home") default_curl_opt "$instance_point/timelines/home?$timelines_params" ;; "home/local") default_curl_opt "$instance_point/timelines/home?local=true&$timelines_params" ;; "favourites") default_curl_opt "$instance_point/favourites?$timelines_params" ;; "bookmarks") default_curl_opt "$instance_point/bookmarks?$timelines_params" ;; "direct") default_curl_opt "$instance_point/timelines/direct?$timelines_params" ;; "public") default_curl_opt "$instance_point/timelines/public?$timelines_params" ;; "local") default_curl_opt "$instance_point/timelines/public?local=true&$timelines_params" ;; "search") echo "$results" ;; esac } search_api_statuses() { echo "Input query:" read query results=$(default_curl_opt --get \ --data-urlencode "q=$query" \ --data-urlencode 'type=statuses' \ --data-urlencode "limit=$max_statuses" \ "$instance_point/search" | jj 'statuses') timeline='search' timeline_menu } reply_mode() { if [ -n "$1" ]; then reply_status=$(status_api_one "$1") else echo 'Input id' read status_id reply_status=$(status_api_one "$status_id") fi if [ "$quoting_reply" = 'true' ]; then echo "$reply_status" | jj -r content | html_to_txt_render | delqse | sed 's/^/> /' > tmp_status.md fi if [ "$2" = '1' ]; then echo "$reply_status" | jj -r content | html_to_txt_render | delqse > tmp_status.md fi if [ "$copy_mentions" = 'true' ]; then mentions_reply=$(echo "$reply_status" | jj -l 'mentions.#.acct' | delq) mentions_reply="$mentions_reply\n" acct_selfstatus=$(echo "$reply_status" | jj account.acct) mentions_reply=$(echo "$mentions_reply""$acct_selfstatus" | sort -u | tr '\n' ',' | sed -e 's/,$//g; s/^,//g') fi write_status_menu "$(echo "$reply_status" | jj id)" } share_and_favorite_mode() { if [ -n "$1" ]; then share_api_status "$1" echo "$http_code" favorite_api_status "$1" echo "$http_code" else echo 'Input id (s - stop)' shareandfavmode=1 while [ $shareandfavmode -eq 1 ]; do read status_id if [ "$status_id" = 's' ]; then shareandfavmode=0 else share_api_status "$status_id" echo "$http_code" favorite_api_status "$status_id" echo "$http_code" fi done fi } share_api_status() { post_request -w "%{http_code}" --url "$instance_point/statuses/$1/reblog" --output /dev/null } share_mode() { echo 'Input id (s - stop)' sharemode=1 while [ $sharemode -eq 1 ]; do read status_id if [ "$status_id" = 's' ]; then sharemode=0 else share_api_status "$status_id" echo "$http_code" fi done } favorite_api_status() { post_request -w "%{http_code}" --url "$instance_point/statuses/$1/favourite" --output /dev/null } favourite_mode() { echo 'Input id (s - stop)' favoritemode=1 while [ $favoritemode -eq 1 ]; do read status_id if [ "$status_id" = 's' ]; then favoritemode=0 else favorite_api_status "$status_id" echo "$http_code" fi done } bookmark_api_status() { mkdir -p -m 711 bookmarks/"$instance" post_request "$instance_point/statuses/$1/bookmark" | jj -p -o "bookmarks/$instance/$1" chmod 600 "bookmarks/$instance/$1" } delete_api_status() { remove_status=$(delete_request "$instance_point/statuses/$1" | jj id) if [ -n "$remove_status" ]; then echo "SUCCESS" sleep 1 else echo "Failed" fi } write_api_status() { if [ -n "$mediaattach" ]; then media=$mediaattach post_request --url "$instance_point"/statuses \ --data-urlencode "status@$1" \ --data-raw "content_type=$content_type" \ --data-raw "visibility=$status_visibility" \ --data-raw "in_reply_to_id=$replyto" \ --data-raw "media_ids[]=$media" \ --data-raw "to[]=$mentions_reply" else post_request --url "$instance_point"/statuses \ --data-urlencode "status@$1" \ --data-raw "content_type=$content_type" \ --data-raw "visibility=$status_visibility" \ --data-raw "in_reply_to_id=$replyto" \ --data-raw "to[]=$mentions_reply" fi } edit_api_status() { put_request --url "$instance_point"/statuses/$1 \ --data-urlencode "status@$2" } upload_api_media() { post_request --url "$instance_point"/media \ --form "file=$1" } write_status_menu() { touch tmp_status.md content_type="$default_content_type" status_visibility="$default_visibility" replyto=$1 mediaattach= status_data_send= if [ -n "$sub_menu_lvl" ]; then sub_menu_lvl=2 level=2 else sub_menu_lvl=1 level=1 fi while [ $sub_menu_lvl -eq $level ]; do clear echo 'Status:' cat tmp_status.md echo '\==========/' echo "Chars: $(cat tmp_status.md | wc -m)" echo "Visiblity: $status_visibility" echo "Content type: $content_type" if [ -n "$mentions_reply" ]; then echo "Mentions: $mentions_reply" fi if [ -n "$replyto" ]; then echo "Reply to: $replyto" fi if [ -n "$mediaattach" ]; then echo "Attachments: $mediaattach" fi if [ -n "$(echo "$status_data_send" | jj id)" ]; then echo 'Send state: OK' elif [ -n "$(echo "$status_data_send" | jj error)" ]; then echo "Send state: ERR: $(echo "$status_data_send" | jj error)" fi wrirepostmenu=$(echo "Edit\nSend\nSend-edited\nAdd attach\nAdd recipient\nChange type\nVisiblity\nReset\nBack\nMain menu" | fzy) case $wrirepostmenu in "Edit") $EDITOR tmp_status.md ;; "Send") status_data_send=$(write_api_status tmp_status.md) ;; "Send-edited") status_data_send=$(edit_api_status $replyto tmp_status.md) ;; "Add attach") echo 'Input path to attach (ex. @image.png or @/full/path/to/attach.png)' read mediaattach ;; "Add recipient") echo 'Input addr (ex. nick,nick_etc@domain.domain)' read mentions_reply ;; "Change type") content_type=$(echo 'text/plain\ntext/markdown\ntext/html' | fzy) ;; "Visiblity") status_visibility=$(echo 'public\nunlisted\nlocal\nprivate\ndirect\nlist' | fzy) ;; "Reset") echo > tmp_status.md mentions_reply= ;; "Back") sub_menu_lvl=$(expr $level - 1) ;; "Main menu") sub_menu_lvl=0 ;; esac done } notif_menu() { sub_menu_lvl=1 clrnotif='Clear all notifications' json=$(notif_api_get_all) while [ $sub_menu_lvl -eq 1 ]; do clear count_new_notif=$(echo "$json" | jj -l '#[pleroma.is_seen=false]#.pleroma.is_seen' | wc -w) echo "New notifications: $count_new_notif" for i in $(echo "$json" | jj -l \#.id); do date_utc=$(echo "$json" | jj \#[id="$i"].created_at) date -d "$date_utc" "$format_time" acct=$(echo "$json" | jj \#[id="$i"].account.acct) status_id=$(echo "$json" | jj \#[id="$i"].status.id) typenotif=$(echo "$json" | jj \#[id="$i"].type) echo "<$status_id> $typenotif <- $acct" echo "$json" | jj -r \#[id="$i"].status.content | delqse | html_to_txt_render echo '___' done menu_choice=$(echo "Main menu\nRead\nRefresh\n$clrnotif" | fzy) case "$menu_choice" in "Main menu") sub_menu_lvl=0 ;; "Read") notif_api_read "$(echo "$json" | jj 0.id)" json=$(notif_api_get_all) ;; "Refresh") json=$(notif_api_get_all) ;; "$clrnotif") notif_api_remove_all && json=$(notif_api_get_all) ;; esac done } notif_api_get_all() { default_curl_opt "$instance_point/notifications?limit=$max_statuses" | jj -p } notif_api_read() { post_request --url "$instance_point/pleroma/notifications/read" \ --data-urlencode "max_id=$1" \ --output /dev/null } notif_api_remove_all() { post_request --url "$instance_point"/notifications/clear } custom_manual_api_request() { while true; do echo 'Select request method:' method=$(echo 'get\npost\nput' | fzy) echo 'Input api request: api/v1/...' case $method in 'get') read raw_api default_curl_opt "https://$instance/$raw_api" | jj -p ;; 'post') read raw_api echo 'input curl data flags: --data-urlencode "example=example"' read flags post_request $flags --url "https://$instance/$raw_api" | jj -p ;; 'put') read raw_api echo 'input curl data flags: --data-urlencode "example=example"' read flags put_request $flags --url "https://$instance/$raw_api" | jj -p ;; esac echo "Done, exit? (y/N)" read yn if [ "$yn" = 'y' ]; then break fi done } statuses_auto_update() { while true; do echo "Updating statuses..." for i in home local; do echo "checking timeline $i" timeline="$i" export instance timeline timeline_api | ./utils/statuses2files.sh sleep 3 done echo "Sleeping..." ./utils/statuses_archiver.sh sleep 30 done } if [ "$daemon_mode" = 'yes' ]; then echo "Daemon mode started; files listening..." statuses_auto_update & while true; do sleep 5 for file_func in favourite share reply; do statuses_file_action=$(/bin/ls $main_basedir/all_statuses/$instance/*/$file_func 2>/dev/null) if [ -n "$statuses_file_action" ]; then dir_status=$(dirname "$statuses_file_action") if [ -f "$dir_status/reblog.id" ]; then status_id=$(cat $dir_status/reblog.id) else status_id=$(echo $dir_status | sed 's/.*\///g') fi case $file_func in 'favourite') favorite_api_status "$status_id" ; rm "$statuses_file_action" ;; 'share') share_api_status $status_id ; rm "$statuses_file_action" ;; 'reply') replyto=$status_id if [ -d "$dir_status/attachments" ]; then attach_id='' echo "Uploading attachments..." for attach in "$dir_status"/attachments/*; do attach_id=$(upload_api_media "@$attach" | jj id) attach_id="${attach_id}," echo $attach_id done mediaattach=$(echo $attach_id | sed 's/,$//g') echo $mediaattach fi write_api_status $dir_status/message rm "$statuses_file_action" ;; esac fi write_status_action=$(/bin/ls $main_basedir/all_statuses/$instance/create 2>/dev/null) if [ -n "$write_status_action" ]; then dir_write_status=$(dirname "$write_status_action") if [ -d "$dir_write_status/attachments" ]; then attach_id='' echo "Uploading attachments..." for attach in "$dir_write_status"/attachments/*; do attach_id=$(upload_api_media "@$attach" | jj id) attach_id="${attach_id}," echo $attach_id done mediaattach=$(echo $attach_id | sed 's/,$//g') echo $mediaattach fi write_api_status $dir_write_status/message rm $write_status_action fi done done fi menu_write_status='Write status' menu_timeline='Timelines' notif='Notifications' my_account='Account' followingsmenu='Followings' followrequests='Follow requests' backup_restore='Backup/Restore' manage_followings='Manage followings' search_menu='Search' custom_request='Make custom api request' authmake='Auth' switchinstance='Switch instance' Exit='Exit' while true; do if [ -n "$auth" ]; then main_menu=$(echo "$menu_write_status\n$menu_timeline\n$notif\n$my_account\n$search_menu\n$custom_request\n$switchinstance\n$Exit" | fzy) else main_menu=$(echo "$authmake\n$menu_timeline\n$switchinstance\n$Exit" | fzy) fi case $main_menu in "$menu_write_status") write_status_menu ;; "$menu_timeline") timeline=$(echo 'home\nhome/local\nfavourites\nbookmarks\ndirect\nlocal\npublic' | fzy) timeline_menu ;; "$notif") notif_menu ;; "$my_account") my_account_menu=$(echo "$followingsmenu\n$followrequests\n$manage_followings\n$backup_restore" | fzy) case $my_account_menu in "$followingsmenu") followings_menu ;; "$followrequests") menu_follow_requests ;; "$manage_followings") action_manage=$(echo 'Add following\nRemove following' | fzy) if [ "$action_manage" = 'Add following' ]; then echo 'Input nick or full address (ex. example_nick or example@domain' read add_account follow_account "$add_account" else followings_menu "$action_manage" fi ;; "$backup_restore") backup_restore_menu ;; esac ;; "$search_menu") search_api_statuses ;; "$custom_request") custom_manual_api_request ;; "$switchinstance") empty=0 case $(echo 'Recently used\nChoice from list\nManual input' | fzy) in "Recently used") if [ -s $instance_hist ]; then touch $instance_hist && instance=$(cat $instance_hist | fzy) else echo 'No recently used instances...' empty=1 fi ;; "Choice from list") instance=$(jj -l -i config.json public_list_instances | sed 's/"//g' | fzy) ;; "Manual input") echo "Type instance (ex. $instance):" && read instance ;; esac if [ $empty -eq 0 ]; then echo "$instance" >> $instance_hist cat $instance_hist | sort | uniq | tee $instance_hist 1>>/dev/null proxy_init instance_point="$default_connect_protocol://$instance/api/v1" instance_point_pleroma="$default_connect_protocol://$instance/api/pleroma" conf_instance_state=$(echo 'Permanent\nTemporaly' | fzy) if [ "$conf_instance_state" = 'Permanent' ]; then jj -i config.json instance -v "$instance" -o config.json else echo '' fi clear make_login fi ;; "$authmake") auth_api_get_token ;; "$Exit") exit 0 ;; esac done