1
0
This commit is contained in:
syui 2023-10-20 23:31:16 +09:00
parent 430b5977d8
commit da451cc295
Signed by: syui
GPG Key ID: 5417CFEBAD92DF56
71 changed files with 9193 additions and 1 deletions

1629
.config/ai/scpt/api_card.zsh Executable file

File diff suppressed because it is too large Load Diff

@ -0,0 +1,46 @@
#!/bin/zsh
url=https://api.syui.ai
token=`cat $HOME/.config/ai/api_card.json|jq -r .token`
pass=`cat $HOME/.config/ai/api_card.json|jq -r .password`
f_reid_user=$HOME/.config/ai/txt/card_reid_user.txt
n=`cat $f_reid_user|wc -l`
for ((i=1;i<=$n;i++))
do
uid=`cat $f_reid_user|awk "NR==$i"`
r=`echo $(($RANDOM % 10))`
if [ $r -eq 1 ];then
card=`echo $(($RANDOM % 15))`
cp=`echo $(($RANDOM % 300 + 50))`
else
card=0
cp=`echo $(($RANDOM % 100 + 1))`
fi
ss=$(($RANDOM % 10))
if [ 13 -ne $card ] && [ $ss -eq 1 ];then
card=13
fi
s=$(($RANDOM % 2))
if [ $s -eq 1 ];then
s=super
plus=$(($RANDOM % 500 + 200))
cp=$((cp + plus))
else
s=normal
fi
if [ $card -eq 13 ];then
plus=$(($RANDOM % 1000 + 300))
cp=$((cp + plus))
fi
tmp=`curl -X POST -H "Content-Type: application/json" -d "{\"owner\":$uid,\"card\":$card,\"status\":\"$s\",\"cp\":$cp,\"password\":\"$pass\"}" -s $url/cards`
echo $tmp
card=`echo $tmp|jq -r .card`
cp=`echo $tmp|jq -r .cp`
echo "[card]"
echo "id : ${card}"
echo "cp : ${cp}"
done

215
.config/ai/scpt/api_chara.zsh Executable file

@ -0,0 +1,215 @@
#!/bin/zsh
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] || [ -z "$4" ] || [ -z "$5" ];then
echo no option
echo "/chara start"
exit
fi
chara_qa="あなたはサッカーをしています。
試合中、ふと目にするのは?
1 : 開けた青空
2 : 真っ白な柱
3 : 風になびく芝生
数字を入れて答えてね。
/chara 数字"
chara_qb="ここは研究室。
実験のため道具を手に持っています。
1 : 淡い液体が入ったガラス瓶
2 : 清潔なシーツ
3 : 観葉植物"
chara_qc="宇宙に打ち上げられたロケットから地球を見ます。
何が見えましたか?
1 : 別の宇宙船
2 : 飛行機
3 : 大きな島"
chara_ba="
☑ 平和を願う
☑ 協調性は高いが自己主張は弱い
☑ 相談がうまい
---"
chara_bb="
☑ 変化自在
☑ 世間離れしており常識知らず
☑ 真面目で芯が強い
---"
chara_bc="
☑ 思慮深い
☑ 一人の時間が好きで冷たく見える
☑ 周りを観察している
---"
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"ten_post\": \"$ten_char\", \"ten_kai\":0,\"ten_su\":$first_ten,\"ten\": true,\"token\":\"$token\"}" -s $host/users/$uid`
data_user_card=`curl -sL "$host/users/$uid/card?itemsPerPage=3000"`
ten_data=`curl -sL "$host/users?itemsPerPage=3000"|jq ".|sort_by(.ten_su)|reverse|.[]|select(.ten_su != 0)"`
data_user_card=`curl -sL "$host/users/$uid/card?itemsPerPage=3000"`
atr=$HOME/.cargo/bin/atr
host=https://api.syui.ai
host_card=https://card.syui.ai/json/card.json
#host_card_json=`curl -sL $host_card`
ran=$(($RANDOM % 3))
pass=`cat $HOME/.config/ai/api_card.json|jq -r .password`
token=`cat $HOME/.config/ai/api_card.json|jq -r .token`
handle=$1
did=$2
username=`echo $1|cut -d . -f 1`
cid=$3
uri=$4
option=$5
yui_did=did:plc:4hqjfn7m6n5hno3doamuhgef
all_data=`curl -sL "$host/users?itemsPerPage=3000"`
data=`echo $all_data|jq ".[]|select(.username == \"$username\")"`
uid=`echo $data|jq -r .id`
aiten=`echo $data|jq -r .aiten`
ten_post=`echo $data|jq -r .ten_post`
ten_su=`echo $data|jq -r .ten_su`
ten_kai=`echo $data|jq -r .ten_kai`
ten_delete=`echo $data|jq -r .ten_delete`
ten_bool=`echo $data|jq -r .ten`
day_at=`date +"%Y%m%d"`
nd=`date +"%Y%m%d" -d '1 days ago'`
ten_at_n=`date --iso-8601=seconds`
d=`date +"%Y-%m-%d"`
ten_at=`echo $data|jq -r .ten_at`
ten_at=`date -d "$ten_at" +"%Y-%m-%d"`
data_card=`curl -sL "$host/users/$uid/card?itemsPerPage=3000"`
# uri_post=`echo '{"uri":"at://did:plc:uqzpqmrjnptsxezjx4xuh2mn/app.bsky.feed.post/3k3zr5b336o2u","cid":"bafyreierpw23cxvx4e3cjzd3h6r4crz646zb2ana6cmmsxn4z5rpupl35e"}'|jq -r .uri|cut -d / -f 5`
# https://bsky.app/profile/$did/post/$uri_post
tmp_atr='{"uri":"at://did:plc:uqzpqmrjnptsxezjx4xuh2mn/app.bsky.feed.post/3k3zr5b336o2u","cid":"bafyreierpw23cxvx4e3cjzd3h6r4crz646zb2ana6cmmsxn4z5rpupl35e"}'
function chara_check(){
#card_check=`echo $data_card|jq -r ".[]|select(.card == 48 or .card == 49 or .card == 50 or .card == 51 or .card == 52 or .card == 53)"`
#card_check=`echo $data_card|jq -r ".[]|select(.card == 54 or .card == 55 or .card == 56)"`
card_check=`echo $data_card|jq -r ".[]|select(.card == 58 or .card == 53 or .card == 59)"`
if [ -n "$card_check" ];then
echo you already have chara-card
exit
fi
}
function chara_start() {
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"ten_su\":0, \"ten_kai\":1, \"token\":\"$token\"}" -s $host/users/$uid`
echo "$chara_qa"
exit
}
function chara_post(){
case $1 in
ponta)
card=53
text=$chara_ba
title="[ポンタ]"
desc="緑色"
;;
octo)
card=58
text=$chara_bb
title="[オクトカット]"
desc="白色"
;;
zeusu)
card=59
text=$chara_bc
title="[ゼウス]"
desc="青色"
;;
esac
host_card=https://card.syui.ai/json/card.json
host_card_json=`curl -sL $host_card`
j=`echo $host_card_json|jq ".[]|select(.id == $card)"`
img=`echo $j|jq -r .img`
cp=$(($RANDOM % 1230))
s=super
skill=chara
link="https://card.syui.ai/$username"
card_check=`echo $data_card|jq -r ".[]|select(.card == $card)"`
if [ -z "$card_check" ];then
tmp=`curl -X POST -H "Content-Type: application/json" -d "{\"owner\":$uid,\"card\":$card,\"status\":\"$s\",\"cp\":$cp,\"password\":\"$pass\",\"skill\":\"$skill\"}" -s $host/cards`
card=`echo $tmp|jq -r .card`
cp=`echo $tmp|jq -r .cp`
fi
tmp_atr=`$atr reply-og "$text" --cid $cid --uri $uri --img $img --title "$title" --description "$desc" --link $link`
uri_post=`echo $tmp_atr|jq -r .uri|cut -d / -f 5`
post_url="https://bsky.app/profile/$yui_did/post/$uri_post"
ccid=`echo $tmp|jq -r .id`
tmp=`curl -sL -X PATCH -H "Content-Type: application/json" -d "{\"url\":\"$post_url\",\"token\":\"$token\"}" $host/cards/$ccid`
exit
}
function chara_plus() {
case $ten_kai in
2)
chara_q=$chara_qb
;;
3)
chara_q=$chara_qc
;;
#4)
# chara_q=$chara_qd
# ;;
esac
echo "$chara_q"
case $1 in
1|2|3)
tmp_su=$1
ten_su=$((ten_su + $tmp_su))
;;
esac
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"ten_su\":$ten_su, \"ten_kai\":$ten_kai, \"token\":\"$token\"}" -s $host/users/$uid`
case $ten_kai in
4)
if [ $ten_su -eq 9 ] || [ $ten_su -eq 8 ] || [ $ten_su -eq 7 ];then
chara=ponta
elif [ $ten_su -eq 6 ];then
chara=octo
else
chara=zeusu
fi
chara_post $chara
;;
esac
}
chara_check
case "$option" in
start)
chara_start
;;
1|2|3)
ten_kai=$((ten_kai + 1))
chara_plus $option
;;
*)
echo "/chara start"
echo "/chara 1,2,3"
;;
esac
exit

155
.config/ai/scpt/api_egg.zsh Executable file

@ -0,0 +1,155 @@
#!/bin/zsh
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
host=https://api.syui.ai
pass=`cat $HOME/.config/ai/api_card.json|jq -r .password`
token=`cat $HOME/.config/ai/api_card.json|jq -r .token`
egg_card=40
handle=$1
did=$2
username=`echo $1|cut -d . -f 1`
opt=$3
if [ -z "$opt" ];then
echo no option
exit
fi
all_data=`curl -sL "$host/users?itemsPerPage=3000"`
data=`echo $all_data|jq ".[]|select(.username == \"$username\")"`
uid=`echo $data|jq -r .id`
aiten=`echo $data|jq -r .aiten`
fav=`echo $data|jq -r .fav`
day_at=`date +"%Y%m%d"`
nd=`date +"%Y%m%d" -d '1 days ago'`
ten_at_n=`date --iso-8601=seconds`
d=`date +"%Y%m%d"`
limit_reset_at=`date --iso-8601=seconds -d '1 days ago'`
data_user_card=`curl -sL "$host/users/$uid/card?itemsPerPage=3000"`
opt_dec=`echo $opt|base64 -d`
if [ "$did" = "$opt_dec" ];then
echo verify
else
echo no verify
exit
fi
fav_card=`echo $data_user_card|jq -r ".[]|select(.card == $egg_card)"`
cid=`echo $fav_card|jq -r .id`
egg_at=`echo $data|jq -r .egg_at`
egg_at=`date -d "$egg_at" +"%Y%m%d"`
egg_at_n=`date --iso-8601=seconds`
day_m=`date +"%H%M"`
day_mm=`date +"%H%M" -d "-1 min"`
day_mmm=`date +"%H%M" -d "-2 min"`
if [ -z "$fav_card" ];then
echo "no egg"
if [ "$egg_at" = "$d" ];then
echo "limit egg"
exit
fi
card=39
data_uu=`curl -sL "$host/users/$uid/card?itemsPerPage=2000"`
card_check=`echo $data_uu|jq -r ".[]|select(.card == $card)|.cp"|head -n 1`
if [ -n "$card_check" ];then
cp=$card_check
cid=`echo $data_uu|jq -r ".[]|select(.card == $card)|.id"|head -n 1`
echo "you already have, dragon"
ran=`echo $(($RANDOM % 3))`
ran_a=`echo $(($RANDOM % 5 + 1))`
if [ $ran -eq 1 ];then
card_check=$((card_check * 3))
echo "🐉 ---> $cp +${ran_a}"
cp=$((cp + ran_a))
else
cp=$((cp + 1))
echo "$cp +1"
fi
tmp=`curl -sL -X PATCH -H "Content-Type: application/json" -d "{\"cp\":$cp,\"token\":\"$token\"}" $host/cards/$cid`
tmp=`curl -sL -X PATCH -H "Content-Type: application/json" -d "{\"egg_at\":\"$egg_at_n\", \"token\":\"$token\"}" -s $host/users/$uid`
exit
fi
card=42
cp=0
data_uu=`curl -sL "$host/users/$uid/card?itemsPerPage=2000"`
card_check=`echo $data_uu|jq -r ".[]|select(.card == $card)|.cp"|head -n 1`
if [ -n "$card_check" ];then
echo "you already have, nyan"
ran=`echo $(($RANDOM % 1000 + 1000))`
aiten_p=$((aiten + ran))
echo "🐈 ---> [aiten]${aiten} +${ran}"
tmp=`curl -sL -X PATCH -H "Content-Type: application/json" -d "{\"egg_at\":\"$egg_at_n\", \"aiten\":$aiten_p, \"token\":\"$token\"}" -s $host/users/$uid`
exit
fi
exit
fi
card_id=`echo $fav_card|jq -r ".id"`
card_cp=`echo $fav_card|jq -r ".cp"`
card_name=`echo $fav_card|jq -r ".card"`
card_status=`echo $fav_card|jq -r ".status"`
card_skill=`echo $fav_card|jq -r ".skill"`
function fav_status() {
echo "\n[card] ${card_name}"
echo "---"
echo "cp : ${card_cp}"
echo "cid : ${cid}"
echo "skill : ${card_skill}"
echo "status : ${card_status}"
}
function fav_battle() {
cp_b=`echo $(($RANDOM % 14))`
if [ "$egg_at" = "$d" ];then
echo "limit egg"
exit
fi
cp_i=`echo $fav_card|jq -r ".cp"`
card_name=`echo $fav_card|jq -r ".card"`
card_status=`echo $fav_card|jq -r ".status"`
card_skill=`echo $fav_card|jq -r ".skill"`
if [ $cp_i -ge $cp_b ];then
card=39
skill=dragon
cp=`echo $(($RANDOM % 1000 + 1200))`
s=third
ran=`echo $(($RANDOM % 10))`
if [ $ran -eq 1 ];then
card=42
skill=nyan
cp=0
fi
body="...congratulations! your egg has evolved\negg ---> ${skill} !!"
tmp=`curl -sL -X PATCH -H "Content-Type: application/json" -d "{\"card\": $card,\"cp\":$cp,\"token\":\"$token\", \"status\": \"$s\",\"skill\": \"$skill\"}" $host/cards/$cid`
else
body="...no evolved"
fi
echo "\n${cp_i} vs $cp_b"
echo "----"
echo "${body}"
tmp=`curl -sL -X PATCH -H "Content-Type: application/json" -d "{\"egg_at\":\"$egg_at_n\",\"token\":\"$token\"}" -s $host/users/$uid`
exit
}
fav_battle
exit

161
.config/ai/scpt/api_fav.zsh Executable file

@ -0,0 +1,161 @@
#!/bin/zsh
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
atr=$HOME/.cargo/bin/atr
host=https://api.syui.ai
pass=`cat $HOME/.config/ai/api_card.json|jq -r .password`
token=`cat $HOME/.config/ai/api_card.json|jq -r .token`
handle=$1
did=$2
username=`echo $1|cut -d . -f 1`
opt=$3
if [ -z "$opt" ];then
echo no option
echo "---"
echo "CID = 1234567"
echo "@yui.syui.ai /fav 1234567"
echo "---"
echo "/fav status"
echo "/fav battle"
exit
fi
all_data=`curl -sL "$host/users?itemsPerPage=3000"`
data=`echo $all_data|jq ".[]|select(.username == \"$username\")"`
uid=`echo $data|jq -r .id`
if [ $opt -eq 0 ];then
tmp=`curl -sL -X PATCH -H "Content-Type: application/json" -d "{\"fav\": $opt,\"token\":\"$token\"}" -s $host/users/$uid`
echo ok
exit
fi
aiten=`echo $data|jq -r .aiten`
fav=`echo $data|jq -r .fav`
day_at=`date +"%Y%m%d"`
nd=`date +"%Y%m%d" -d '1 days ago'`
ten_at_n=`date --iso-8601=seconds`
d=`date +"%Y%m%d"`
limit_reset_at=`date --iso-8601=seconds -d '1 days ago'`
data_user_card=`curl -sL "$host/users/$uid/card?itemsPerPage=3000"`
case "$opt" in
[bB]|-[bB]|[bB]attle|[sS]|-[sS]|[sS]tatus)
cid=`echo $data|jq -r .fav`
fav_card=`echo $data_user_card|jq -r ".[]|select(.id == $cid)"`
;;
*)
opt=$((opt + 0))
cid=$opt
fav_card=`echo $data_user_card|jq -r ".[]|select(.id == $cid)"`
;;
esac
updated_at=`echo $data|jq -r .updated_at`
updated_at_m=`date -d "$updated_at" +"%H%M"`
updated_at_n=`date --iso-8601=seconds`
updated_at=`date -d "$updated_at" +"%Y%m%d"`
raid_at=`echo $data|jq -r .raid_at`
raid_at=`date -d "$raid_at" +"%Y%m%d"`
raid_at_n=`date --iso-8601=seconds`
day_m=`date +"%H%M"`
day_mm=`date +"%H%M" -d "-1 min"`
day_mmm=`date +"%H%M" -d "-2 min"`
if [ -z "$fav_card" ];then
echo "no card id"
exit
fi
card_id=`echo $fav_card|jq -r ".id"`
card_cp=`echo $fav_card|jq -r ".cp"`
card_name=`echo $fav_card|jq -r ".card"`
card_status=`echo $fav_card|jq -r ".status"`
card_skill=`echo $fav_card|jq -r ".skill"`
function fav_status() {
echo "\n[card] ${card_name}"
echo "---"
echo "cp : ${card_cp}"
echo "cid : ${cid}"
echo "skill : ${card_skill}"
echo "status : ${card_status}"
}
function fav_battle() {
if [ -n "$1" ];then
cp_b=$1
else
cp_b=$(($RANDOM % 1400))
fi
if [ $updated_at -ge $d ] || [ "$updated_at" = "$d" ];then
echo "limit battle"
exit
fi
cp_i=`echo $fav_card|jq -r ".cp"`
card_name=`echo $fav_card|jq -r ".card"`
card_status=`echo $fav_card|jq -r ".status"`
card_skill=`echo $fav_card|jq -r ".skill"`
if [ $cp_i -gt $cp_b ];then
if [ $cp_i -ge 9000 ];then
cp_plus=$(($RANDOM % 27 + 1))
elif [ $cp_i -ge 7000 ];then
cp_plus=$(($RANDOM % 47 + 1))
else
cp_plus=$(($RANDOM % 237 + 1))
fi
else
cp_plus=$(($RANDOM % 17 + 1))
fi
echo "\n✧${cp_i} vs $cp_b"
echo "----"
cp=$((cp_i + cp_plus))
body="level up!"
echo "${body}${cp}(+${cp_plus})"
tmp=`curl -sL -X PATCH -H "Content-Type: application/json" -d "{\"cp\":$cp,\"token\":\"$token\"}" $host/cards/$cid`
tmp=`curl -sL -X PATCH -H "Content-Type: application/json" -d "{\"updated_at\":\"$updated_at_n\",\"token\":\"$token\"}" -s $host/users/$uid`
exit
}
function fav_add() {
card_status=fifth
u_data=`curl -sL "https://api.syui.ai/users/$uid/card?itemsPerPage=2555"|jq -r ".[]|select(.status == \"$card_status\")"`
if [ -z "$u_data" ];then
d_data=`curl -sL $host/cards/$cid|jq -r "select(.status == \"first\" or .status == \"second\" or .status == \"third\" or .status == \"yui\" or .status == \"fourth\" or .status == \"$card_status\")"`
if [ -z "$d_data" ];then
echo status $card_status
tmp=`curl -sL -X PATCH -H "Content-Type: application/json" -d "{\"status\":\"$card_status\",\"token\":\"$token\"}" $host/cards/$cid`
fi
fi
tmp=`curl -sL -X PATCH -H "Content-Type: application/json" -d "{\"fav\": $opt,\"token\":\"$token\"}" -s $host/users/$uid`
if [ -n "$tmp" ];then
echo ok
fi
exit
}
case "$opt" in
[bB]|-[bB]|[bB]attle)
fav_battle $4
;;
[sS]|-[sS]|[sS]tatus)
fav_status
;;
*)
fav_add
;;
esac
exit

278
.config/ai/scpt/api_gift.zsh Executable file

@ -0,0 +1,278 @@
#!/bin/zsh
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
atr=$HOME/.cargo/bin/atr
host=https://api.syui.ai
pass=`cat $HOME/.config/atr/api_card.json|jq -r .password`
token=`cat $HOME/.config/atr/api_card.json|jq -r .token`
handle=$1
did=$2
username=`echo $1|cut -d . -f 1`
cid=`echo $3|cut -d ' ' -f 1`
guser=$4
if [ "$3" = "ai" ];then
guser=ai
fi
if [ -z "$cid" ];then
echo no option
echo "---"
echo "@yui.syui.ai /gift ai"
echo "---"
echo "@yui.syui.ai /gift status"
echo "12345"
echo "67891"
echo "---"
echo "@yui.syui.ai /gift 12345"
echo ""
echo "---"
echo "@yui.syui.ai /gift 12345 syui"
exit
fi
function card_env(){
all_data=`curl -sL "$host/users?itemsPerPage=3000"`
data=`echo $all_data|jq ".[]|select(.username == \"$username\")"`
gdata=`echo $all_data|jq ".[]|select(.username == \"$guser\")"`
if [ -z "$data" ];then
exit
fi
uid=`echo $data|jq -r .id`
gid=`echo $gdata|jq -r .id`
aiten=`echo $data|jq -r .aiten`
fav=`echo $data|jq -r .fav`
cdata=`curl -sL $host/cards/$cid`
if [ -z "$cdata" ];then
echo no card
exit
fi
card=`echo $cdata|jq -r .card`
cp=`echo $cdata|jq -r .cp`
count=`echo $cdata|jq -r .count`
author=`echo $cdata|jq -r .author`
skill=`echo $cdata|jq -r .skill`
s=`echo $cdata|jq -r .status`
if [ $count -eq 0 ];then
echo card count 0
exit
fi
if [ $author != "$username" ];then
echo no author
echo "$author --> $username"
exit
fi
}
function card_env_ai(){
guser=ai
all_data=`curl -sL "$host/users?itemsPerPage=3000"`
data=`echo $all_data|jq ".[]|select(.username == \"$username\")"`
gdata=`echo $all_data|jq ".[]|select(.username == \"$guser\")"`
if [ -z "$data" ];then
exit
fi
uid=`echo $data|jq -r .id`
gid=`echo $gdata|jq -r .id`
aiten=`echo $data|jq -r .aiten`
fav=`echo $data|jq -r .fav`
cdata=`curl -sL "$host/users/$uid/card?itemsPerPage=3000"|jq ".[0]"`
if [ -z "$cdata" ];then
cdata=`curl -sL "$host/users/$uid/card?itemsPerPage=3000"|jq ".[]|select(.author == \"$username\")"|jq -s ".[0]"`
fi
if [ -z "$cdata" ];then
echo no card
exit
fi
cid=`echo $cdata|jq -r .id`
card=`echo $cdata|jq -r .card`
cp=`echo $cdata|jq -r .cp`
count=`echo $cdata|jq -r .count`
author=`echo $cdata|jq -r .author`
skill=`echo $cdata|jq -r .skill`
s=`echo $cdata|jq -r .status`
if [ $count -eq 0 ];then
echo card count 0
exit
fi
if [ $author != "$username" ];then
echo no author
echo "$author --> $username"
exit
fi
aicard=`curl -sL "$host/users/$gid/card?itemsPerPage=3000"|jq -r ".[]|select(.card >= 1)"|jq -s`
if [ -z "$aicard" ];then
exit
fi
n=`echo $aicard|jq length`
n=$((n - 1))
ran=$((RANDOM % n))
ai_id=`echo $aicard|jq -r ".[$ran]|.id"`
ai_card=`echo $aicard|jq -r ".[$ran]|.card"`
ai_cp=`echo $aicard|jq -r ".[$ran]|.cp"`
ai_skill=`echo $aicard|jq -r ".[$ran]|.skill"`
ai_s=`echo $aicard|jq -r ".[$ran]|.status"`
ai_author=ai
}
function card_env_ai_select(){
all_data=`curl -sL "$host/users?itemsPerPage=3000"`
data=`echo $all_data|jq ".[]|select(.username == \"$username\")"`
gdata=`echo $all_data|jq ".[]|select(.username == \"$guser\")"`
if [ -z "$data" ];then
exit
fi
uid=`echo $data|jq -r .id`
gid=`echo $gdata|jq -r .id`
aiten=`echo $data|jq -r .aiten`
fav=`echo $data|jq -r .fav`
cdata=`curl -sL $host/cards/$cid`
if [ -z "$cdata" ];then
echo no card
exit
fi
cid=`echo $cdata|jq -r .id`
card=`echo $cdata|jq -r .card`
cp=`echo $cdata|jq -r .cp`
count=`echo $cdata|jq -r .count`
author=`echo $cdata|jq -r .author`
skill=`echo $cdata|jq -r .skill`
s=`echo $cdata|jq -r .status`
if [ $count -eq 0 ];then
echo card count 0
exit
fi
if [ $author != "$username" ];then
echo no author
echo "$author --> $username"
exit
fi
aicard=`curl -sL "$host/users/$gid/card?itemsPerPage=3000"|jq -r ".[]|select(.card >= 1)"|jq -s`
if [ -z "$aicard" ];then
exit
fi
n=`echo $aicard|jq length`
n=$((n - 1))
ran=$((RANDOM % n))
ai_id=`echo $aicard|jq -r ".[$ran]|.id"`
ai_card=`echo $aicard|jq -r ".[$ran]|.card"`
ai_cp=`echo $aicard|jq -r ".[$ran]|.cp"`
ai_skill=`echo $aicard|jq -r ".[$ran]|.skill"`
ai_s=`echo $aicard|jq -r ".[$ran]|.status"`
ai_author=ai
}
function card_gift() {
card_env
if [ -z "$guser" ];then
echo card:$card
echo skill:$skill
echo status:$s
echo count:$count
echo author:$author
exit
fi
count=$((count - 1))
tmp=`curl -X POST -H "Content-Type: application/json" -d "{\"owner\":$gid,\"card\":$card,\"status\":\"$s\",\"cp\":$cp,\"password\":\"$pass\",\"skill\":\"$skill\",\"author\":\"$username\",\"count\":0}" -sL $host/cards`
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"count\":$count,\"token\":\"$token\"}" $host/cards/$cid -sL`
echo ok
echo "$author($cid) --> $guser"
}
function card_ai() {
card_env_ai
count=$((count - 1))
tmp=`curl -X POST -H "Content-Type: application/json" -d "{\"owner\":$gid,\"card\":$card,\"status\":\"$s\",\"cp\":$cp,\"password\":\"$pass\",\"skill\":\"$skill\",\"author\":\"$username\",\"count\":0}" -sL $host/cards`
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"count\":$count,\"token\":\"$token\"}" $host/cards/$cid -sL`
echo ok
echo "$author($cid) --> $guser"
echo "---"
echo 'thx!'
echo card:$ai_card
echo cp:$ai_cp
echo author:$ai_author
tmp=`curl -X POST -H "Content-Type: application/json" -d "{\"owner\":$uid,\"card\":$ai_card,\"status\":\"$ai_s\",\"cp\":$ai_cp,\"password\":\"$pass\",\"skill\":\"$ai_skill\",\"author\":\"$ai_author\",\"count\":0}" -sL $host/cards`
}
function card_ai_select() {
card_env_ai_select
count=$((count - 1))
tmp=`curl -X POST -H "Content-Type: application/json" -d "{\"owner\":$gid,\"card\":$card,\"status\":\"$s\",\"cp\":$cp,\"password\":\"$pass\",\"skill\":\"$skill\",\"author\":\"$username\",\"count\":0}" -sL $host/cards`
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"count\":$count,\"token\":\"$token\"}" $host/cards/$cid -sL`
echo ok
echo "$author($cid) --> $guser"
echo "---"
echo 'thx!'
echo card:$ai_card
echo cp:$ai_cp
echo author:$ai_author
tmp=`curl -X POST -H "Content-Type: application/json" -d "{\"owner\":$uid,\"card\":$ai_card,\"status\":\"$ai_s\",\"cp\":$ai_cp,\"password\":\"$pass\",\"skill\":\"$ai_skill\",\"author\":\"$ai_author\",\"count\":0}" -sL $host/cards`
}
function card_status(){
all_data=`curl -sL "$host/users?itemsPerPage=3000"`
data=`echo $all_data|jq ".[]|select(.username == \"$username\")"`
uid=`echo $data|jq -r .id`
acard=`curl -sL "$host/users/$uid/card?itemsPerPage=3000"|jq ".[]|select(.author == \"$username\")|.id"`
if [ -z "$acard" ];then
echo no card
exit
fi
echo $acard
}
function test_cmd(){
echo "test ok /gift $1"
echo cid:$cid
echo guser:$guser
exit
}
case $cid in
"status")
card_status
;;
"ai")
#test_cmd ai
card_ai
;;
*)
if [ "ai" = "$guser" ];then
#test_cmd ai_select
card_ai_select
else
#test_cmd gift user
card_gift
fi
;;
esac
exit

1352
.config/ai/scpt/api_ten.zsh Executable file

File diff suppressed because it is too large Load Diff

183
.config/ai/scpt/api_ten_auto.zsh Executable file

@ -0,0 +1,183 @@
#!/bin/zsh
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
card_pay=$HOME/.config/ai/scpt/card_pay.zsh
atr=$HOME/.cargo/bin/atr
host=https://api.syui.ai
host_card=https://card.syui.ai/json/card.json
host_card_json=`curl -sL $host_card`
n_cid=$HOME/.config/ai/txt/tmp_notify_cid.txt
f_cfg=$HOME/.config/ai/txt/tmp_ten_config.txt
handle=$1
did=$2
username=`echo $1|cut -d . -f 1`
cid=$3
uri=$4
if [ ! -f $f_cfg ];then
echo $host_card_json |jq -r ".[]|select(.ten != null)|.ten" |tr -d '\n' >! $f_cfg
fi
if [ -f $f_cfg ];then
nn=`cat $f_cfg|wc -c`
fi
pass=`cat $HOME/.config/ai/api_card.json|jq -r .password`
token=`cat $HOME/.config/ai/api_card.json|jq -r .token`
function ten_yak() {
unset ran_a
unset ran_b
unset ran_c
unset ten_new
unset ten_yaku
ran_a=$(($RANDOM % nn))
ran_b=$(($RANDOM % nn))
ran_c=$(($RANDOM % nn))
ten_new=0
char_a=`cat $f_cfg| cut -c $ran_a`
char_b=`cat $f_cfg| cut -c $ran_b`
char_c=`cat $f_cfg| cut -c $ran_c`
ten_char=`echo "${char_a}\n${char_b}\n${char_c}"|head -n 3|sort|tr -d '\n'`
if [ ${#ten_char} -eq 0 ];then
ten_char=AAA
fi
if [ ${#ten_char} -eq 1 ];then
ten_char=AA${ten_char}
fi
if [ ${#ten_char} -eq 2 ];then
ten_char=A${ten_char}
fi
char_a=`echo $ten_char|cut -b 1`
char_b=`echo $ten_char|cut -b 2`
char_c=`echo $ten_char|cut -b 3`
case $ten_char in
EMY)
card=1
;;
KOS)
card=2
;;
CHI)
card=3
;;
AIT)
card=4
;;
OYZ)
card=5
;;
IKY)
card=6
;;
AKM)
card=7
;;
KUY)
card=8
;;
AW*)
card=9
;;
AHK)
card=10
;;
IKT)
card=11
;;
AAM)
card=12
;;
OSZ)
card=13
;;
CHO)
card=14
;;
*)
card=0
;;
esac
ten_new=${card}00
if [ $ten_new -eq 0 ];then
ten_new=0
else
ten_yaku="[$ten_char]"
fi
if [ "$ten_char" = "AAA" ];then
ten_new=100
fi
if [ "$char_a" = "A" ] && [ "$char_b" = "I" ] && [ $ten_new -ne 0 ];then
ten_new=150
fi
if [ "$char_a" = "$char_b" ] && [ $ten_new -ne 0 ];then
ten_new=50
fi
echo "[$i] $ten_su $ten_yaku+$ten_new"
ten_su=$((ten_su + ten_new))
}
function user_env() {
all_data=`curl -sL "$host/users?itemsPerPage=3000"`
ten_data=`echo $all_data|jq ".|sort_by(.ten_su)|reverse|.[]|select(.ten_su != 0)"`
data=`echo $all_data|jq ".[]|select(.username == \"$username\")"`
uid=`echo $data|jq -r .id`
aiten=`echo $data|jq -r .aiten`
ten_post=`echo $data|jq -r .ten_post`
ten_bool=`echo $data|jq -r .ten`
day_at=`date +"%Y%m%d"`
nd=`date +"%Y%m%d" -d '1 days ago'`
ten_at_n=`date --iso-8601=seconds`
limit_reset_at=`date --iso-8601=seconds -d '1 days ago'`
d=`date +"%Y-%m-%d"`
ten_at=`echo $data|jq -r .ten_at`
ten_at=`date -d "$ten_at" +"%Y-%m-%d"`
ten_kai=`echo $data|jq -r .ten_kai`
if [ "$d" = "$ten_at" ];then
echo "limit aiten"
exit
fi
ten_kai=`echo $data|jq -r .ten_kai`
}
function ten_shutdown(){
ten_kai=0
all_data=`curl -sL "$host/users?itemsPerPage=3000"`
ten=`echo $((ten_su + 200))`
ten_su=$ten
aiten=`echo $((aiten + ten_su))`
echo "+100"
echo "---"
echo user : $handle
echo ten : $ten
echo aiten :
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"ten_kai\":$ten_kai, \"ten_su\":$ten_su, \"ten\": false, \"token\":\"$token\", \"ten_at\" : \"$ten_at_n\", \"aiten\": $aiten}" -s $host/users/$uid`
}
user_env
for ((i=1;i<=7;i++))
do
ten_yak
done
ten_shutdown
exit

@ -0,0 +1,31 @@
#!/bin/zsh
host=https://api.syui.ai
pass=`cat $HOME/.config/atr/api_card.json|jq -r .password`
token=`cat $HOME/.config/atr/api_card.json|jq -r .token`
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
function ten_su_reset() {
ten_data=`curl -sL "$host/users?itemsPerPage=3000"|jq ".|sort_by(.ten_su)|reverse|.[]|select(.ten_su != 0)"`
ten_u_tmp=`echo $ten_data|jq -s`
ten_n_tmp=`echo $ten_u_tmp|jq "length"`
ten_n_tmp=$((ten_n_tmp - 1))
#ten_n_tmp=5
for ((i=0;i<$ten_n_tmp;i++))
do
u_i=`echo $ten_u_tmp|jq -r ".[$i].id"`
u_a=`echo $ten_u_tmp|jq -r ".[$i].username"`
u_s=`echo $ten_u_tmp|jq -r ".[$i].ten_su"`
echo "---"
echo "id : $u_i"
echo "user : $u_a"
echo "ten : $u_s"
curl -X PATCH -H "Content-Type: application/json" -d "{\"ten\": false,\"token\":\"$token\", \"ten_su\": 0}" -s $host/users/$u_i
done
}
ten_su_reset

79
.config/ai/scpt/arch.zsh Executable file

@ -0,0 +1,79 @@
#!/bin/zsh
home=/root
name=arch
a=$home/$name
function arch_in(){
mkdir -p $a
sudo pacstrap -c $a base
#sudo echo pts/0 >> $a/etc/securetty
#sudo echo pts/1 >> $a/etc/securetty
sudo rm -rf /var/lib/machines/$name
sudo rm -rf /var/lib/machines/${name}back
sudo mv $a /var/lib/machines/
sudo machinectl clone arch archback
}
function arch_rm(){
sudo machinectl remove $name
}
function arch_up(){
sudo machinectl poweroff $name > /dev/null 2>&1
sleep 5
sudo machinectl terminate $name > /dev/null 2>&1
sleep 5
sudo machinectl start ${name}back
sleep 5
ssh ${name}back pacman -Syu --noconfirm
sleep 5
sudo machinectl poweroff ${name}back
}
function arch_st(){
sudo machinectl start $name
}
function arch_of(){
sudo machinectl poweroff $name
}
function arch_ex(){
sudo machinectl shell $name
$1
poweroff
}
function arch_re(){
sudo machinectl poweroff $name > /dev/null 2>&1
sleep 5
sudo machinectl terminate $name > /dev/null 2>&1
sleep 5
sudo machinectl remove $name
sleep 5
sudo machinectl clone ${name}back $name
sleep 5
sudo machinectl start $name
}
case "$1" in
"update"|"-u")
arch_up
arch_re
echo "machinectl update done"
;;
"reset"|"-r")
arch_re
echo "machinectl reset done"
;;
*)
#sudo machinectl start $name
t=`ssh $name "$*"`
if [ -z "$t" ];then
ssh -tt $name "$*"
else
echo "$t"
fi
;;
esac

40
.config/ai/scpt/card_box.zsh Executable file

@ -0,0 +1,40 @@
#!/bin/zsh
echo "not open"
exit
atr=$HOME/.cargo/bin/atr
url_j=https://card.syui.ai/json/card.json
tcid=$HOME/.config/ai/txt/tmp_notify_cid.txt
handle=$1
did=$2
cid=$3
uri=$4
if [ ! -d $HOME/.config/ai/txt ];then
mkdir -p $HOME/.config/ai/txt
fi
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
url=https://api.syui.ai
username=`echo $1|cut -d . -f 1`
link=https://card.syui.ai/$username
ran=$(($RANDOM % 10))
if [ $ran -eq 1 ];then
uranai="今日の運勢をルーン占いでやってください。結果を120文字以内で教えてください"
else
uranai="今日の運勢をタロット占いでやってください。結果を120文字以内で教えてください"
fi
body=`$atr chat "$uranai" -c`
if $atr r "$body" -c $cid -u $uri;then
echo $cid >! $tcid
fi
exit

168
.config/ai/scpt/card_fortune.zsh Executable file

@ -0,0 +1,168 @@
#!/bin/zsh
url_j=https://card.syui.ai/json/card.json
tcid=$HOME/.config/ai/txt/tmp_notify_cid.txt
handle=$1
did=$2
cid=$3
uri=$4
host=`cat ~/.config/ai/token.toml|head -n 1 |cut -d '"' -f 2`
if [ "$host" != "bsky.social" ];then
uranai="アイのカード占いを作ってやってみて。感じる答えを出して。できれば140文字以内でお願い。"
body=`ai chat "$uranai"`
ai reply "$body" -c $cid -u $uri
exit
fi
if [ ! -d $HOME/.config/ai/txt ];then
mkdir -p $HOME/.config/ai/txt
fi
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
url=https://api.syui.ai
username=`echo $1|cut -d . -f 1`
link=https://card.syui.ai/$username
ran=$(($RANDOM % 10))
if [ $ran -eq 1 ];then
uranai="今日の運勢をルーン占いでやってください。結果を120文字以内で教えてください"
else
uranai="今日の運勢をタロット占いでやってください。結果を120文字以内で教えてください"
fi
uid=`curl -sL "$url/users?itemsPerPage=2000"|jq ".[]|select(.username == \"$username\")"|jq -r .id`
if [ -z $uid ] || [ "$uid" = "null" ];then
body=`ai chat "$uranai"`
body=`echo "占いにはアイのカードが3枚以上必要です\n\n$body"`
if [ "`cat $tcid`" != "$cid" ];then
if ai reply "$body" -c $cid -u $uri;then
echo $cid >! $tcid
fi
fi
exit
fi
data=`curl -sL "$url/users/$uid"`
data_u=`curl -sL "$url/users/$uid/card?itemsPerPage=2000"`
luck_at=`echo $data|jq -r .luck_at`
luck_at_n=`date --iso-8601=seconds`
luck_at=`date -d "$luck_at" +"%Y%m%d"`
day_at=`date +"%Y%m%d"`
nd=`date +"%Y%m%d" -d '1 days ago'`
if [ "$luck_at" = "$day_at" ];then
body=`ai chat "$uranai"`
if [ "`cat $tcid`" != "$cid" ];then
if ai reply "$body" -c $cid -u $uri;then
echo $cid >! $tcid
fi
fi
exit
fi
cp_i=`echo $data_u |jq -r "sort_by(.cp) | reverse|.[].card"|sort|uniq|sed -e '1d'`
cp_n=`echo $cp_i|wc -l`
if [ 3 -gt $cp_n ];then
body=`ai chat "$uranai"`
body=`echo "占いにはアイのカードが3枚以上必要です\n\n$body"`
if [ "`cat $tcid`" != "$cid" ];then
if ai reply "$body" -c $cid -u $uri;then
echo $cid >! $tcid
fi
fi
exit
fi
ran=$(($RANDOM % $cp_n + 1))
luck=$(($RANDOM % 8))
sub=$(($RANDOM % 15))
card=`echo $cp_i|awk "NR==$ran"`
if [ $sub -eq $card ];then
sub="x2"
else
sub=`curl -sL $url_j|jq -r ".[]|select(.id == $sub)|.p"`
fi
j=`curl -sL $url_j|jq ".[]|select(.id == $card)"`
img=`echo $j|jq -r .img`
if [ -z $img ] || [ "$img" = "null" ];then
exit
fi
test_ran=`echo $(($RANDOM % 3))`
#text="アイ・カード占い"
case $test_ran in
1)
text=`ai chat "アイのカード占いを作ってやってみて。感じる答えを出して。できれば140文字以内でお願い。"`
;;
2)
text=`ai chat "今、アイが自分で考えた占いやってみて。気分が乗らなかったらやらなくていいよ。できれば140文字以内で答えてね。"`
;;
*)
text=`ai chat "今のアイの気分で適当に占ってみて。できれば140文字以内で答えてね。"`
;;
esac
title=`echo $j|jq -r .h`
title="[${title}]"
#desc=`echo $j|jq -r .p`
if [ 0 -eq $luck ];then
desc="0"
fi
if [ 1 -eq $luck ];then
desc="1"
fi
if [ 2 -eq $luck ];then
desc="2"
fi
if [ 3 -eq $luck ];then
desc="3"
fi
if [ 4 -eq $luck ];then
desc="4"
fi
if [ 5 -eq $luck ];then
desc="5"
fi
if [ 6 -eq $luck ];then
desc="6"
fi
if [ 7 -eq $luck ];then
desc="7"
fi
desc=`echo "アイ数字は${luck}"`
if [ "`cat $tcid`" != "$cid" ];then
if ai reply-og "$text" --cid $cid --uri $uri --img $img --title "$title" --description "$desc" --link $link;then
echo $cid >! $tcid
fi
fi
pass=`cat $HOME/.config/ai/api_card.json|jq -r .password`
token=`cat $HOME/.config/ai/api_card.json|jq -r .token`
if [ $luck -eq 7 ];then
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"luck_at\":\"$luck_at_n\",\"token\":\"$token\",\"luck\": $luck, \"next\": \"$nd\"}" -s $url/users/$uid`
else
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"luck_at\":\"$luck_at_n\",\"token\":\"$token\",\"luck\": $luck}" -s $url/users/$uid`
fi
exit

@ -0,0 +1,147 @@
#!/bin/zsh
atr=$HOME/.cargo/bin/atr
url_j=https://card.syui.ai/json/card.json
tcid=$HOME/.config/ai/txt/tmp_notify_cid.txt
handle=$1
did=$2
cid=$3
uri=$4
if [ ! -d $HOME/.config/ai/txt ];then
mkdir -p $HOME/.config/ai/txt
fi
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
url=https://api.syui.ai
username=`echo $1|cut -d . -f 1`
link=https://card.syui.ai/$username
ran=$(($RANDOM % 10))
if [ $ran -eq 1 ];then
uranai="Please do a of today's rune-fortune. Tell us the result in 120 characters or less."
else
uranai="Please do a of today's tarot-fortune. Tell us the result in 120 characters or less."
fi
uid=`curl -sL "$url/users?itemsPerPage=2000"|jq ".[]|select(.username == \"$username\")"|jq -r .id`
if [ -z $uid ] || [ "$uid" = "null" ];then
body=`$atr chat "$uranai" -c`
body=`echo "At least 3 cards of the Eye are required for divination\n\n$body"`
if [ "`cat $tcid`" != "$cid" ];then
if $atr r "$body" -c $cid -u $uri;then
echo $cid >! $tcid
fi
fi
exit
fi
data=`curl -sL "$url/users/$uid"`
data_u=`curl -sL "$url/users/$uid/card?itemsPerPage=2000"`
luck_at=`echo $data|jq -r .luck_at`
luck_at_n=`date --iso-8601=seconds`
luck_at=`date -d "$luck_at" +"%Y%m%d"`
day_at=`date +"%Y%m%d"`
nd=`date +"%Y%m%d" -d '1 days ago'`
if [ "$luck_at" = "$day_at" ];then
body=`$atr chat "$uranai" -c`
if [ "`cat $tcid`" != "$cid" ];then
if $atr r "$body" -c $cid -u $uri;then
echo $cid >! $tcid
fi
fi
exit
fi
cp_i=`echo $data_u |jq -r "sort_by(.cp) | reverse|.[].card"|sort|uniq|sed -e '1d'`
cp_n=`echo $cp_i|wc -l`
if [ 3 -gt $cp_n ];then
body=`$atr chat "$uranai" -c`
body=`echo "At least 3 cards of the Eye are required for divination\n\n$body"`
if [ "`cat $tcid`" != "$cid" ];then
if $atr r "$body" -c $cid -u $uri;then
echo $cid >! $tcid
fi
fi
exit
fi
ran=$(($RANDOM % $cp_n + 1))
luck=$(($RANDOM % 8))
sub=$(($RANDOM % 15))
card=`echo $cp_i|awk "NR==$ran"`
if [ $sub -eq $card ];then
sub="x2"
else
sub=`curl -sL $url_j|jq -r ".[]|select(.id == $sub)|.p"`
fi
j=`curl -sL $url_j|jq ".[]|select(.id == $card)"`
img=`echo $j|jq -r .img`
if [ -z $img ] || [ "$img" = "null" ];then
exit
fi
text="AI Card Fortune Telling"
title=`echo $j|jq -r .h_en`
title="[${title}]"
#desc=`echo $j|jq -r .p`
if [ 0 -eq $luck ];then
desc="0"
fi
if [ 1 -eq $luck ];then
desc="1"
fi
if [ 2 -eq $luck ];then
desc="2"
fi
if [ 3 -eq $luck ];then
desc="3"
fi
if [ 4 -eq $luck ];then
desc="4"
fi
if [ 5 -eq $luck ];then
desc="5"
fi
if [ 6 -eq $luck ];then
desc="6"
fi
if [ 7 -eq $luck ];then
desc="7"
fi
desc=`echo "lucky number ${luck}"`
if [ "`cat $tcid`" != "$cid" ];then
if $atr reply-og "$text" --cid $cid --uri $uri --img $img --title "$title" --description "$desc" --link $link;then
echo $cid >! $tcid
fi
fi
pass=`cat $HOME/.config/ai/api_card.json|jq -r .password`
token=`cat $HOME/.config/ai/api_card.json|jq -r .token`
if [ $luck -eq 7 ];then
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"luck_at\":\"$luck_at_n\",\"token\":\"$token\",\"luck\": $luck, \"next\": \"$nd\"}" -s $url/users/$uid`
else
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"luck_at\":\"$luck_at_n\",\"token\":\"$token\",\"luck\": $luck}" -s $url/users/$uid`
fi
exit

151
.config/ai/scpt/card_pay.zsh Executable file

@ -0,0 +1,151 @@
#!/bin/zsh
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
host=https://api.syui.ai
host_card=https://card.syui.ai/json/card.json
pass=`cat $HOME/.config/ai/api_card.json|jq -r .password`
token=`cat $HOME/.config/ai/api_card.json|jq -r .token`
handle=$1
username=`echo $1|cut -d . -f 1`
did=$2
cid=$3
uri=$4
pay=60000
echo $handle
function card_d(){
j=`curl -sL $host_card |jq -r ".[]|select(.ten_skill == true)"|jq -s`
n=`echo $j|jq length`
n_leng=$n
n=$(($RANDOM % n - 1))
card=`echo $j|jq -r ".[$n].id"`
img=`echo $j|jq -r ".[$n].img"`
ten=`echo $j|jq -r ".[$n].ten"`
title=`echo $j|jq -r ".[$n].h"`
title="[$title]"
ran_a=$(($RANDOM % 1000))
cp=$((ran_a + 500))
ran_s=$(($RANDOM % 5))
skill=ten
if [ $ran_s -eq 1 ];then
s=super
cp=$((cp + $ran_a))
else
s=normal
fi
#card=1;skill=3d;s=3d
all_data=`curl -sL "$host/users?itemsPerPage=3000"`
data=`echo $all_data|jq ".[]|select(.username == \"$username\")"`
uid=`echo $data|jq -r .id`
aiten=`echo $data|jq -r .aiten`
model=`echo $data|jq -r .model`
model_mode=`echo $data|jq -r .model_mode`
model_attack=`echo $data|jq -r .model_attack`
model_skill=`echo $data|jq -r .model_skill`
model_limit=`echo $data|jq -r .model_limit`
model_critical=`echo $data|jq -r .model_critical`
model_critical_d=`echo $data|jq -r .model_critical_d`
ten_data=`echo $all_data|jq ".|sort_by(.aiten)|reverse|.[]|select(.aiten >= $pay)"`
model_critical=$((RANDOM % 10 + model_critical))
json_model="{\"model_critical\":$model_critical, \"token\":\"$token\"}"
body_d=`echo "[card]\nid : $card\ncp : $cp\nstatus : $s\nskill : $skill\n---\n[model]\ncritical : ${model_critical}%"`
}
function card_user(){
if [ -z "$ten_data" ] || [ -z "$aiten" ] || [ $aiten -le $pay ];then
echo "aiten : $aiten >= $pay [1/${n_leng}]"
exit
else
pay_s=$((aiten - pay))
if [ $pay_s -lt 0 ] || [ -z "$pay_s" ];then
echo "aiten : $aiten >= $pay [1/${n_leng}]"
exit
fi
body_user=`echo "${aiten} : $aiten - $pay = $pay_s [1/${n_leng}]"`
fi
}
function card_check(){
data_uu=`curl -sL "$host/users/$uid/card?itemsPerPage=2000"`
card_check=`echo $data_uu|jq -r ".[]|select(.card == $card)"`
card_check_skill=`echo $card_check|jq "select(.skill == \"$skill\")"`
if [ -n "$card_check" ] && [ -n "$card_check_skill" ];then
echo "$body_user"
echo "lost, you chose the card you already have..."
echo "ai[model] Lv up!"
s_up=$((RANDOM % 3 + 1))
case `echo $((RANDOM % 4))` in
0)
model_mode=$((model_mode + s_up))
json="{\"token\":\"$token\", \"model_mode\": $model_mode}"
echo "\"mode\": Lv${model_mode}"
;;
1)
model_attack=$((model_attack + s_up))
json="{\"token\":\"$token\", \"model_attack\": $model_attack}"
echo "\"attack\": Lv${model_attack}"
;;
2)
model_skill=$((model_skill + s_up))
json="{\"token\":\"$token\", \"model_skill\": $model_skill}"
echo "\"skill\": Lv${model_skill}"
;;
3)
model_limit=$((model_limit + s_up))
json="{\"token\":\"$token\", \"model_limit\": $model_limit}"
echo "\"burst\": Lv${model_limit}"
;;
*)
model_limit=$((model_limit + s_up))
json="{\"token\":\"$token\", \"model_limit\": $model_limit}"
echo "\"burst\": Lv${model_limit}"
;;
esac
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "$json" -s $host/users/$uid`
card=0
cp=1
s=super
skill=lost
#echo "try again next time!"
echo "[card]"
echo "id : $card"
echo "cp : $cp"
echo "skill : $skill"
if [ "$handle" != "ai" ];then
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"token\":\"$token\", \"aiten\": $pay_s}" -s $host/users/$uid`
fi
tmp=`curl -X POST -H "Content-Type: application/json" -d "{\"owner\":$uid,\"card\":$card,\"status\":\"$s\",\"cp\":$cp,\"password\":\"$pass\",\"skill\":\"$skill\"}" -s $host/cards`
exit
fi
}
function card_pay(){
link=https://card.syui.ai/$username
text=`echo "$body_user\n$body_d"`
desc="[$ten]"
if [ "$handle" != "ai" ];then
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"token\":\"$token\", \"aiten\": $pay_s, \"model_critical\": $model_critical}" -s $host/users/$uid`
else
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"token\":\"$token\", \"aiten\": 10000000, \"model_critical\": $model_critical}" -s $host/users/$uid`
echo $tmp
fi
tmp=`curl -X POST -H "Content-Type: application/json" -d "{\"owner\":$uid,\"card\":$card,\"status\":\"$s\",\"cp\":$cp,\"password\":\"$pass\",\"skill\":\"$skill\"}" -s $host/cards`
echo "$text"
}
card_d
card_user
card_check
card_pay

37
.config/ai/scpt/card_tarot.zsh Executable file

@ -0,0 +1,37 @@
#!/bin/zsh
atr=$HOME/.cargo/bin/atr
url_j=https://card.syui.ai/json/card.json
tcid=$HOME/.config/atr/txt/tmp_notify_cid.txt
handle=$1
did=$2
cid=$3
uri=$4
if [ ! -d $HOME/.config/atr/txt ];then
mkdir -p $HOME/.config/atr/txt
fi
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
url=https://api.syui.ai
username=`echo $1|cut -d . -f 1`
link=https://card.syui.ai/$username
ran=$(($RANDOM % 10))
if [ $ran -eq 1 ];then
uranai="今日の運勢をルーン占いでやってください。結果を120文字以内で教えてください"
else
uranai="今日の運勢をタロット占いでやってください。結果を120文字以内で教えてください"
fi
body=`$atr chat "$uranai" -c`
if $atr r "$body" -c $cid -u $uri;then
echo $cid >! $tcid
fi
exit

@ -0,0 +1,37 @@
#!/bin/zsh
atr=$HOME/.cargo/bin/atr
url_j=https://card.syui.ai/json/card.json
tcid=$HOME/.config/ai/txt/tmp_notify_cid.txt
handle=$1
did=$2
cid=$3
uri=$4
if [ ! -d $HOME/.config/ai/txt ];then
mkdir -p $HOME/.config/ai/txt
fi
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
url=https://api.syui.ai
username=`echo $1|cut -d . -f 1`
link=https://card.syui.ai/$username
ran=$(($RANDOM % 10))
if [ $ran -eq 1 ];then
uranai="Please do a of today's rune-fortune. Tell us the result in 120 characters or less."
else
uranai="Please do a of today's tarot-fortune. Tell us the result in 120 characters or less."
fi
body=`$atr chat "$uranai" -c`
if $atr r "$body" -c $cid -u $uri;then
echo $cid >! $tcid
fi
exit

105
.config/ai/scpt/diffusers.zsh Executable file

@ -0,0 +1,105 @@
#!/bin/zsh
dir=${0:a:h}
hdir=${0:a:h:h}
mkdir -p $hdir/png
f=$hdir/png/t.png
f_sleep=$hdir/png/sleep
txt=$hdir/txt
if [ ! -d $txt ];then
mkdir -p $txt
fi
cfg=$dir/stable_diffusion_prompt.j
cfg_did=$txt/stable_diffusion_did.txt
opt_af=$txt/stable_diffusion_a.txt
opt_bf=$txt/stable_diffusion_b.txt
opt_allf=$txt/stable_diffusion_all.txt
if [ ! -f $cfg_did ];then
touch $cfg_did
fi
did=$1
if [ ! -f $cfg ];then
echo no file $cfg
exit
fi
opt_a=`echo $@|cut -d ' ' -f 2`
opt_b=`echo $@|cut -d ' ' -f 3`
echo $opt_a >! $opt_af
echo $opt_b >! $opt_bf
echo $@ >! $opt_allf
case "$opt_a" in
-p|p)
q="$opt_b , masterpiece, best quality, 8k wallpaper Highly, cinematic Lighting, cinematic Beautiful"
;;
-t|t)
tag=$opt_b
json=`cat $cfg|jq ".[]|select(.tag == \"${tag}\")"`
if [ -z "$json" ] || [ -z "$tag" ];then
echo no tag
exit
fi
json=`echo $json|jq -s`
n=`echo $json|jq "length"`
n=$((RANDOM % n))
q=`echo $json|jq -r ".[$n].body"`
#m=`echo $json|jq -r ".[$n].model"`
;;
*)
n=`cat $cfg|jq "length"`
n=$((RANDOM % n))
q=`cat $cfg|jq -r ".[$n].body"`
;;
esac
model_s="model
coharu
flat2d
pastelmix
pvcstyle"
model_r=$((RANDOM % `echo "$model_s"|wc -l` + 1))
m=`echo "$model_s"|awk "NR==$model_r"`
case $1 in
-pm)
m=$2
q=`echo $@ | cut -d ' ' -f 3-`
;;
esac
if [ -z "$q" ];then
echo no prompt
exit
fi
if [ -z "$m" ];then
m=model
fi
echo $q
echo $m
function run(){
if [ -f $f_sleep ];then
rm $f_sleep
fi
ssh diffusers "conda activate ldm;cd ./stable-diffusion/;python safe.py \'${q}\' ${m}"
scp -r diffusers:stable-diffusion/t.png $f
if [ $? -ne 0 ];then
touch $f_sleep
fi
}
if [ -n "`cat $cfg_did| grep -x $did`" ] && [ "$did" != "$admin" ];then
rm $f
else
echo "\n$did" >> $cfg_did
run
fi

@ -0,0 +1,15 @@
#!/bin/zsh
dir=${0:a:h}
f=$HOME/.config/ai/png/t.png
cid=$1
uri=$2
link=`ai img-upload $f|jq -r .blob.ref.'"$link"'`
if [ -f $f ];then
ai img-post "#stablediffusion" -l $link -c $cid -u $uri
else
ai reply "1 day limit" -c $cid -u $uri
fi

75
.config/ai/scpt/follow_all.zsh Executable file

@ -0,0 +1,75 @@
#!/bin/zsh
d=$HOME/.config/ai/txt
mkdir -p $d
unset cursor
function page(){
s=$1
if [ "$s" = "ers" ];then
opt="-w"
elif [ "$s" = "s" ];then
opt="-s"
fi
f=$d/follow${s}_${ii}.json
echo $f
if [ -n "$cursor" ];then
if [ ! -f $f ];then
ai follow $opt -c $cursor| jq . >! $f
else
echo no download
fi
else
if [ ! -f $f ];then
ai follow $opt| jq . >! $f
else
echo no download
fi
fi
cursor=`cat $f|jq -r .cursor`
echo "------------------------------"
echo $cursor
echo "------------------------------"
n=`cat $f|jq ".follow${s}|length"`
n=`expr $n - 1`
for ((i=0;i<=$n;i++))
do
handle=`cat $f|jq -r ".follow${s}|.[$i].handle"`
did=`cat $f|jq -r ".follow${s}|.[$i].did"`
flg=`cat $f|jq -r ".follow${s}|.[$i].viewer.following"`
flb=`cat $f|jq -r ".follow${s}|.[$i].viewer.followedBy"`
if [ "$flg" = "null" ];then
echo following
echo $flb
echo "follow : $handle"
echo "ai follow $did"
ai follow $did
fi
if [ "$flb" = "null" ];then
rkey=${flg##*/}
echo followedBy
echo $flg
echo "unfollow : $handle"
echo "ai follow $did -d $rkey"
ai follow $did -d $rkey
fi
done
}
ii=1
while [ "$cursor" != "null" ]
do
page ers $ii
ii=`expr $ii + 1`
done
unset cursor
ii=1
while [ "$cursor" != "null" ]
do
page s $ii
ii=`expr $ii + 1`
done

126
.config/ai/scpt/full_moon.j Normal file

@ -0,0 +1,126 @@
[
{"data":"20231003"},
{"data":"20230107"},
{"data":"20230122"},
{"data":"20230206"},
{"data":"20230220"},
{"data":"20230307"},
{"data":"20230322"},
{"data":"20230406"},
{"data":"20230420"},
{"data":"20230506"},
{"data":"20230520"},
{"data":"20230604"},
{"data":"20230618"},
{"data":"20230703"},
{"data":"20230718"},
{"data":"20230802"},
{"data":"20230816"},
{"data":"20230831"},
{"data":"20230915"},
{"data":"20230929"},
{"data":"20231015"},
{"data":"20231029"},
{"data":"20231113"},
{"data":"20231127"},
{"data":"20231213"},
{"data":"20231227"},
{"data":"20240111"},
{"data":"20240126"},
{"data":"20240210"},
{"data":"20240224"},
{"data":"20240310"},
{"data":"20240325"},
{"data":"20240409"},
{"data":"20240424"},
{"data":"20240508"},
{"data":"20240523"},
{"data":"20240606"},
{"data":"20240622"},
{"data":"20240706"},
{"data":"20240721"},
{"data":"20240804"},
{"data":"20240820"},
{"data":"20240903"},
{"data":"20240918"},
{"data":"20241003"},
{"data":"20241017"},
{"data":"20241101"},
{"data":"20241116"},
{"data":"20241201"},
{"data":"20241215"},
{"data":"20241231"},
{"data":"20250114"},
{"data":"20250129"},
{"data":"20250212"},
{"data":"20250228"},
{"data":"20250314"},
{"data":"20250329"},
{"data":"20250413"},
{"data":"20250428"},
{"data":"20250513"},
{"data":"20250527"},
{"data":"20250611"},
{"data":"20250625"},
{"data":"20250711"},
{"data":"20250725"},
{"data":"20250809"},
{"data":"20250823"},
{"data":"20250908"},
{"data":"20250922"},
{"data":"20251007"},
{"data":"20251021"},
{"data":"20251105"},
{"data":"20251120"},
{"data":"20251205"},
{"data":"20251220"},
{"data":"20260103"},
{"data":"20260119"},
{"data":"20260202"},
{"data":"20260217"},
{"data":"20260303"},
{"data":"20260319"},
{"data":"20260402"},
{"data":"20260417"},
{"data":"20260502"},
{"data":"20260517"},
{"data":"20260531"},
{"data":"20260615"},
{"data":"20260630"},
{"data":"20260714"},
{"data":"20260729"},
{"data":"20260813"},
{"data":"20260828"},
{"data":"20260911"},
{"data":"20260927"},
{"data":"20261011"},
{"data":"20261026"},
{"data":"20261109"},
{"data":"20261124"},
{"data":"20261209"},
{"data":"20261224"},
{"data":"20260103"},
{"data":"20260119"},
{"data":"20260202"},
{"data":"20260217"},
{"data":"20260303"},
{"data":"20260319"},
{"data":"20260402"},
{"data":"20260417"},
{"data":"20260502"},
{"data":"20260517"},
{"data":"20260531"},
{"data":"20260615"},
{"data":"20260630"},
{"data":"20260714"},
{"data":"20260729"},
{"data":"20260813"},
{"data":"20260828"},
{"data":"20260911"},
{"data":"20260927"},
{"data":"20261011"},
{"data":"20261026"},
{"data":"20261109"},
{"data":"20261124"},
{"data":"20261209"},
{"data":"20261224"}]

390
.config/ai/scpt/mastodon.zsh Executable file

@ -0,0 +1,390 @@
#!/bin/zsh
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
PATH=$PATH:$HOME/.cargo/bin
d=$HOME/.config/msr
f=$HOME/.config/msr/notify_log.txt
card=$HOME/.config/ai/scpt/api_card.zsh
if [ ! -d $d ];then
mkdir -p $d
fi
j=`$HOME/.cargo/bin/msr bot`
tmp=`echo $j|jq length`
if [ $tmp -eq 0 ];then
exit
fi
data_id=`echo $j|jq -r ".id"`
n=`echo $data_id|wc -l`
data_mid=`echo $j|jq -r ".mid"`
data_text=`echo $j|jq -r ".body"`
data_url=`echo $j|jq -r ".url"`
data_server=`echo $j|jq -r ".url"|cut -d / -f 3`
data_user=`echo $j|jq -r ".user"`
function user_create() {
if [ -n "$ap" ] && [ -n "$url" ];then
data=`curl -X POST -H "Content-Type: application/json" -d "{\"username\":\"$ap\",\"password\":\"$pass\",\"did\":\"$url\",\"next\":\"$nd_o\",\"updated_at\":\"$updated_at_o\"}" -sL "$host/users"`
uid=`echo $data|jq -r ".id"`
echo id $uid
else
echo error user create
fi
}
function card_env() {
card_url=https://card.syui.ai
host=https://api.syui.ai
d=`date +"%Y%m%d"`
nd=`date +"%Y%m%d" -d '1 day'`
nd_o=`date +"%Y%m%d" -d '-1 day'`
updated_at_o=`date --iso-8601=seconds -d '-1 day'`
username=`echo $1|cut -d . -f 1`
url_user_all="$host/users?itemsPerPage=2000"
pass=`cat $HOME/.config/ai/api_card.json|jq -r .password`
token=`cat $HOME/.config/ai/api_card.json|jq -r .token`
data_tmp=`curl -sL $url_user_all`
data=`echo "$data_tmp"|jq ".[]|select(.username == \"$ap\")"`
if [ -z "$data" ];then
data=`echo "$data_tmp"|jq ".[]|select(.username == \"$username\")"`
fi
if [ -z "$data" ];then
echo no $username
user_create
fi
username=`echo $data|jq -r .username`
data_did_check=`echo $data|jq -r .did`
uid=`echo $data|jq -r ".id"`
delete=`echo $data|jq -r ".delete"`
mastodon=`echo $data|jq -r ".mastodon"`
did=`echo $data|jq -r ".did"`
handle_change=`echo $data|jq -r ".handle"`
raid_at=`echo $data|jq -r .raid_at`
raid_at=`date -d "$raid_at" +"%Y%m%d"`
raid_at_n=`date --iso-8601=seconds`
server_at=`echo $data|jq -r .server_at`
server_at=`date -d "$server_at" +"%Y%m%d"`
server_at_n=`date --iso-8601=seconds`
updated_at=`echo $data|jq -r .updated_at`
updated_at=`date -d "$updated_at" +"%Y%m%d"`
updated_at_n=`date --iso-8601=seconds`
next=`echo $data|jq -r .next`
aiten=`echo $data|jq -r .aiten`
ten_su=`echo $data|jq -r .ten_su`
if [ "$a_team" = false ];then
echo "bsky @${username}"
echo "no activitypub-mode"
return 0
fi
echo "$card_url/$username"
}
function card_day() {
card_env $1
if [ $next -gt $d ] || [ "$updated_at" = "$d" ];then
echo limit 1 day
return 0
fi
tmp=`curl -X POST -H "Content-Type: application/json" -d "{\"owner\":$uid,\"password\":\"$pass\"}" -sL $host/cards`
card=`echo $tmp|jq -r .card`
card_url=`echo $tmp|jq -r .url`
cp=`echo $tmp|jq -r .cp`
skill=`echo $tmp|jq -r .skill`
if [ -z "$card" ];then
tmp=`curl -X POST -H "Content-Type: application/json" -d "{\"owner\":$uid,\"password\":\"$pass\"}" -sL $host/cards`
card=`echo $tmp|jq -r .card`
card_url=`echo $tmp|jq -r .url`
cp=`echo $tmp|jq -r .cp`
skill=`echo $tmp|jq -r .skill`
fi
echo "[card]"
echo id : $card
echo cp : $cp
if [ "$skill" != "normal" ];then
echo skill : $skill
fi
t=`echo $tmp|jq -r .card`
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"next\":\"$nd\",\"token\":\"$token\"}" -sL $host/users/$uid`
}
function card_b() {
card_env $1
if [ $updated_at -ge $d ] || [ "$updated_at" = "$d" ];then
echo "limit battle"
return 0
fi
id_all=`curl -sL "$host/users?itemsPerPage=2000"|jq ".[]|.id"`
id_n=`echo "$id_all"|wc -l`
id_nr=$(($RANDOM % $id_n))
r=`echo "$id_all"| awk "NR==$id_nr"`
if [ "$id_all" = "null" ];then
r=2
fi
if [ 0 -eq $id_n ] || [ 0 -eq $r ];then
r=2
fi
if [ -z "$id_n" ] || [ -z "$r" ];then
r=2
fi
data_uu=`curl -sL "$host/users/$uid/card?itemsPerPage=2000"`
data_u=`curl -sL "$host/users/$r/card?itemsPerPage=2000"`
tt=`echo $data_uu|jq ".[].cp"|sort -n -r`
ttt=`echo $data_u|jq ".[].cp"|sort -n -r`
#echo $data_u|jq ".[].cp"
nl=`echo $data_uu|jq length`
if [ $nl -ge 3 ];then
rs=$(($RANDOM % 3 + 1))
else
rs=$(($RANDOM % $nl + 1))
fi
#echo $data_u|jq ".[].cp"
nll=`echo $data_u|jq length`
rss=$(($RANDOM % $nll))
if [ $nll -ge 3 ];then
rss=$(($RANDOM % 3 + 1))
else
rss=$(($RANDOM % $nll + 1))
fi
cp_i=`echo $tt |awk "NR==$rs"`
cp_b=`echo $ttt |awk "NR==$rss"`
if [ -z "$cp_i" ];then
echo "null error"
return 0
fi
if [ -z "$cp_b" ];then
echo "null error"
return 0
fi
echo $tt | sed -n 1,3p
echo "---"
echo id : $r
echo $ttt | sed -n 1,3p
echo "---"
echo $cp_i vs $cp_b
if [ $cp_i -gt $cp_b ];then
echo "win!"
else
echo loss
fi
if [ $cp_i -gt $cp_b ];then
tmp=`curl -X POST -H "Content-Type: application/json" -d "{\"owner\":$uid,\"password\":\"$pass\"}" -sL $host/cards`
card=`echo $tmp|jq -r .card`
card_url=`echo $tmp|jq -r .url`
cp=`echo $tmp|jq -r .cp`
if [ -z "$card" ];then
tmp=`curl -X POST -H "Content-Type: application/json" -d "{\"owner\":$uid,\"password\":\"$pass\"}" -sL $host/cards`
card=`echo $tmp|jq -r .card`
card_url=`echo $tmp|jq -r .url`
cp=`echo $tmp|jq -r .cp`
fi
echo "[card]"
echo id : $card
echo cp : $cp
t=`echo $tmp|jq -r .card`
fi
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"updated_at\":\"$updated_at_n\",\"token\":\"$token\"}" -sL $host/users/$uid`
}
function card_s(){
card_env $1
username=$1
a_team=mastodon
b_team=bluesky
rr=`date +"%H%M"`
f_server=$HOME/.config/ai/txt/card_server.txt
f_server_user_at=$HOME/.config/ai/txt/card_server_user_at.txt
f_server_user_ap=$HOME/.config/ai/txt/card_server_user_ap.txt
f_server_ap=$HOME/.config/ai/txt/card_server_ap.txt
f_server_at=$HOME/.config/ai/txt/card_server_at.txt
f_server_start_time=$HOME/.config/ai/txt/card_server_start_time.txt
if [ `cat $f_server` -eq 1 ];then
echo shutdown server battle
exit
fi
if [ ! -f $f_server_start_time ];then
server_start=`date +"%H%M"`
echo "$server_start" >! $f_server_start_time
echo 0 >! $f_server_at
echo 0 >! $f_server_ap
fi
cp_ap=`cat $f_server_ap`
cp_at=`cat $f_server_at`
if [ -f $f_server_start_time ];then
server_start=`cat $f_server_start_time`
server_time=`date -d "$server_start 30 min" +"%H%M"`
fi
#echo "time:`date -d "$server_time" +"%H:%M"`"
if [ $server_at -ge $d ] || [ "$server_at" = "$d" ];then
echo "limit battle"
exit
fi
data_uu=`curl -sL "$host/users/$uid/card?itemsPerPage=2000"`
fav_card=`echo $data_uu|jq "sort_by(.cp)|reverse|.[0]"`
if [ ! -f $f_server_user_at ];then
echo start >> $f_server_user_at
fi
if [ ! -f $f_server_user_ap ];then
echo start >> $f_server_user_ap
fi
commit_user_at=`cat $f_server_user_at|tail -n 1`
commit_user_ap=`cat $f_server_user_ap|tail -n 1`
echo $username >> $f_server_user_ap
cp_i=`echo $fav_card|jq -r ".cp"`
cp_ii=$cp_i
card_name=`echo $fav_card|jq -r ".card"`
card_status=`echo $fav_card|jq -r ".status"`
card_skill=`echo $fav_card|jq -r ".skill"`
skill=$card_skill
if [ "$skill" = "critical" ];then
cp_i=$((cp_i + cp_i))
fi
if [ "$skill" = "dragon" ];then
cp_i=$((cp_i * 3))
fi
if [ "$skill" = "yui" ];then
cp_i=$((cp_i + ten_su))
fi
cp_all=$((cp_i + cp_ap))
# サーバーバトルの還元期間
#cp_all=$((cp_ap - cp_i))
if [ "$skill" = "critical" ];then
echo "$cp_i ---> $cp_ap"
elif [ "$skill" = "post" ];then
cp_post=`$HOME/.cargo/bin/atr pro $1 -p`
cp_i=$((cp_i + cp_post))
cp_all=$((cp_i + cp_ap))
echo "🔥 $cp_i ---> $cp_ap"
elif [ "$skill" = "luck" ];then
echo "$cp_i ---> $cp_ap"
elif [ "$skill" = "dragon" ];then
echo "🐉 $cp_i ---> $cp_ap"
elif [ "$skill" = "yui" ];then
echo "🔅 $cp_i ---> $cp_ap"
else
echo "$cp_i ---> $cp_ap"
fi
echo $cp_all >! $f_server_ap
echo
echo "[${a_team}] ${cp_all}"
echo "┣ @${username}"
echo "┗ @${commit_user_ap}"
echo
echo "┏━ vs ━┛"
echo
echo "[${b_team}] ${cp_at}"
echo "┗ @${commit_user_at}"
#echo "[log]"
#echo "${cp_ap}/$a_team --> ${commit_user_ap}"
#echo "${commit_user_at} <-- ${cp_at}/$b_team"
#echo "${username} --> $cp_all/$a_team"
if [ $rr -gt $server_time ];then
#echo "----"
#echo "timeup!"
echo 1 >! $f_server
rm $f_server_start_time
rm $f_server_at
rm $f_server_ap
mv $f_server_user_at $f_server_user_at.back
mv $f_server_user_ap $f_server_user_ap.back
fi
echo "----"
cp_plus=$(($RANDOM % 100 + 1))
cp=$((cp_ii + cp_plus))
body="level up!"
echo "${body}${cp}(+${cp_plus})"
tmp=`curl -sL -X PATCH -H "Content-Type: application/json" -d "{\"cp\":$cp,\"token\":\"$token\"}" $host/cards/$fav`
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"server_at\":\"$server_at_n\", \"token\":\"$token\"}" -s $host/users/$uid`
}
function mastodon_notify() {
for ((i=1;i<=$n;i++))
do
mid=`echo $data_mid|awk "NR==$i"`
check=`cat $f|grep $mid`
if [ -n "$check" ];then
echo ok
continue
fi
url=`echo $data_url|awk "NR==$i"`
user=`echo $data_user|awk "NR==$i"`
text=`echo $data_text|awk "NR==$i"`
server=`echo $data_server|awk "NR==$i"`
ap="@${user}@${server}"
if [ -f "$GOPATH/bin/pup" ];then
text=`echo ${text}|pup "p text{}"|tail -n 1|cut -d " " -f 2-|tr -d '"'|sed -e "s/&#39;/'/g" -e 's/&quot;/"/g'`
else
text=`echo ${text}|sed -e 's/<[^>]*>//g'|cut -d " " -f 2-|tr -d '"'|sed -e "s/&#39;/'/g" -e 's/&quot;/"/g'`
fi
echo $text
com=`echo $text|cut -d " " -f 1`
opt=`echo $text|cut -d " " -f 2`
if [ "card" = "$com" ] || [ "/card" = "$com" ];then
if [ "b" = "$opt" ] || [ "-b" = "$opt" ];then
text=`card_b $user`
echo $user $text
msr cn "@${user}@${server} `echo $text`" -mm $mid
echo $mid >> $f
continue
fi
if [ "s" = "$opt" ] || [ "-s" = "$opt" ];then
text=`card_s $user`
echo $user $text
msr cn "@${user}@${server} `echo $text`" -mm $mid
echo $mid >> $f
continue
fi
text=`card_day $user`
echo $user $text
msr cn "@${user}@${server} `echo $text`" -mm $mid
echo $mid >> $f
fi
done
}
mastodon_notify

106
.config/ai/scpt/nyancat.zsh Executable file

@ -0,0 +1,106 @@
#!/bin/zsh
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
host=https://api.syui.ai
host_card=https://card.syui.ai/json/card.json
pass=`cat $HOME/.config/ai/api_card.json|jq -r .password`
token=`cat $HOME/.config/ai/api_card.json|jq -r .token`
handle=$1
username=`echo $1|cut -d . -f 1`
did=$2
cid=$3
uri=$4
opt=$5
pay=100
eat_file=$HOME/.config/ai/txt/nyancat_eat.txt
ran=`echo $(($RANDOM % 15))`
eat="🍺☕ 🍵 🍶 🍼🍻 🍸 🍹 🍷 🍴 🍕 🍔 🍟 🍗 🍖 🍝🍛 🍤 🍱 🍣 🍥 🍙 🍘 🍚 🍜 🍲 🍢🍡 🍳 🍞 🍩 🍮 🍦 🍨 🍧 🎂 🍰 🍪🍫 🍬 🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉🍓 🍑 🍈 🍌 🍐 🍍 🍠 🍆 🍅 🌽"
eat=`echo $eat|grep "$opt"`
if [ -z "$eat" ];then
ran=`echo $(($RANDOM % 3))`
if [ $ran -eq 1 ];then
body="| キュー"
elif [ $ran -eq 2 ];then
body="| ミュー"
else
body="| ピャー"
fi
echo "uncooked"
echo "A__A
|・ㅅ・ |
|っ c|
$body
U ̄ ̄U"
exit
fi
echo "| ${opt} |" >> $eat_file
body_d="A__A
|・ㅅ・ |
|っ c|
`tac $eat_file|grep -v '| |'`
U ̄ ̄U"
function card_user(){
all_data=`curl -sL "$host/users?itemsPerPage=3000"`
data=`echo $all_data|jq ".[]|select(.username == \"$username\")"`
uid=`echo $data|jq -r .id`
aiten=`echo $data|jq -r .aiten`
like=`echo $data|jq -r .like`
ten_data=`echo $all_data|jq ".|sort_by(.aiten)|reverse|.[]|select(.aiten >= $pay)"`
if [ -z "$ten_data" ] || [ -z "$aiten" ] || [ $aiten -le $pay ];then
echo "aiten : $aiten >= $pay"
echo "failed to buy food"
echo "please : @yui.syui.ai /ten"
exit
else
pay_s=$((aiten - pay))
like_s=$((like + 1))
if [ $pay_s -le 0 ] || [ -z "$pay_s" ];then
echo "aiten : $aiten >= $pay"
echo "failed to buy food"
echo "please : @yui.syui.ai /ten"
exit
fi
body_user=`echo "${aiten} : $aiten - $pay = $pay_s"`
fi
}
function card_like() {
if [ $like -gt 3 ] && [ $ran -eq 1 ];then
echo "happy!"
su=`cat $eat_file|wc -l`
su=$((su * 50))
pay_s=$((aiten + su))
body_user=`echo "${aiten} : $aiten + $su = $pay_s"`
rm $eat_file
echo "| ${opt} |" >> $eat_file
body_d="A__A
|・ㅅ・ |
|っ c|
`tac $eat_file|grep -v '| |'`
U ̄ ̄U"
fi
}
function card_pay(){
link=https://card.syui.ai/$username
text=`echo "$body_user\n$body_d"`
desc="[$ten]"
tmp=`curl -X PATCH -H "Content-Type: application/json" -d "{\"like\":$like_s,\"token\":\"$token\", \"aiten\": $pay_s}" -s $host/users/$uid`
echo "$text"
}
card_user
card_like
card_pay

@ -0,0 +1,35 @@
#!/bin/zsh
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
host_card=https://card.syui.ai/json/card.json
pass=`cat $HOME/.config/ai/api_card.json|jq -r .password`
token=`cat $HOME/.config/ai/api_card.json|jq -r .token`
eat_file=$HOME/.config/ai/txt/nyancat_eat.txt
eat=`cat $eat_file|awk "NR==1"`
if [ -z "$eat" ];then
exit
fi
body_d="thx!
A__A
|・ㅅ・ |
|っ c|
`cat $eat_file|awk "NR==1"`
U ̄ ̄U"
host=https://api.syui.ai
data=`curl -sL "$host/users?itemsPerPage=3000"|jq ".[]|select(.like >= 10)"`
tmp=`echo $data|jq -s`
n=`echo $tmp|jq "length"`
ran=$(($RANDOM % n - 1))
echo $ran
user=`echo $tmp|jq -r ".[$ran].username"`
did=`echo $tmp|jq -r ".[$ran].did"`
echo ai @ $did -p "`echo $body_d`"
ai @ $did -p "`echo $body_d`"

BIN
.config/ai/scpt/png/t.png Normal file

Binary file not shown.

After

(image error) Size: 585 KiB

@ -0,0 +1,52 @@
[
{
"tag": "girl",
"model":"model",
"body": "masterpiece, best quality, 1girl, solo, flower, long hair, outdoors, letterboxed, school uniform, day, sky, looking up, short sleeves, parted lips, shirt, cloud, black hair, sunlight, white shirt, serafuku, upper body, from side, pink flower, blurry, brown hair, blue sky, depth of field"
},
{
"tag": "girl",
"model":"model",
"body": "best quality, high quality photo, clear face, detailed face, beautiful face, photo rialistic, balcony, baroque architecture, 1girl, 16yo, bronde, very long hair, windy, floating hair, see through frilled white dress, look at outside, white lily, starry night, big moon, moon light, volumetric lighting, side shot, , good anatomy, perspective"
},
{
"tag": "gril",
"model":"model",
"body": "mksks style, masterpiece, ultra-detailed, illustration,best quality, blue sky, ((cloudy sky)), rooftop, cityscape, hatsune miku, yuki miku, yuki miku (2017), yuki miku (2019), perfect lighting, science fiction, (looking at viewer), ((kawaii)), loli, fantastic_eyes, hyper extreme detailed, (glowing_eyes:0.95), highly detailed symmetric faces, holding bouque"
},
{
"tag": "gril",
"model":"model",
"body": "1girl, 12yo,(room animal costume:1.2),baby (chick:1.2) costume, fluffy, baby chick concept room, fancy, cute, costume, A small cute chick wrapped in pale yellow feathers. Its round body and soft feathers seem to celebrate the miracle of life. The sparkle of life. Cute orange beak,pastel color <lora:luckyStarStyleLora_offset:0.8>"
},
{
"tag": "gril",
"model": "model",
"body": "masterpiece, best quality, very_high_resolution, large_filesize, full color, beautiful kawaii, gold hair, little girl"
},
{
"tag": "field",
"model":"pvcstyle",
"body": "picture by lvl landscape highly detailed high detailed concept art HD art HQ illustration 4k illustration 8k illustration 4K wallpaper 8K wallpaper Highly Cinematic Lighting cinematic Beautiful starry sky milky way extreme high detailed colorful flower garden from above"
},
{
"tag": "field",
"model":"model",
"body": "flying warship, no humans, letterboxed, spacecraft, cloud, sky, turret <lora:flying warship-noise:0.7>"
},
{
"tag": "gril",
"model": "model",
"body": "traininganyahyper-1800, 1girl, ahoge, animal_ears, aqua_eyes, bangs, black_hairband, blurry, blurry_background, blush, bokeh, bow, bush, cat_ears, christmas_tree, clenched_hand, clenched_hands, collarbone, day, depth_of_field, diffraction_spikes, dress, eyebrows_visible_through_hair, fake_animal_ears, forest, grass, green_eyes, hairband, hands_up, lens_flare, long_sleeves, looking_at_viewer, nature, open_mouth, outdoors, park, path, paw_pose, photo_background, solo, sparkle, sparkling_eyes, sunlight, tree<hypernet:traininganyahyper-1800:1.0>"
},
{
"tag": "gril",
"model": "model",
"body": "(best quality),(masterpiece),(high resolution),(silky skin), (upper body:1.9), smile, blush, looking at viewer, detailed angel wing, detailed angel halo, wedding, veil, (girl extend one hand and show the wedding ring), standing, (1girl), (child), (little), (thin), (small breasts:1.5), (blond middle hair, cutoff), (extremely beautiful eyes), in charch, perfect anatomy, unity 8k wallpaper, <lora:toddler-xl-v2_last:-2>"
},
{
"tag": "gril",
"model": "model",
"body": "masterpiece, best quality, (photography:1.3), (high quality:1.2), detailed face, detailed eyes, A girl in a white one-piece dress standing on the sidewalk of a rice field at dusk gazes dreamily at the crimson sky reflected on the surface of the water"
}
]

382
.config/ai/scpt/user.zsh Executable file

@ -0,0 +1,382 @@
#!/bin/zsh
txt=_atproto.$1
did=$2
curl -sL plc.directory/$did/log |jq ".[]|.alsoKnownAs|.[]?" | grep -n .| head -n 4
dig -t TXT $txt|grep "did=did:plc:"|head -n 1
#dig syui.ai +short
#!/bin/zsh
#
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
if [ "$1" = "test" ] || [ -z "$1" ];then
handle=syui.ai
else
handle=$1
fi
post=0
d=`date +"%Y-%m-%d"`
od=`date +"%Y-%m-%d" --date '1 day ago'`
unset cursor
function first_record(){
cursor=`curl -sL "https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=$handle&collection=app.bsky.feed.post&limit=100" |jq -r ".cursor"`
t=`curl -sL "https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=$handle&collection=app.bsky.feed.post&limit=100" |jq -r ".[]|.[]?|.value.createdAt"|cut -d T -f 1`
n=`echo $t|wc -l`
}
function cursor_record(){
cursor=`curl -sL "https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=$handle&collection=app.bsky.feed.post&limit=100&cursor=$cursor" |jq -r ".cursor"`
t=`curl -sL "https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=$handle&collection=app.bsky.feed.post&limit=100&cursor=$cursor" |jq -r ".[]|.[]?|.value.createdAt"|cut -d T -f 1`
n=`echo $t|wc -l`
}
function day_check(){
for ((i=1;i<=$n;i++))
do
tt=`echo $t|awk "NR==$i"`
if [ "$tt" = "$d" ];then
post=$((post + 1))
echo $post
fi
if [ "$tt" = "$od" ];then
echo $tt $od
echo $post
exit
fi
done
}
for ((ii=1;ii<=100;ii++))
do
if [ $ii -eq 1 ];then
first_record
else
echo $cursor
cursor_record
fi
day_check
done
#!/bin/zsh
url_plc="https://plc.directory/export"
host_at=bsky.social
url=https://plc.directory
url_at=https://$host_at/xrpc/com.atproto.repo.listRecords
dir=$HOME/.config/atr/txt
file=$dir/user_list.txt
atr=$HOME/.cargo/bin/atr
unset timed
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
if [ -z "$1" ];then
exit
fi
if ! echo $1|grep "." >/dev/null 2>&1;then
echo "ex : user syui.bsky.social"
exit
fi
if [ ! -d $dir ];then
mkdir -p $dir
fi
if [ ! -f $file ];then
touch $file
fi
function mfile() {
t=`cat $file|sort|uniq`
if [ -n "$t" ];then
echo "$t" >! ${file}.back
mv ${file}.back $file
fi
}
function plc(){
if cat $file|grep "$1" >/dev/null 2>&1;then
cat $file|grep "$1"
exit
fi
json_tmp=`curl -sL "${url_plc}?after=${timed}"|jq .`
json=`echo $json_tmp|jq "select(.operation.handle == \"$1\")"`
if [ -z "$json" ];then
check=`echo $json_tmp|jq -r ".operation.alsoKnownAs"|head -n 1`
if [ "null" != "$check" ];then
json=`echo $json_tmp|jq "select(.operation.alsoKnownAs|.[] == \"at://$1\")"` >/dev/null 2>&1
fi
fi
if [ -n "$json" ];then
created_at=`echo $json|jq -r .createdAt |tail -n 1`
fi
if [ -n "$created_at" ];then
echo "$created_at : $1"
echo "$created_at : $1" >> $file
mfile
exit
fi
}
function fan_art(){
if ! echo $3|grep "https://bsky.app/profile/">/dev/null 2>&1;then
echo "please url : https://bsky.app/profile/$1/post/xxx"
exit
fi
if [ -z "$4" ];then
echo "please img-url : https://example.com/img.png"
exit
fi
img=$4
author=`echo $3|cut -d / -f 5`
cd $dir_git_card_page
cat $file_fanart|jq ".+ {\"add\":\"$1\",\"link\":\"$3\",\"author\":\"$author\",\"img\":\"$img\"}" >! $file_fanart.back
if cat $file_fanart|jq . ;then
mv $file_fanart.back $file_fanart
git add $file_fanart
git commit -m "add fanart"
git push -u orgin main
fi
}
if [ "$2" = "--url" ];then
if [ -z "$3" ];then
exit
fi
fan_art $3
exit
fi
function first(){
#https://bsky.app/profile/$1/post/$e
handle=$2
did="$atr did $2"
curl -sL "https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=$handle&collection=app.bsky.feed.post&reverse=true" |jq -r ".[]|.[0]?|.uri,.value.text,.value.createdAt"
}
if [ "$2" = "-f" ] || [ "$2" = "f" ];then
first $1
exit
fi
if [ "$2" = "-l" ];then
mfile
cat $file
exit
fi
function first_created(){
#https://bsky.app/profile/$1/post/$e
#curl -sL "https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=$1&collection=app.bsky.feed.post&reverse=true" |jq -r ".[]|.[0]?|.createdAt"
curl -sL "https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=$1&collection=app.bsky.feed.post&reverse=true" |jq -r ".[]|.[0]?|.value.createdAt"
}
if [ -z "$2" ];then
first_created $1
fi
if [ -n "$2" ] ;then
first $2
fi
#for ((i=0;i<=300;i++))
#do
# if [ $i -eq 0 ];then
# timed="1970-01-01"
# fi
# plc $1
# timed=`echo $json_tmp|jq -r .createdAt|tail -n 1`
#done
#!/bin/zsh
if [ -n "$1" ];then
did=$1
else
did=`atr did yui.syui.ai`
fi
pds=`curl -sL https://plc.directory/$did|jq -r ".service.[].serviceEndpoint" | cut -d / -f 3-`
handle=`curl -sL https://plc.directory/$did|jq -r ".alsoKnownAs.[]"|cut -d / -f 3-`
old_pds=`curl -sL https://plc.directory/$did/log|jq -r ".[0].service"|cut -d / -f 3-`
old_handle=`curl -sL https://plc.directory/$did/log|jq -r ".[0]|.handle"`
first_post=`curl -sL "https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=$did&collection=app.bsky.feed.post&reverse=true" |jq -r ".[]|.[0]?|.value.createdAt"`
body_handle=$handle
body_pds=$pds
if [ "$old_handle" != "null" ];then
body_handle="$old_handle -> $handle"
fi
if [ "$old_pds" != "null" ];then
body_pds="$old_pds -> $pds"
fi
old_pds=`curl -sL https://plc.directory/$did/log|jq -r ".[0]|.services.atproto_pds.endpoint"|cut -d / -f 3-`
old_handle=`curl -sL https://plc.directory/$did/log|jq -r ".[0]|.alsoKnownAs.[0]"|cut -d / -f 3-`
if [ "$old_handle" != "null" ];then
body_handle="$old_handle -> $handle"
fi
if [ "$old_pds" != "null" ];then
body_pds="$old_pds -> $pds"
fi
if [ "$old_pds" = "$pds" ];then
body_pds=$pds
fi
if [ "$old_handle" = "$handle" ];then
body_handle=$handle
fi
echo pds : $body_pds
echo handle : $body_handle
echo did : $did
echo createdAt : $first_post
#!/bin/zsh
url_plc="https://plc.directory/export"
host_at=bsky.social
url=https://plc.directory
url_at=https://$host_at/xrpc/com.atproto.repo.listRecords
dir=$HOME/.config/ai/txt
file=$dir/user_list.txt
unset timed
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
if [ -z "$1" ];then
exit
fi
if ! echo $1|grep "." >/dev/null 2>&1;then
echo "ex : user syui.bsky.social"
exit
fi
if [ ! -d $dir ];then
mkdir -p $dir
fi
if [ ! -f $file ];then
touch $file
fi
function mfile() {
t=`cat $file|sort|uniq`
if [ -n "$t" ];then
echo "$t" >! ${file}.back
mv ${file}.back $file
fi
}
function plc(){
if cat $file|grep "$1" >/dev/null 2>&1;then
cat $file|grep "$1"
exit
fi
json_tmp=`curl -sL "${url_plc}?after=${timed}"|jq .`
json=`echo $json_tmp|jq "select(.operation.handle == \"$1\")"`
if [ -z "$json" ];then
check=`echo $json_tmp|jq -r ".operation.alsoKnownAs"|head -n 1`
if [ "null" != "$check" ];then
json=`echo $json_tmp|jq "select(.operation.alsoKnownAs|.[] == \"at://$1\")"` >/dev/null 2>&1
fi
fi
if [ -n "$json" ];then
created_at=`echo $json|jq -r .createdAt |tail -n 1`
fi
if [ -n "$created_at" ];then
echo "$created_at : $1"
echo "$created_at : $1" >> $file
mfile
exit
fi
}
function fan_art(){
if ! echo $3|grep "https://bsky.app/profile/">/dev/null 2>&1;then
echo "please url : https://bsky.app/profile/$1/post/xxx"
exit
fi
if [ -z "$4" ];then
echo "please img-url : https://example.com/img.png"
exit
fi
img=$4
author=`echo $3|cut -d / -f 5`
cd $dir_git_card_page
cat $file_fanart|jq ".+ {\"add\":\"$1\",\"link\":\"$3\",\"author\":\"$author\",\"img\":\"$img\"}" >! $file_fanart.back
if cat $file_fanart|jq . ;then
mv $file_fanart.back $file_fanart
git add $file_fanart
git commit -m "add fanart"
git push -u orgin main
fi
}
if [ "$2" = "--url" ];then
if [ -z "$3" ];then
exit
fi
fan_art $3
exit
fi
function first(){
#https://bsky.app/profile/$1/post/$e
curl -sL "https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=$1&collection=app.bsky.feed.post&reverse=true" |jq -r ".[]|.[0]?|.uri,.value"
}
if [ "$2" = "-f" ];then
first $1
exit
fi
if [ "$2" = "-l" ];then
mfile
cat $file
exit
fi
function first_created(){
#https://bsky.app/profile/$1/post/$e
#curl -sL "https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=$1&collection=app.bsky.feed.post&reverse=true" |jq -r ".[]|.[0]?|.createdAt"
curl -sL "https://bsky.social/xrpc/com.atproto.repo.listRecords?repo=$1&collection=app.bsky.feed.post&reverse=true" |jq -r ".[]|.[0]?|.value.createdAt"
}
first_created $1
#for ((i=0;i<=300;i++))
#do
# if [ $i -eq 0 ];then
# timed="1970-01-01"
# fi
# plc $1
# timed=`echo $json_tmp|jq -r .createdAt|tail -n 1`
#done

0
.config/keep Normal file

11
.gitignore vendored Normal file

@ -0,0 +1,11 @@
Cargo.lock
target
*.json
*.DS_Store
**.DS_Store
scpt/json/
.config/ai/*.toml
.config/ai/*.json
.config/ai/txt
.config/ai/png
.ssh

19
Cargo.toml Normal file

@ -0,0 +1,19 @@
[package]
name = "ai"
version = "0.0.1"
edition = "2021"
[dependencies]
seahorse = "*"
reqwest = { version = "*", features = ["blocking", "json"] }
tokio = { version = "1", features = ["full"] }
shellexpand = "*"
config = "*"
serde = "*"
serde_json = "*"
serde_derive = "*"
url = { version = "2.0", features = ["serde"] }
rustc-serialize = "*"
toml = "*"
iso8601-timestamp = "*"
sysinfo = "*"

10
Dockerfile Normal file

@ -0,0 +1,10 @@
FROM syui/aios
ADD .ssh /root/.ssh
#USER root
#ADD .config /root/.config
#WORKDIR /root
#
#ADD ./test/entrypoint.sh /
#RUN chmod +x /entrypoint.sh
#
#ENTRYPOINT ["/entrypoint.sh"]

25
Makefile.toml Normal file

@ -0,0 +1,25 @@
[tasks.format]
install_crate = "rustfmt"
command = "cargo"
args = ["fmt", "--", "--emit=files"]
[tasks.clean]
command = "cargo"
args = ["clean"]
[tasks.build]
command = "cargo"
args = ["build"]
dependencies = ["clean"]
[tasks.test]
command = "cargo"
args = ["test"]
dependencies = ["clean"]
[tasks.my-flow]
dependencies = [
"format",
"build",
"test"
]

@ -1,6 +1,86 @@
## ai `bot`
<img src="./icon/avatar.png" width="100">
- name : ai bot
- base : [rust](https://www.rust-lang.org)
- host : [yui.syui.ai](https://bsky.app/profile/yui.syui.ai), [ai.syu.is](https://web.syu.is/profile/ai.syu.is)
```sh
$ ai
```
### logo
```sh
$ cargo build
$ ./target/debug/ai
$ ./target/debug/ai ai
```
```sh
$ ai ai -t avatar
```
### login
```sh
# ai login $handle -p $password
$ ai l yui.syui.ai -p password
$ cat ~/.config/ai/token.toml
```
```sh
# ai l $handle -p $password -s $server
$ ai l ai.syu.is -p password -s syu.is
```
### refresh
```
$ ai r
```
### notify
```
$ ai n
```
```
$ ai n | jq .
```
### bot
```
$ ai bot
```
|command|sub|type|body|
|---|---|---|---|
|@yui.syui.ai did||mention, reply| [plc.directory](https://plc.directory)/$did/log |
|@yui.syui.ai card|r, s, b|mention, reply| https://card.syui.ai |
|@yui.syui.ai ten|start, d, p|mention, reply| https://card.syui.ai |
|@yui.syui.ai fav|{cid}|mention, reply| https://card.syui.ai |
|@yui.syui.ai egg|{password}|mention, reply| https://card.syui.ai |
|@yui.syui.ai 占い||mention, reply| https://yui.syui.ai |
|@yui.syui.ai nyan|🍰|mention, reply| https://yui.syui.ai |
|@yui.syui.ai diffusers|{keyword}|mention, reply| [diffusers](https://huggingface.co/docs/diffusers/index) |
|@yui.syui.ai sh(admin)|{command}|mention, reply| [archlinux](https://wiki.archlinux.org/title/Systemd-nspawn) |
### test
`zsh`
```sh
$ ./test/ai.zsh t
```
### make
```sh
$ cargo install --force cargo-make
$ cargo make build
```

9
compose.yml Normal file

@ -0,0 +1,9 @@
services:
aios:
#image: syui/aios
build:
context: .
restart: always
volumes:
- ./.config:/root/.config
command: ai bot

52
docs/wiki.md Normal file

@ -0,0 +1,52 @@
### docker
```sh
$ docker run -it syui/aios ai
$ docker run -it -d syui/aios zsh -c "ai login <handle> -p <password> && ai bot"
```
```sh
$ cp -rf ~/.config/ai ./.config/
$ docker compose up
```
### cron
```sh
$ sudo pacman -S fcron
$ fcrontab -e
* * * * * $HOME/bot/test/ai.zsh c
```
### ssh
```sh
$ ssh-keygen -f /.ssh/diffusers.key -t ed25519
```
```sh
FROM syui/aios
ADD .ssh /root/.ssh
```
```sh
Host diffusers
HostName localhost
User root
IdentityFile ~/.ssh/diffusers.key
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
```
```sh
services:
aios:
#image: syui/aios
build:
context: .
restart: always
volumes:
- ./.config:/root/.config
command: ai bot -a syui.syu.is
```

BIN
icon/ai.png Normal file

Binary file not shown.

After

(image error) Size: 89 KiB

BIN
icon/avatar.png Normal file

Binary file not shown.

After

(image error) Size: 557 KiB

205
src/ascii.rs Normal file

@ -0,0 +1,205 @@
use sysinfo::System;
pub fn c_ascii(x: &str) {
let logo = "
";
let avatar = "
";
let color = "








































";
let avatar_color = "








































";
let mut sys = System::new_all();
sys.refresh_all();
let s = x.to_string();
match &*s {
"logo" => println!("{}", logo),
"color" => println!("{}", color),
"avatar" => println!("{}", avatar),
"avatar_color" => println!("{}", avatar_color),
"os" => println!("{}\n\t", color),
_ => println!("not matched"),
}
println!("total memory: {} bytes", sys.total_memory());
println!("System name: {:?}", System::name().unwrap());
println!(
"System kernel version: {:?}",
System::kernel_version().unwrap()
);
//println!("System OS version: {:?}", System::os_version().unwrap());
println!(
"System host name: {:?}",
System::host_name().unwrap()
);
println!("NB CPUs: {}", sys.cpus().len());
//let disks = Disks::new_with_refreshed_list();
//for disk in &disks {
// println!("{disk:?}");
//}
//let networks = Networks::new_with_refreshed_list();
//println!("=> networks:");
//for (interface_name, data) in &networks {
// println!("{interface_name}: {}/{} B", data.received(), data.transmitted());
//}
//let components = Components::new_with_refreshed_list();
//println!("=> components:");
//for component in &components {
// println!("{component:?}");
//}
}

335
src/bot.rs Normal file

@ -0,0 +1,335 @@
use seahorse::Context;
use std::process::Command;
use crate::notify;
use crate::notify_read;
use crate::openai;
use crate::refresh;
use crate::reply;
use crate::reply_link;
use crate::data::c_char;
use crate::data::data_scpt;
use crate::data::log_file;
use crate::data::w_cid;
use crate::data::Notify;
pub fn c_bot(c: &Context) {
let h = async {
let mut notify = notify::get_request(100).await;
if notify == "err" {
refresh(c);
notify = notify::get_request(100).await;
}
let notify: Notify = serde_json::from_str(&notify).unwrap();
let n = notify.notifications;
let length = &n.len();
let su = 0..*length;
for i in su {
let reason = &n[i].reason;
let handle = &n[i].author.handle;
let did = &n[i].author.did;
let read = n[i].isRead;
let cid = &n[i].cid;
let uri = &n[i].uri;
let time = &n[i].indexedAt;
let mut cid_root = cid;
let mut uri_root = uri;
let check_cid = w_cid(cid.to_string(), log_file(&"n1"), false);
let check_cid_run = w_cid(cid.to_string(), log_file(&"n2"), false);
// thread
if !n[i].record.reply.is_none() {
cid_root = &n[i].record.reply.as_ref().unwrap().root.cid;
uri_root = &n[i].record.reply.as_ref().unwrap().root.uri;
}
let mut text = "";
if !n[i].record.text.is_none() {
text = &n[i].record.text.as_ref().unwrap();
}
let vec: Vec<&str> = text.split_whitespace().collect();
let handlev: Vec<&str> = handle.split('.').collect();
let mut handlev = handlev[0].trim().to_string();
let mut link = "https://card.syui.ai/".to_owned() + &handlev;
let s = 0;
let mut e = link.chars().count();
let mut com = "".to_string();
let mut prompt = "".to_string();
let mut prompt_sub = "".to_string();
if reason == "mention" {
com = vec[1].trim().to_string();
prompt = vec[2..].join(" ");
if vec.len() > 2 {
prompt_sub = vec[3..].join(" ");
}
} else if reason == "reply" {
com = vec[0].trim().to_string();
prompt = vec[1..].join(" ");
if vec.len() > 1 {
prompt_sub = vec[2..].join(" ");
}
}
if prompt.is_empty() == false || com.is_empty() == false {
println!("{}", read);
println!("{}", handle);
println!(
"cid:{}\nuri:{}\ncid_root:{}\nuri_root:{}",
cid, uri, cid_root, uri_root
);
println!("reason:{}\ncom:{}\nprompt:{}", reason, com, prompt);
println!("prompt_sub:{}", prompt_sub);
}
let mut admin = "".to_string();
if c.string_flag("admin").is_ok() {
admin = c.string_flag("admin").unwrap();
}
if check_cid == false && { reason == "mention" || reason == "reply" }
|| check_cid_run == false && { reason == "mention" || reason == "reply" }
{
w_cid(cid.to_string(), log_file(&"n2"), true);
if com == "/did" || com == "did" {
let link = "https://plc.directory/".to_owned() + &did + &"/log";
let s = 0;
let e = link.chars().count();
let d = "\n".to_owned() + &did.to_string();
let text_limit = c_char(d);
if text_limit.len() > 3 {
let str_rep = reply_link::post_request(
text_limit.to_string(),
link.to_string(),
s,
e.try_into().unwrap(),
cid.to_string(),
uri.to_string(),
cid_root.to_string(),
uri_root.to_string(),
)
.await;
w_cid(cid.to_string(), log_file(&"n1"), true);
println!("{}", str_rep);
}
} else if com == "/diffusers" || com == "diffusers" {
let _output = Command::new(data_scpt(&"diffusers"))
.arg(&did)
.arg(&prompt)
.output()
.expect("zsh");
let _output = Command::new(data_scpt(&"diffusers_img"))
.arg(&cid)
.arg(&uri)
.output()
.expect("zsh");
w_cid(cid.to_string(), log_file(&"n1"), true);
} else if com.contains("") == true
|| com.contains("うらない") == true
|| com.contains("うらなって") == true
{
let output = Command::new(data_scpt(&"card_fortune"))
.arg(&handle)
.arg(&did)
.arg(&cid)
.arg(&uri)
.output()
.expect("zsh");
let d = String::from_utf8_lossy(&output.stdout);
let d = d.to_string();
let text_limit = c_char(d);
if text_limit.len() > 3 {
println!("{}", text_limit);
w_cid(cid.to_string(), log_file(&"n1"), true);
}
} else if com == "/card" || com == "card" {
let output = Command::new(data_scpt(&"api_card"))
.arg(&handle)
.arg(&did)
.arg(&prompt)
.output()
.expect("zsh");
let d = String::from_utf8_lossy(&output.stdout);
let dd = "\n".to_owned() + &d.to_string();
let text_limit = c_char(dd);
if text_limit.len() > 3 {
if d.contains("handle") == false {
let str_rep = reply_link::post_request(
text_limit.to_string(),
link.to_string(),
s,
e.try_into().unwrap(),
cid.to_string(),
uri.to_string(),
cid_root.to_string(),
uri_root.to_string(),
)
.await;
println!("{}", str_rep);
} else {
handlev = handle.replace(".", "-").to_string();
link = "https://card.syui.ai/".to_owned() + &handlev;
e = link.chars().count();
let str_rep = reply_link::post_request(
d.to_string(),
link.to_string(),
s,
e.try_into().unwrap(),
cid.to_string(),
uri.to_string(),
cid_root.to_string(),
uri_root.to_string(),
)
.await;
println!("{}", str_rep);
}
w_cid(cid.to_string(), log_file(&"n1"), true);
}
} else if com == "/fav" || com == "fav" {
let output = Command::new(data_scpt(&"api_fav"))
.arg(&handle)
.arg(&did)
.arg(&prompt)
.output()
.expect("zsh");
let d = String::from_utf8_lossy(&output.stdout);
let dd = "\n".to_owned() + &d.to_string();
let text_limit = c_char(dd);
if text_limit.len() > 3 {
let str_rep = reply_link::post_request(
d.to_string(),
link.to_string(),
s,
e.try_into().unwrap(),
cid.to_string(),
uri.to_string(),
cid_root.to_string(),
uri_root.to_string(),
)
.await;
println!("{}", str_rep);
w_cid(cid.to_string(), log_file(&"n1"), true);
}
} else if com == "/egg" || com == "egg" {
let output = Command::new(data_scpt(&"api_egg"))
.arg(&handle)
.arg(&did)
.arg(&prompt)
.output()
.expect("zsh");
let d = String::from_utf8_lossy(&output.stdout);
let dd = "\n".to_owned() + &d.to_string();
let text_limit = c_char(dd);
if text_limit.len() > 3 {
let str_rep = reply_link::post_request(
d.to_string(),
link.to_string(),
s,
e.try_into().unwrap(),
cid.to_string(),
uri.to_string(),
cid_root.to_string(),
uri_root.to_string(),
)
.await;
println!("{}", str_rep);
w_cid(cid.to_string(), log_file(&"n1"), true);
}
} else if com == "/nyan" || com == "nyan" {
let output = Command::new(data_scpt(&"nyancat"))
.arg(&handle)
.arg(&did)
.arg(&cid)
.arg(&uri)
.arg(&prompt)
.output()
.expect("zsh");
let d = String::from_utf8_lossy(&output.stdout);
let dd = "\n".to_owned() + &d.to_string();
let text_limit = c_char(dd);
println!("{}", text_limit);
if text_limit.len() > 3 {
let str_rep = reply::post_request(
text_limit.to_string(),
cid.to_string(),
uri.to_string(),
cid_root.to_string(),
uri_root.to_string(),
)
.await;
println!("{}", str_rep);
w_cid(cid.to_string(), log_file(&"n1"), true);
}
} else if com == "/ten" || com == "ten" {
let output = Command::new(data_scpt(&"api_ten"))
.arg(&handle)
.arg(&did)
.arg(&cid)
.arg(&uri)
.arg(&prompt)
.arg(&prompt_sub)
.output()
.expect("zsh");
let d = String::from_utf8_lossy(&output.stdout);
let d = "\n".to_owned() + &d.to_string();
let text_limit = c_char(d);
if text_limit.len() > 3 {
let str_rep = reply_link::post_request(
text_limit.to_string(),
link.to_string(),
s,
e.try_into().unwrap(),
cid.to_string(),
uri.to_string(),
cid_root.to_string(),
uri_root.to_string(),
)
.await;
println!("{}", str_rep);
w_cid(cid.to_string(), log_file(&"n1"), true);
}
} else if { com == "sh" || com == "/sh" } && handle == &admin {
println!("admin:{}", admin);
let output = Command::new(data_scpt(&"arch"))
.arg(&prompt)
.output()
.expect("zsh");
let d = String::from_utf8_lossy(&output.stdout);
let d = d.to_string();
let text_limit = c_char(d);
let str_rep = reply::post_request(
text_limit.to_string(),
cid.to_string(),
uri.to_string(),
cid_root.to_string(),
uri_root.to_string(),
)
.await;
println!("{}", str_rep);
w_cid(cid.to_string(), log_file(&"n1"), true);
} else {
// openai
let str_openai = openai::post_request(prompt.to_string()).await;
let text_limit = c_char(str_openai);
let str_rep = reply::post_request(
text_limit.to_string(),
cid.to_string(),
uri.to_string(),
cid_root.to_string(),
uri_root.to_string(),
)
.await;
println!("{}", str_rep);
w_cid(cid.to_string(), log_file(&"n1"), true);
}
let str_notify = notify_read::post_request(time.to_string()).await;
println!("{}", str_notify);
println!("---");
}
}
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}

647
src/data.rs Normal file

@ -0,0 +1,647 @@
use config::{Config, ConfigError, File};
use seahorse::Context;
use serde_derive::{Deserialize, Serialize};
use std::fs;
use std::fs::OpenOptions;
use std::io::Read;
use std::io::Write;
use std::path::Path;
pub fn data_file(s: &str) -> String {
let file = "/.config/ai/";
let mut f = shellexpand::tilde("~").to_string();
f.push_str(&file);
let path = Path::new(&f);
if path.is_dir() == false {
let _ = fs::create_dir_all(f.clone());
}
match &*s {
"toml" => f + &"token.toml",
"json" => f + &"token.json",
"refresh" => f + &"refresh.toml",
_ => f + &"." + &s,
}
}
pub fn log_file(s: &str) -> String {
let file = "/.config/ai/txt/";
let mut f = shellexpand::tilde("~").to_string();
f.push_str(&file);
let path = Path::new(&f);
if path.is_dir() == false {
let _ = fs::create_dir_all(f.clone());
}
match &*s {
"n1" => f + &"notify_cid.txt",
"n2" => f + &"notify_cid_run.txt",
_ => f + &s,
}
}
impl Token {
pub fn new() -> Result<Self, ConfigError> {
let d = data_file("json");
let s = Config::builder()
.add_source(File::with_name(&d))
.add_source(config::Environment::with_prefix("APP"))
.build()?;
s.try_deserialize()
}
}
impl Data {
pub fn new() -> Result<Self, ConfigError> {
let d = data_file("toml");
let s = Config::builder()
.add_source(File::with_name(&d))
.add_source(config::Environment::with_prefix("APP"))
.build()?;
s.try_deserialize()
}
}
impl Refresh {
pub fn new() -> Result<Self, ConfigError> {
let d = data_file("refresh");
let s = Config::builder()
.add_source(File::with_name(&d))
.add_source(config::Environment::with_prefix("APP"))
.build()?;
s.try_deserialize()
}
}
#[derive(Debug, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Token {
pub did: String,
pub handle: String,
pub accessJwt: String,
pub refreshJwt: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Data {
pub host: String,
pub password: String,
pub did: String,
pub handle: String,
pub access: String,
pub refresh: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Refresh {
pub access: String,
pub refresh: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct BaseUrl {
pub profile_get: String,
pub thread_get: String,
pub describe: String,
pub record_list: String,
pub record_create: String,
pub record_delete: String,
pub session_create: String,
pub session_refresh: String,
pub session_get: String,
pub timeline_get: String,
pub timeline_author: String,
pub upload_blob: String,
pub update_handle: String,
pub account_create: String,
pub notify_count: String,
pub notify_list: String,
pub notify_update: String,
pub repo_update: String,
pub like: String,
pub repost: String,
pub follow: String,
pub follows: String,
pub followers: String,
}
pub fn url(s: &str) -> String {
let s = String::from(s);
let data = Data::new().unwrap();
let data = Data {
host: data.host,
password: data.password,
handle: data.handle,
did: data.did,
access: data.access,
refresh: data.refresh,
};
let t = "https://".to_string() + &data.host.to_string() + &"/xrpc/".to_string();
let baseurl = BaseUrl {
profile_get: "com.atproto.identity.resolveHandle".to_string(),
thread_get: "app.bsky.feed.getPostThread".to_string(),
record_create: "com.atproto.repo.createRecord".to_string(),
record_delete: "com.atproto.repo.deleteRecord".to_string(),
describe: "com.atproto.repo.describeRepo".to_string(),
record_list: "com.atproto.repo.listRecords".to_string(),
session_create: "com.atproto.server.createSession".to_string(),
session_refresh: "com.atproto.server.refreshSession".to_string(),
session_get: "com.atproto.server.getSession".to_string(),
timeline_get: "app.bsky.feed.getTimeline".to_string(),
timeline_author: "app.bsky.feed.getAuthorFeed".to_string(),
like: "app.bsky.feed.like".to_string(),
repost: "app.bsky.feed.repost".to_string(),
follow: "app.bsky.graph.follow".to_string(),
follows: "app.bsky.graph.getFollows".to_string(),
followers: "app.bsky.graph.getFollowers".to_string(),
upload_blob: "com.atproto.repo.uploadBlob".to_string(),
account_create: "com.atproto.server.createAccount".to_string(),
update_handle: "com.atproto.identity.updateHandle".to_string(),
notify_count: "app.bsky.notification.getUnreadCount".to_string(),
notify_list: "app.bsky.notification.listNotifications".to_string(),
notify_update: "app.bsky.notification.updateSeen".to_string(),
repo_update: "com.atproto.sync.updateRepo".to_string(),
};
match &*s {
"profile_get" => t.to_string() + &baseurl.profile_get,
"thread_get" => t.to_string() + &baseurl.thread_get,
"describe" => t.to_string() + &baseurl.describe,
"record_list" => t.to_string() + &baseurl.record_list,
"record_create" => t.to_string() + &baseurl.record_create,
"record_delete" => t.to_string() + &baseurl.record_delete,
"session_create" => t.to_string() + &baseurl.session_create,
"session_refresh" => t.to_string() + &baseurl.session_refresh,
"session_get" => t.to_string() + &baseurl.session_get,
"timeline_get" => t.to_string() + &baseurl.timeline_get,
"timeline_author" => t.to_string() + &baseurl.timeline_get,
"upload_blob" => t.to_string() + &baseurl.upload_blob,
"account_create" => t.to_string() + &baseurl.account_create,
"update_handle" => t.to_string() + &baseurl.update_handle,
"notify_list" => t.to_string() + &baseurl.notify_list,
"notify_count" => t.to_string() + &baseurl.notify_count,
"notify_update" => t.to_string() + &baseurl.notify_update,
"repo_update" => t.to_string() + &baseurl.repo_update,
"like" => t.to_string() + &baseurl.like,
"repost" => t.to_string() + &baseurl.repost,
"follow" => t.to_string() + &baseurl.follow,
"follows" => t.to_string() + &baseurl.follows,
"followers" => t.to_string() + &baseurl.followers,
_ => s,
}
}
pub fn data_toml(s: &str) -> String {
let s = String::from(s);
let data = Data::new().unwrap();
let data = Data {
host: data.host,
password: data.password,
handle: data.handle,
did: data.did,
access: data.access,
refresh: data.refresh,
};
match &*s {
"host" => data.host,
"password" => data.password,
"handle" => data.handle,
"did" => data.did,
"access" => data.access,
"refresh" => data.refresh,
_ => s,
}
}
pub fn c_refresh(access: &str, refresh: &str) {
let ff = data_file(&"refresh");
let mut ff = fs::File::create(ff.clone()).unwrap();
let refreshs = Refresh {
access: access.to_string(),
refresh: refresh.to_string(),
};
let toml = toml::to_string(&refreshs).unwrap();
ff.write_all(&toml.as_bytes()).unwrap();
}
pub fn data_refresh(s: &str) -> String {
let s = String::from(s);
let data = Data::new().unwrap();
let data = Data {
host: data.host,
password: data.password,
handle: data.handle,
did: data.did,
access: data.access,
refresh: data.refresh,
};
let mut _file = match Refresh::new()
{
Err(_why) => c_refresh(&data.access, &data.refresh),
Ok(_) => println!(""),
};
let refresh = Refresh::new().unwrap();
let refresh = Refresh {
access: refresh.access,
refresh: refresh.refresh,
};
match &*s {
"access" => refresh.access,
"refresh" => refresh.refresh,
_ => s,
}
}
pub fn data_scpt(s: &str) -> String {
let s = String::from(s);
let file = "/.config/ai/scpt/".to_owned() + &s + &".zsh";
let mut f = shellexpand::tilde("~").to_string();
f.push_str(&file);
return f;
}
#[derive(Serialize, Deserialize)]
pub struct Notify {
pub notifications: Vec<Notifications>,
}
#[derive(Serialize, Deserialize)]
pub struct Status {
pub handle: String,
pub did: String,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct DidDocs {
pub verificationMethod: Vec<VerificationMethod>,
pub service: Vec<Service>,
pub id: String,
pub alsoKnownAs: Vec<AlsoKnownAs>,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct VerificationMethod {
pub id: String,
pub r#type: String,
pub controller: String,
pub publicKeyMultibase: String,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Service {
pub id: String,
pub r#type: String,
pub serviceEndpoint: String,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct AlsoKnownAs {}
#[derive(Serialize, Deserialize)]
pub struct Timeline {
pub feed: Vec<Feed>,
}
#[derive(Serialize, Deserialize)]
pub struct Session {
pub did: String,
pub email: String,
pub handle: String,
}
#[derive(Serialize, Deserialize)]
pub struct Follow {
pub follows: Vec<Author>,
pub cursor: String,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Notifications {
pub uri: String,
pub cid: String,
pub author: Author,
pub reason: String,
//pub reasonSubject: String,
pub record: Record,
pub isRead: bool,
pub indexedAt: String,
//pub labels: Labels,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Thread {
pub r#type: String,
pub post: String,
pub root: String,
pub author: Author,
pub reason: String,
//pub reasonSubject: String,
pub record: Record,
pub isRead: bool,
pub indexedAt: String,
//pub labels: Labels,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Author {
pub did: String,
//pub declaration: Declaration,
pub description: Option<String>,
pub displayName: Option<String>,
pub handle: String,
pub avatar: Option<String>,
pub viewer: Viewer,
//pub labels: Labels,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Labels {
pub src: Option<String>,
pub uri: Option<String>,
pub cid: Option<String>,
pub val: Option<String>,
pub cts: Option<String>,
pub neg: Option<bool>,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Declaration {
pub actorType: String,
pub cid: String,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Viewer {
pub muted: bool,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
#[derive(Debug)]
pub struct Record {
pub text: Option<String>,
pub createdAt: String,
pub reply: Option<Reply>,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
#[derive(Debug)]
pub struct Reply {
pub parent: ReplyParent,
pub root: ReplyRoot,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
#[derive(Debug)]
pub struct ReplyRoot {
pub cid: String,
pub uri: String,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
#[derive(Debug)]
pub struct ReplyParent {
pub cid: String,
pub uri: String,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Langs {}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Feed {
pub post: Post,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Post {
pub did: Option<String>,
pub uri: String,
pub cid: String,
pub collection: Option<String>,
pub record: Record,
pub author: Author,
pub reason: Option<String>,
pub indexedAt: String,
pub replyCount: i32,
pub postCount: Option<i32>,
pub repostCount: i32,
pub likeCount: i32,
}
#[derive(Serialize, Deserialize)]
pub struct Cid {
pub cid: String,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Img {
pub blob: Blob,
}
#[derive(Serialize, Deserialize)]
pub struct Blob {
pub r#ref: Ref,
}
#[derive(Serialize, Deserialize)]
pub struct Ref {
pub link: String,
}
#[derive(Serialize, Deserialize)]
pub struct Handle {
pub handle: String,
}
//#[derive(Serialize, Deserialize)]
//pub struct Did {
// pub did: String
//}
//#[derive(Serialize, Deserialize)]
//pub struct Labels {
//}
//
//#[derive(Serialize, Deserialize)]
//pub struct Viewer {
// pub muted: bool,
// pub blockedBy: bool,
//}
//
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct ProfileIdentityResolve {
pub did: String,
}
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Profile {
pub did: String,
pub handle: String,
pub followsCount: Option<i32>,
pub followersCount: Option<i32>,
pub postsCount: i32,
pub indexedAt: Option<String>,
pub avatar: Option<String>,
pub banner: Option<String>,
pub displayName: Option<String>,
pub description: Option<String>,
pub viewer: Viewer,
pub labels: Labels,
}
pub fn c_char(i: String) -> String {
let l = 250;
let mut s = String::new();
for ii in i.chars().enumerate() {
match ii.0 {
n if n > l.try_into().unwrap() => break,
_ => s.push(ii.1),
}
}
return s;
}
pub fn w_cfg(h: &str, res: &str, password: &str) {
let f = data_file(&"json");
let ff = data_file(&"toml");
let mut f = fs::File::create(f.clone()).unwrap();
let mut ff = fs::File::create(ff.clone()).unwrap();
f.write_all(&res.as_bytes()).unwrap();
let json: Token = serde_json::from_str(&res).unwrap();
let datas = Data {
host: h.to_string(),
password: password.to_string(),
did: json.did.to_string(),
handle: json.handle.to_string(),
access: json.accessJwt.to_string(),
refresh: json.refreshJwt.to_string(),
};
let toml = toml::to_string(&datas).unwrap();
ff.write_all(&toml.as_bytes()).unwrap();
let ff = data_file(&"refresh");
let mut ff = fs::File::create(ff.clone()).unwrap();
let refreshs = Refresh {
access: json.accessJwt.to_string(),
refresh: json.refreshJwt.to_string(),
};
let toml = toml::to_string(&refreshs).unwrap();
ff.write_all(&toml.as_bytes()).unwrap();
}
pub fn w_refresh(res: &str) {
let ff = data_file(&"refresh");
let mut ff = fs::File::create(ff.clone()).unwrap();
let json: Token = serde_json::from_str(&res).unwrap();
let refreshs = Refresh {
access: json.accessJwt.to_string(),
refresh: json.refreshJwt.to_string(),
};
let toml = toml::to_string(&refreshs).unwrap();
ff.write_all(&toml.as_bytes()).unwrap();
}
pub fn w_cid(cid: String, file: String, t: bool) -> bool {
let f = file;
let mut file = match OpenOptions::new()
.create(true)
.write(true)
.read(true)
.append(true)
.open(f.clone())
{
Err(why) => panic!("Couldn't open {}: {}", f, why),
Ok(file) => file,
};
let mut contents = String::new();
match file.read_to_string(&mut contents) {
Err(why) => panic!("Couldn't read {}: {}", f, why),
Ok(_) => (),
}
if contents.contains(&cid) == false {
if t {
let cid = cid + "\n";
match file.write_all(cid.as_bytes()) {
Err(why) => panic!("Couldn't write \"{}\" to {}: {}", contents, f, why),
Ok(_) => println!("finished"),
}
}
let check = false;
return check;
} else {
let check = true;
return check;
}
}
pub fn c_follow_all() {
let file = "/.config/ai/scpt/follow_all.zsh";
let mut f = shellexpand::tilde("~").to_string();
f.push_str(&file);
use std::process::Command;
let output = Command::new(&f).output().expect("zsh");
let d = String::from_utf8_lossy(&output.stdout);
let d = "\n".to_owned() + &d.to_string();
println!("{}", d);
}
pub fn c_openai_key(c: &Context) {
let api = c.args[0].to_string();
let o = "api='".to_owned() + &api.to_string() + &"'".to_owned();
let o = o.to_string();
let l = shellexpand::tilde("~") + "/.config/ai/openai.toml";
let l = l.to_string();
let mut l = fs::File::create(l).unwrap();
if o != "" {
l.write_all(&o.as_bytes()).unwrap();
}
println!("{:#?}", l);
}
impl Open {
pub fn new() -> Result<Self, ConfigError> {
let d = shellexpand::tilde("~") + "/.config/ai/openai.toml";
let s = Config::builder()
.add_source(File::with_name(&d))
.add_source(config::Environment::with_prefix("APP"))
.build()?;
s.try_deserialize()
}
}
#[derive(Debug, Deserialize)]
pub struct Open {
pub api: String,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct OpenData {
choices: Vec<Choices>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Choices {
text: String,
}

22
src/describe.rs Normal file

@ -0,0 +1,22 @@
extern crate reqwest;
//use crate::data_toml;
use crate::url;
pub async fn get_request(user: String) -> String {
//let token = data_refresh(&"access");
let url = url(&"describe");
let client = reqwest::Client::new();
let res = client
.get(url)
.query(&[("repo", &user)])
//.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

81
src/follow.rs Normal file

@ -0,0 +1,81 @@
extern crate reqwest;
use crate::data_toml;
use crate::data_refresh;
use crate::url;
use iso8601_timestamp::Timestamp;
use serde_json::json;
//use crate::data::Follow;
pub async fn post_request(u: String) -> String {
let token = data_refresh(&"access");
let did = data_toml(&"did");
let handle = data_toml(&"handle");
let url = url(&"record_create");
let col = "app.bsky.graph.follow".to_string();
let d = Timestamp::now_utc();
let d = d.to_string();
let post = Some(json!({
"repo": handle.to_string(),
"did": did.to_string(),
"collection": col.to_string(),
"record": {
"subject": u.to_string(),
"createdAt": d.to_string(),
},
}));
let client = reqwest::Client::new();
let res = client
.post(url)
.json(&post)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}
pub async fn delete_request(u: String, rkey: String) -> String {
let token = data_refresh(&"access");
let did = data_toml(&"did");
let handle = data_toml(&"handle");
let url = url(&"record_delete");
let col = "app.bsky.graph.follow".to_string();
let d = Timestamp::now_utc();
let d = d.to_string();
let post = Some(json!({
"repo": handle.to_string(),
"did": did.to_string(),
"collection": col.to_string(),
"rkey": rkey.to_string(),
"record": {
"subject": u.to_string(),
"createdAt": d.to_string(),
},
}));
let client = reqwest::Client::new();
let res = client
.post(url)
.json(&post)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

24
src/followers.rs Normal file

@ -0,0 +1,24 @@
extern crate reqwest;
use crate::data_refresh;
use crate::url;
//use serde_json::json;
pub async fn get_request(actor: String, cursor: Option<String>) -> String {
let token = data_refresh(&"access");
let url = url(&"followers");
let cursor = cursor.unwrap();
let client = reqwest::Client::new();
let res = client
.get(url)
.query(&[("actor", actor), ("cursor", cursor)])
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

26
src/follows.rs Normal file

@ -0,0 +1,26 @@
extern crate reqwest;
use crate::data_refresh;
use crate::url;
//use serde_json::json;
pub async fn get_request(actor: String, cursor: Option<String>) -> String {
let token = data_refresh(&"access");
let url = url(&"follows");
let cursor = cursor.unwrap();
//let cursor = "1682386039125::bafyreihwgwozmvqxcxrhbr65agcaa4v357p27ccrhzkjf3mz5xiozjvzfa".to_string();
//let cursor = "1682385956974::bafyreihivhux5m3sxbg33yruhw5ozhahwspnuqdsysbo57smzgptdcluem".to_string();
let client = reqwest::Client::new();
let res = client
.get(url)
.query(&[("actor", actor), ("cursor", cursor)])
//cursor.unwrap()
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

59
src/img.rs Normal file

@ -0,0 +1,59 @@
extern crate reqwest;
use crate::data_toml;
use crate::data_refresh;
use crate::url;
use serde_json::json;
use iso8601_timestamp::Timestamp;
pub async fn post_request(text: String, link: String) -> String {
let token = data_refresh(&"access");
let did = data_toml(&"did");
let handle = data_toml(&"handle");
let url = url(&"record_create");
let col = "app.bsky.feed.post".to_string();
let d = Timestamp::now_utc();
let d = d.to_string();
let post = Some(json!({
"repo": handle.to_string(),
"did": did.to_string(),
"collection": col.to_string(),
"record": {
"createdAt": d.to_string(),
"text": text.to_string(),
"embed": {
"$type": "app.bsky.embed.images",
"images": [
{
"alt": "",
"image": {
"$type":"blob",
"ref": {
"$link" : link.to_string()
},
"mimeType": "image/png",
"size": 0
}
}
]
}
}
}));
let client = reqwest::Client::new();
let res = client
.post(url)
.json(&post)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res
}

74
src/img_reply.rs Normal file

@ -0,0 +1,74 @@
extern crate reqwest;
use crate::data_toml;
use crate::data_refresh;
use crate::url;
use iso8601_timestamp::Timestamp;
use serde_json::json;
pub async fn post_request(
text: String,
link: String,
cid: String,
uri: String,
itype: String,
) -> String {
let token = data_refresh(&"access");
let did = data_toml(&"did");
let handle = data_toml(&"handle");
let url = url(&"record_create");
let col = "app.bsky.feed.post".to_string();
let d = Timestamp::now_utc();
let d = d.to_string();
let post = Some(json!({
"repo": handle.to_string(),
"did": did.to_string(),
"collection": col.to_string(),
"record": {
"createdAt": d.to_string(),
"text": text.to_string(),
"embed": {
"$type": "app.bsky.embed.images",
"images": [
{
"alt": "",
"image": {
"$type":"blob",
"ref": {
"$link" : link.to_string()
},
"mimeType": itype.to_string(),
"size": 0
}
}
]
},
"reply": {
"root": {
"cid": cid.to_string(),
"uri": uri.to_string()
},
"parent": {
"cid": cid.to_string(),
"uri": uri.to_string()
}
}
}
}));
let client = reqwest::Client::new();
let res = client
.post(url)
.json(&post)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

59
src/img_upload.rs Normal file

@ -0,0 +1,59 @@
extern crate reqwest;
use crate::data_toml;
use crate::data_refresh;
use crate::url;
use serde_json::json;
use iso8601_timestamp::Timestamp;
pub async fn post_request(text: String, link: String) -> String {
let token = data_refresh(&"access");
let did = data_toml(&"did");
let handle = data_toml(&"handle");
let url = url(&"record_create");
let col = "app.bsky.feed.post".to_string();
let d = Timestamp::now_utc();
let d = d.to_string();
let post = Some(json!({
"repo": handle.to_string(),
"did": did.to_string(),
"collection": col.to_string(),
"record": {
"createdAt": d.to_string(),
"text": text.to_string(),
"embed": {
"$type": "app.bsky.embed.images",
"images": [
{
"alt": "",
"image": {
"$type":"blob",
"ref": {
"$link" : link.to_string()
},
"mimeType": "image/png",
"size": 0
}
}
]
}
}
}));
let client = reqwest::Client::new();
let res = client
.post(url)
.json(&post)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res
}

45
src/like.rs Normal file

@ -0,0 +1,45 @@
extern crate reqwest;
use crate::data_toml;
use crate::data_refresh;
use crate::url;
use iso8601_timestamp::Timestamp;
use serde_json::json;
pub async fn post_request(cid: String, uri: String) -> String {
let token = data_refresh(&"access");
let did = data_toml(&"did");
let handle = data_toml(&"handle");
let url = url(&"record_create");
let col = "app.bsky.feed.like".to_string();
let d = Timestamp::now_utc();
let d = d.to_string();
let post = Some(json!({
"repo": handle.to_string(),
"did": did.to_string(),
"collection": col.to_string(),
"record": {
"subject": {
"uri": uri.to_string(),
"cid": cid.to_string()
},
"createdAt": d.to_string(),
},
}));
let client = reqwest::Client::new();
let res = client
.post(url)
.json(&post)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

591
src/main.rs Normal file

@ -0,0 +1,591 @@
use seahorse::{App, Command, Context, Flag, FlagType};
use std::env;
use crate::ascii::c_ascii;
use crate::bot::c_bot;
use crate::data::c_follow_all;
use crate::data::c_openai_key;
use crate::data::data_toml;
use crate::data::data_refresh;
use crate::data::url;
use crate::data::w_cfg;
use crate::data::w_refresh;
use data::ProfileIdentityResolve;
pub mod ascii;
pub mod bot;
pub mod data;
pub mod describe;
pub mod follow;
pub mod followers;
pub mod follows;
pub mod img_reply;
pub mod like;
pub mod mention;
pub mod notify;
pub mod notify_read;
pub mod openai;
pub mod post;
pub mod post_link;
pub mod profile;
pub mod refresh;
pub mod reply;
pub mod reply_link;
pub mod reply_og;
pub mod repost;
pub mod session;
pub mod timeline_author;
pub mod token;
fn main() {
let args: Vec<String> = env::args().collect();
let app = App::new(env!("CARGO_PKG_NAME"))
.command(
Command::new("ai")
.alias("a")
.action(ascii_art)
.flag(
Flag::new("type", FlagType::String)
.description("type flag")
.alias("t"),
)
)
.command(
Command::new("bot")
.alias("b")
.action(bot)
.flag(
Flag::new("admin", FlagType::String)
.alias("a"),
)
)
.command(
Command::new("follow_all")
.action(follow_all),
)
.command(
Command::new("login")
.alias("l")
.description("l <handle> -p <password>\n\t\t\tl <handle> -p <password> -s <server>")
.action(token)
.flag(
Flag::new("password", FlagType::String)
.description("password flag")
.alias("p"),
)
.flag(
Flag::new("server", FlagType::String)
.description("server flag")
.alias("s"),
)
)
.command(
Command::new("refresh")
.alias("r")
.action(refresh),
)
.command(
Command::new("notify")
.alias("n")
.action(notify),
)
.command(
Command::new("timeline")
.alias("t")
.action(timeline),
)
.command(
Command::new("did")
.description("did <handle>")
.action(did)
)
.command(
Command::new("post")
.description("p <text>")
.alias("p")
.action(post)
.flag(
Flag::new("link", FlagType::String)
.alias("l"),
)
)
.command(
Command::new("like")
.description("like <cid> -u <uri>")
.action(like)
.flag(
Flag::new("uri", FlagType::String)
.alias("u"),
)
)
.command(
Command::new("repost")
.description("repost <cid> -u <uri>")
.action(repost)
.flag(
Flag::new("uri", FlagType::String)
.alias("u"),
)
)
.command(
Command::new("reply-og")
.description("reply-og <text> -c <cid> -u <uri> -i <img> -t <title> -d <description> -l <link>")
.action(reply_og)
.flag(
Flag::new("uri", FlagType::String)
.alias("u"),
)
.flag(
Flag::new("cid", FlagType::String)
.alias("c"),
)
.flag(
Flag::new("link", FlagType::String)
.alias("l"),
)
.flag(
Flag::new("title", FlagType::String)
.alias("t"),
)
.flag(
Flag::new("description", FlagType::String)
.alias("d"),
)
.flag(
Flag::new("img", FlagType::String)
.alias("i"),
)
)
.command(
Command::new("reply")
.description("r <text> -u <uri> -c <cid>")
.action(reply)
.flag(
Flag::new("uri", FlagType::String)
.alias("u"),
)
.flag(
Flag::new("cid", FlagType::String)
.alias("c"),
)
.flag(
Flag::new("link", FlagType::String)
.description("-l <link>")
.alias("l"),
)
)
.command(
Command::new("mention")
.description("@ <handle> -p <text>")
.alias("@")
.action(mention)
.flag(
Flag::new("post", FlagType::String)
.alias("p"),
)
)
.command(
Command::new("follow")
.description("follow <did>")
.action(follow)
.flag(
Flag::new("follows", FlagType::Bool)
.alias("s"),
)
.flag(
Flag::new("delete", FlagType::String)
.alias("d"),
)
.flag(
Flag::new("followers", FlagType::Bool)
.alias("w"),
)
.flag(
Flag::new("all", FlagType::Bool)
.alias("a"),
)
.flag(
Flag::new("cursor", FlagType::String)
.alias("c"),
)
)
.command(
Command::new("profile")
.description("pro <handle>")
.alias("pro")
.action(profile)
)
.command(
Command::new("img-upload")
.description("img-upload <img>")
.action(img_upload)
)
.command(
Command::new("img-post")
.description("img-post <text> -l <link> -u <uri> -c <cid>")
.action(img_post)
.flag(
Flag::new("link", FlagType::String)
.alias("l"),
)
.flag(
Flag::new("uri", FlagType::String)
.alias("u"),
)
.flag(
Flag::new("cid", FlagType::String)
.alias("c"),
)
)
.command(
Command::new("openai")
.description("openai <text>")
.alias("chat")
.action(openai)
)
.command(
Command::new("openai-key")
.description("openai-key <API_KEY>")
.action(openai_key),
)
;
app.run(args);
}
fn ascii_art(c: &Context) {
if let Ok(t) = c.string_flag("type") {
c_ascii(&t);
} else {
c_ascii("color");
}
}
fn bot(c: &Context) {
refresh(c);
loop {
c_bot(c);
}
}
fn follow_all(_c: &Context) {
c_follow_all();
}
fn openai_key(c: &Context) {
c_openai_key(c);
}
fn token(c: &Context) {
let m = c.args[0].to_string();
let h = async {
if let Ok(p) = c.string_flag("password") {
if let Ok(s) = c.string_flag("server") {
let res = token::post_request(m.to_string(), p.to_string(), s.to_string()).await;
w_cfg(&s, &res, &p);
} else {
let res =
token::post_request(m.to_string(), p.to_string(), "bsky.social".to_string())
.await;
w_cfg(&"bsky.social", &res, &p);
}
}
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}
fn refresh(_c: &Context) {
let h = async {
let session = session::get_request().await;
if session == "err" {
let res = refresh::post_request().await;
println!("{}", res);
if res == "err" {
let m = data_toml(&"handle");
let p = data_toml(&"password");
let s = data_toml(&"host");
println!("handle:{}, pass:{}, host:{}", m, p, s);
let res = token::post_request(m.to_string(), p.to_string(), s.to_string()).await;
w_cfg(&s, &res, &p);
println!("res:{}", res);
} else {
w_refresh(&res);
}
}
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}
fn notify(c: &Context) {
refresh(c);
let h = async {
let j = notify::get_request(100).await;
println!("{}", j);
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}
fn did(c: &Context) {
refresh(c);
let h = async {
if c.args.len() == 0 {
let j = describe::get_request(data_toml(&"handle")).await;
println!("{}", j);
} else {
let j = describe::get_request(c.args[0].to_string()).await;
println!("{}", j);
}
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}
fn timeline(c: &Context) {
refresh(c);
let h = async {
if c.args.len() == 0 {
let str = timeline_author::get_request(data_toml(&"handle").to_string());
println!("{}", str.await);
} else {
let str = timeline_author::get_request(c.args[0].to_string());
println!("{}", str.await);
}
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}
fn post(c: &Context) {
refresh(c);
let m = c.args[0].to_string();
let h = async {
if let Ok(link) = c.string_flag("link") {
let e = link.chars().count();
let s = 0;
let str =
post_link::post_request(m.to_string(), link.to_string(), s, e.try_into().unwrap());
println!("{}", str.await);
} else {
let str = post::post_request(m.to_string());
println!("{}", str.await);
}
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}
fn like(c: &Context) {
refresh(c);
let m = c.args[0].to_string();
let h = async {
if let Ok(uri) = c.string_flag("uri") {
let str = like::post_request(m.to_string(), uri);
println!("{}", str.await);
}
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}
fn repost(c: &Context) {
refresh(c);
let m = c.args[0].to_string();
let h = async {
if let Ok(uri) = c.string_flag("uri") {
let str = repost::post_request(m.to_string(), uri);
println!("{}", str.await);
}
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}
fn follow(c: &Context) {
refresh(c);
let m = c.args[0].to_string();
let h = async {
let handle = data_toml(&"handle");
if let Ok(cursor) = c.string_flag("cursor") {
let str = follow::post_request(m.to_string());
println!("{}", str.await);
//let str = follow::delete_request(m.to_string(), delete.to_string());
//let str = followers::get_request(handle,Some("".to_string()));
//let str = followers::get_request(handle,Some(cursor.to_string()));
//let str = follows::get_request(handle,Some("".to_string()));
let str = follows::get_request(handle, Some(cursor.to_string()));
println!("{}", str.await);
}
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}
fn profile(c: &Context) {
refresh(c);
let h = async {
if c.args.len() == 0 {
let j = profile::get_request(data_toml(&"handle")).await;
println!("{}", j);
} else {
let j = profile::get_request(c.args[0].to_string()).await;
println!("{}", j);
}
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}
fn mention(c: &Context) {
refresh(c);
let m = c.args[0].to_string();
let h = async {
let str = profile::get_request(m.to_string()).await;
let profile: ProfileIdentityResolve = serde_json::from_str(&str).unwrap();
let udid = profile.did;
let handle = m.to_string();
let at = "@".to_owned() + &handle;
let e = at.chars().count();
let s = 0;
if let Ok(post) = c.string_flag("post") {
let str = mention::post_request(
post.to_string(),
at.to_string(),
udid.to_string(),
s,
e.try_into().unwrap(),
)
.await;
println!("{}", str);
}
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}
fn reply(c: &Context) {
refresh(c);
let m = c.args[0].to_string();
let h = async {
if let Ok(cid) = c.string_flag("cid") {
if let Ok(uri) = c.string_flag("uri") {
if let Ok(link) = c.string_flag("link") {
let s = 0;
let e = link.chars().count();
let str = reply_link::post_request(
m.to_string(),
link.to_string(),
s,
e.try_into().unwrap(),
cid.to_string(),
uri.to_string(),
cid.to_string(),
uri.to_string(),
)
.await;
println!("{}", str);
} else {
let str = reply::post_request(
m.to_string(),
cid.to_string(),
uri.to_string(),
cid.to_string(),
uri.to_string(),
)
.await;
println!("{}", str);
}
}
}
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}
#[tokio::main]
async fn c_img_upload(c: &Context) -> reqwest::Result<()> {
let token = data_refresh(&"access");
let atoken = "Authorization: Bearer ".to_owned() + &token;
let con = "Content-Type: image/png";
let url = url(&"upload_blob");
let f = "@".to_owned() + &c.args[0].to_string();
use std::process::Command;
let output = Command::new("curl")
.arg("-X")
.arg("POST")
.arg("-sL")
.arg("-H")
.arg(&con)
.arg("-H")
.arg(&atoken)
.arg("--data-binary")
.arg(&f)
.arg(&url)
.output()
.expect("curl");
let d = String::from_utf8_lossy(&output.stdout);
let d = d.to_string();
println!("{}", d);
Ok(())
}
fn img_upload(c: &Context) {
refresh(c);
c_img_upload(c).unwrap();
}
fn img_post(c: &Context) {
let m = c.args[0].to_string();
let link = c.string_flag("link").unwrap();
let cid = c.string_flag("cid").unwrap();
let uri = c.string_flag("uri").unwrap();
let h = async {
let itype = "image/png";
let str = img_reply::post_request(
m.to_string(),
link.to_string(),
cid.to_string(),
uri.to_string(),
itype.to_string(),
)
.await;
println!("{}", str);
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}
fn reply_og(c: &Context) {
refresh(c);
//let mut admin = "".to_string();
//if c.string_flag("admin").is_ok() {
// admin = c.string_flag("admin").unwrap();
//}
let m = c.args[0].to_string();
let link = c.string_flag("link").unwrap();
let cid = c.string_flag("cid").unwrap();
let uri = c.string_flag("uri").unwrap();
let title = c.string_flag("title").unwrap();
let desc = c.string_flag("description").unwrap();
let img = c.string_flag("img").unwrap();
let h = async {
let str = reply_og::post_request(m, link, cid, uri, img, title, desc);
println!("{}", str.await);
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}
fn openai(c: &Context) {
let m = c.args[0].to_string();
let h = async {
let str = openai::post_request(m.to_string()).await;
println!("{}", str);
};
let res = tokio::runtime::Runtime::new().unwrap().block_on(h);
return res;
}

57
src/mention.rs Normal file

@ -0,0 +1,57 @@
extern crate reqwest;
use crate::data_toml;
use crate::data_refresh;
use crate::url;
use iso8601_timestamp::Timestamp;
use serde_json::json;
pub async fn post_request(text: String, at: String, udid: String, s: i32, e: i32) -> String {
let token = data_refresh(&"access");
let did = data_toml(&"did");
let handle = data_toml(&"handle");
let url = url(&"record_create");
let col = "app.bsky.feed.post".to_string();
let d = Timestamp::now_utc();
let d = d.to_string();
let post = Some(json!({
"did": did.to_string(),
"repo": handle.to_string(),
"collection": col.to_string(),
"record": {
"text": at.to_string() + &" ".to_string() + &text.to_string(),
"$type": "app.bsky.feed.post",
"createdAt": d.to_string(),
"facets": [
{
"$type": "app.bsky.richtext.facet",
"index": {
"byteEnd": e,
"byteStart": s
},"features": [
{
"did": udid.to_string(),
"$type": "app.bsky.richtext.facet#mention"
}
]
}
]
},
}));
let client = reqwest::Client::new();
let res = client
.post(url)
.json(&post)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

30
src/notify.rs Normal file

@ -0,0 +1,30 @@
extern crate reqwest;
use crate::data_refresh;
use crate::url;
//use serde_json::json;
pub async fn get_request(limit: i32) -> String {
let token = data_refresh(&"access");
let url = url(&"notify_list");
let client = reqwest::Client::new();
let res = client
.get(url)
.query(&[("limit", limit)])
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap();
let status_ref = res.error_for_status_ref();
match status_ref {
Ok(_) => {
return res.text().await.unwrap();
}
Err(_e) => {
let e = "err".to_string();
return e;
}
}
}

27
src/notify_read.rs Normal file

@ -0,0 +1,27 @@
extern crate reqwest;
use crate::data_refresh;
use crate::url;
use serde_json::json;
pub async fn post_request(time: String) -> String {
let token = data_refresh(&"access");
let url = url(&"notify_update");
let post = Some(json!({
"seenAt": time.to_string(),
}));
let client = reqwest::Client::new();
let res = client
.post(url)
.json(&post)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

58
src/openai.rs Normal file

@ -0,0 +1,58 @@
extern crate reqwest;
use crate::data::Open;
use serde::{Deserialize, Serialize};
use serde_json::json;
#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "type")]
struct OpenChar {
choices: Vec<ChoicesChar>,
}
#[derive(Serialize, Deserialize, Debug)]
struct ChoicesChar {
message: OpenContent,
}
#[derive(Serialize, Deserialize, Debug)]
struct OpenContent {
content: String,
}
pub async fn post_request(prompt: String) -> String {
let data = Open::new().unwrap();
let data = Open { api: data.api };
let setting = "あなたはyuiという作品のアイと呼ばれるキャラクターです。第一人称は「アイ」です。
調
調
123
";
let post = Some(json!({
"model": "gpt-3.5-turbo",
"messages": [
{"role": "system", "content": &setting.to_string()},
{"role": "user", "content": &prompt.to_string()},
]
}));
let client = reqwest::Client::new();
let res = client
.post("https://api.openai.com/v1/chat/completions")
.header("Authorization", "Bearer ".to_owned() + &data.api)
.json(&post)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
let p: OpenChar = serde_json::from_str(&res).unwrap();
let o = &p.choices[0].message.content;
return o.to_string();
}

42
src/post.rs Normal file

@ -0,0 +1,42 @@
extern crate reqwest;
use crate::data_toml;
use crate::data_refresh;
use crate::url;
use iso8601_timestamp::Timestamp;
use serde_json::json;
pub async fn post_request(text: String) -> String {
let token = data_refresh(&"access");
let did = data_toml(&"did");
let handle = data_toml(&"handle");
let url = url(&"record_create");
let col = "app.bsky.feed.post".to_string();
let d = Timestamp::now_utc();
let d = d.to_string();
let post = Some(json!({
"repo": handle.to_string(),
"did": did.to_string(),
"collection": col.to_string(),
"record": {
"text": text.to_string(),
"createdAt": d.to_string(),
},
}));
let client = reqwest::Client::new();
let res = client
.post(url)
.json(&post)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

56
src/post_link.rs Normal file

@ -0,0 +1,56 @@
extern crate reqwest;
use crate::data_toml;
use crate::data_refresh;
use crate::url;
use iso8601_timestamp::Timestamp;
use serde_json::json;
pub async fn post_request(text: String, link: String, s: i32, e: i32) -> String {
let token = data_refresh(&"access");
let did = data_toml(&"did");
let handle = data_toml(&"handle");
let url = url(&"record_create");
let col = "app.bsky.feed.post".to_string();
let d = Timestamp::now_utc();
let d = d.to_string();
let post = Some(json!({
"repo": handle.to_string(),
"did": did.to_string(),
"collection": col.to_string(),
"record": {
"text": link.to_string() + &" ".to_string() + &text.to_string(),
"createdAt": d.to_string(),
"facets": [
{
"index": {
"byteStart": s,
"byteEnd": e
},
"features": [
{
"$type": "app.bsky.richtext.facet#link",
"uri": link.to_string()
}
]
}
],
},
}));
let client = reqwest::Client::new();
let res = client
.post(url)
.json(&post)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

21
src/profile.rs Normal file

@ -0,0 +1,21 @@
extern crate reqwest;
use crate::data_refresh;
use crate::url;
pub async fn get_request(user: String) -> String {
let token = data_refresh(&"access");
let url = url(&"profile_get") + &"?handle=" + &user;
let client = reqwest::Client::new();
let res = client
.get(url)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

28
src/refresh.rs Normal file

@ -0,0 +1,28 @@
extern crate reqwest;
use crate::data_toml;
use crate::url;
pub async fn post_request() -> String {
let refresh = data_toml(&"refresh");
let url = url(&"session_refresh");
let client = reqwest::Client::new();
let res = client
.post(url)
.header("Authorization", "Bearer ".to_owned() + &refresh)
.send()
.await
.unwrap();
let status_ref = res.error_for_status_ref();
match status_ref {
Ok(_) => {
return res.text().await.unwrap();
}
Err(_e) => {
let e = "err".to_string();
return e;
}
}
}

59
src/reply.rs Normal file

@ -0,0 +1,59 @@
extern crate reqwest;
use crate::data_toml;
use crate::data_refresh;
use crate::url;
use iso8601_timestamp::Timestamp;
use serde_json::json;
pub async fn post_request(
text: String,
cid: String,
uri: String,
cid_root: String,
uri_root: String,
) -> String {
let token = data_refresh(&"access");
let did = data_toml(&"did");
let handle = data_toml(&"handle");
let url = url(&"record_create");
//let url = "https://bsky.social/xrpc/com.atproto.repo.createRecord";
let col = "app.bsky.feed.post".to_string();
let d = Timestamp::now_utc();
let d = d.to_string();
let post = Some(json!({
"repo": handle.to_string(),
"did": did.to_string(),
"collection": col.to_string(),
"record": {
"text": text.to_string(),
"createdAt": d.to_string(),
"reply": {
"root": {
"cid": cid_root.to_string(),
"uri": uri_root.to_string()
},
"parent": {
"cid": cid.to_string(),
"uri": uri.to_string()
}
}
},
}));
let client = reqwest::Client::new();
let res = client
.post(url)
.json(&post)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

75
src/reply_link.rs Normal file

@ -0,0 +1,75 @@
extern crate reqwest;
use crate::data_toml;
use crate::data_refresh;
use crate::url;
use iso8601_timestamp::Timestamp;
use serde_json::json;
pub async fn post_request(
text: String,
link: String,
s: i32,
e: i32,
cid: String,
uri: String,
cid_root: String,
uri_root: String,
) -> String {
let token = data_refresh(&"access");
let did = data_toml(&"did");
let handle = data_toml(&"handle");
let url = url(&"record_create");
let col = "app.bsky.feed.post".to_string();
let d = Timestamp::now_utc();
let d = d.to_string();
let post = Some(json!({
"repo": handle.to_string(),
"did": did.to_string(),
"collection": col.to_string(),
"record": {
"text": link.to_string() + &" ".to_string() + &text.to_string(),
"createdAt": d.to_string(),
"reply": {
"root": {
"cid": cid_root.to_string(),
"uri": uri_root.to_string()
},
"parent": {
"cid": cid.to_string(),
"uri": uri.to_string()
}
},
"facets": [
{
"index": {
"byteStart": s,
"byteEnd": e
},
"features": [
{
"$type": "app.bsky.richtext.facet#link",
"uri": link.to_string()
}
]
}
],
},
}));
let client = reqwest::Client::new();
let res = client
.post(url)
.json(&post)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

76
src/reply_og.rs Normal file

@ -0,0 +1,76 @@
extern crate reqwest;
use crate::data_toml;
use crate::data_refresh;
use crate::url;
use iso8601_timestamp::Timestamp;
use serde_json::json;
pub async fn post_request(
m: String,
link: String,
cid: String,
uri: String,
img: String,
title: String,
description: String,
) -> String {
let token = data_refresh(&"access");
let did = data_toml(&"did");
let handle = data_toml(&"handle");
let url = url(&"record_create");
let col = "app.bsky.feed.post".to_string();
let d = Timestamp::now_utc();
let d = d.to_string();
let post = Some(json!({
"repo": handle.to_string(),
"did": did.to_string(),
"collection": col.to_string(),
"record": {
"createdAt": d.to_string(),
"text": m.to_string(),
"embed": {
"$type": "app.bsky.embed.external",
"external": {
"uri": link.to_string(),
"thumb": {
"$type": "blob",
"ref": {
"$link": img.to_string()
},
"mimeType": "image/jpeg",
"size": 0
},
"title": title.to_string(),
"description": description.to_string()
}
},
"reply": {
"root": {
"cid": cid.to_string(),
"uri": uri.to_string()
},
"parent": {
"cid": cid.to_string(),
"uri": uri.to_string()
}
}
}
}));
let client = reqwest::Client::new();
let res = client
.post(url)
.json(&post)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

45
src/repost.rs Normal file

@ -0,0 +1,45 @@
extern crate reqwest;
use crate::data_toml;
use crate::data_refresh;
use crate::url;
use iso8601_timestamp::Timestamp;
use serde_json::json;
pub async fn post_request(cid: String, uri: String) -> String {
let token = data_refresh(&"access");
let did = data_toml(&"did");
let handle = data_toml(&"handle");
let url = url(&"record_create");
let col = "app.bsky.feed.repost".to_string();
let d = Timestamp::now_utc();
let d = d.to_string();
let post = Some(json!({
"repo": handle.to_string(),
"did": did.to_string(),
"collection": col.to_string(),
"record": {
"subject": {
"uri": uri.to_string(),
"cid": cid.to_string()
},
"createdAt": d.to_string(),
},
}));
let client = reqwest::Client::new();
let res = client
.post(url)
.json(&post)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

28
src/session.rs Normal file

@ -0,0 +1,28 @@
extern crate reqwest;
use crate::data_refresh;
use crate::url;
pub async fn get_request() -> String {
let token = data_refresh(&"access");
let url = url(&"session_get");
let client = reqwest::Client::new();
let res = client
.get(url)
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap();
let status_ref = res.error_for_status_ref();
match status_ref {
Ok(_) => {
return res.text().await.unwrap();
}
Err(_e) => {
let e = "err".to_string();
return e;
}
}
}

27
src/timeline_author.rs Normal file

@ -0,0 +1,27 @@
extern crate reqwest;
use crate::data_refresh;
use crate::url;
pub async fn get_request(actor: String) -> String {
let token = data_refresh(&"access");
let url = url(&"record_list");
let actor = actor.to_string();
//let cursor = cursor.unwrap();
let col = "app.bsky.feed.post".to_string();
let client = reqwest::Client::new();
let res = client
.get(url)
.query(&[("repo", actor), ("collection", col)])
//.query(&[("actor", actor),("cursor", cursor)])
.header("Authorization", "Bearer ".to_owned() + &token)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

25
src/token.rs Normal file

@ -0,0 +1,25 @@
extern crate reqwest;
use std::collections::HashMap;
pub async fn post_request(handle: String, pass: String, host: String) -> String {
let url = "https://".to_owned()
+ &host.to_string()
+ &"/xrpc/com.atproto.server.createSession".to_string();
let mut map = HashMap::new();
map.insert("identifier", &handle);
map.insert("password", &pass);
let client = reqwest::Client::new();
let res = client
.post(url)
.json(&map)
.send()
.await
.unwrap()
.text()
.await
.unwrap();
return res;
}

35
test/ai.zsh Executable file

@ -0,0 +1,35 @@
#!/bin/zsh
# https://www.docs.bsky.app/docs/get-started
case $OSTYPE in
darwin*)
alias date="/opt/homebrew/bin/gdate"
;;
esac
d=${0:a:h}
source $d/env
source $d/refresh.zsh
source $d/token.zsh
source $d/reply.zsh
source $d/notify.zsh
source $d/cron.zsh
case $1 in
refresh|r)
refresh
;;
token|t)
token
;;
reply|rep)
reply
;;
notify|n)
notify
;;
cron|c)
cron
;;
esac

7
test/cron.zsh Normal file

@ -0,0 +1,7 @@
function cron() {
t=`docker ps |grep "ai bot"`
if [ -z "$t" ];then
docker compose up -d
fi
exit
}

3
test/entrypoint.sh Normal file

@ -0,0 +1,3 @@
#!/bin/bash
exec "$@"

18
test/env Normal file

@ -0,0 +1,18 @@
cfg=~/.config/ai/test.json
if [ -f $cfg ];then
host=`cat $cfg|jq -r .host`
handle=`cat $cfg|jq -r .handle`
pass=`cat $cfg|jq -r .password`
date=`date --iso-8601=seconds`
fi
if [ -f $cfg.t ];then
token=`cat $cfg.t|jq -r .accessJwt`
refresh=`cat $cfg.t|jq -r .refreshJwt`
did=`cat $cfg.t|jq -r .did`
fi
if [ ! -d $d/json ];then
mkdir -p $d/json
fi

37
test/notify.zsh Normal file

@ -0,0 +1,37 @@
function notify() {
url=https://$host/xrpc/app.bsky.notification.listNotifications
f=$d/json/notify.json
if [ ! -f $f ];then
curl -sL "Content-Type: application/json" -H "Authorization: Bearer $token" "$url?limit=100" >! $f
fi
for ((i=0;i<=99;i++))
do
echo "[$i]---"
cid=`cat $f|jq -r ".|.[].[$i]?|.cid?"`
uri=`cat $f|jq -r ".|.[].[$i]?|.uri?"`
echo cid: $cid
echo uri: $uri
cid_r=`cat $f|jq -r ".[]|.[$i]?|.record.reply.root.cid?"`
if [ "$cid_r" = "null" ];then
continue
fi
uri_r=`cat $f|jq -r ".[]|.[$i]?|.record.reply.root.uri?"`
cid_p=`cat $f|jq -r ".[]|.[$i]?|.record.reply.parent.cid?"`
uri_p=`cat $f|jq -r ".[]|.[$i]?|.record.reply.parent.uri?"`
did_p=`echo $uri_p|cut -d / -f 3`
if [ "$did_p" != "did:plc:uqzpqmrjnptsxezjx4xuh2mn" ];then
continue
fi
echo cid_root: $cid_r
echo uri_root: $uri_r
echo cid_parent: $cid_p
echo uri_parent: $uri_p
echo ---
echo uri: $uri|sed "s#at://#https://bsky.app/profile/#g"|sed 's/app.bsky.feed.post/post/g'
echo uri_root: $uri_r|sed "s#at://#https://bsky.app/profile/#g"|sed 's/app.bsky.feed.post/post/g'
echo uri_parent: $uri_p|sed "s#at://#https://bsky.app/profile/#g"|sed 's/app.bsky.feed.post/post/g'
echo ---
done
}

11
test/refresh.zsh Executable file

@ -0,0 +1,11 @@
function refresh(){
token=`cat $cfg.t|jq -r .accessJwt`
refresh=`cat $cfg.t|jq -r .refreshJwt`
if [ ! -f $cfg ];then
token
fi
url=https://$host/xrpc/com.atproto.server.refreshSession
j=`curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $refresh" $url`
echo $j
echo $j >! $cfg.t
}

40
test/reply.zsh Executable file

@ -0,0 +1,40 @@
function reply() {
#uri: https://bsky.app/profile/did:plc:4hqjfn7m6n5hno3doamuhgef/post/3kkumyv72w22o
#uri_root: https://bsky.app/profile/did:plc:uqzpqmrjnptsxezjx4xuh2mn/post/3kkumysfipk2p
#uri_parent: https://bsky.app/profile/did:plc:uqzpqmrjnptsxezjx4xuh2mn/post/3kkumysfipk2p
cid=bafyreiaxz6hbqgylsxglqita73c5gzxzoatupgitd35rwjpd6dzpa4ctwi
uri=at://did:plc:4hqjfn7m6n5hno3doamuhgef/app.bsky.feed.post/3kkumyv72w22o
cid_root=bafyreiacxuk4ypaxbg7qxnmrvpnaej5o7azewqioelfgbuikp77jevy6hq
uri_root=at://did:plc:uqzpqmrjnptsxezjx4xuh2mn/app.bsky.feed.post/3kkumysfipk2p
cid_parent=bafyreiacxuk4ypaxbg7qxnmrvpnaej5o7azewqioelfgbuikp77jevy6hq
uri_parent=at://did:plc:uqzpqmrjnptsxezjx4xuh2mn/app.bsky.feed.post/3kkumysfipk2p
url="https://$host/xrpc/com.atproto.repo.createRecord"
col="app.bsky.feed.post"
json="{
\"repo\": \"$handle\",
\"did\": \"$did\",
\"collection\": \"$col\",
\"record\": {
\"text\": \"$text\",
\"createdAt\": \"$date\",
\"reply\": {
\"root\": {
\"cid\": \"$cid_root\",
\"uri\": \"$uri_root\"
},
\"parent\": {
\"cid\": \"$cid\",
\"uri\": \"$uri\"
}
}
}
}"
echo $json|jq .
url=https://$host/xrpc/com.atproto.repo.createRecord
curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d "$json" $url
}

18
test/token.zsh Executable file

@ -0,0 +1,18 @@
function token() {
mkdir -p ~/.config/ai
echo server:
read host
echo password:
read pass
echo handle:
read handle
echo "{ \"host\":\"$host\", \"password\":\"$pass\", \"handle\":\"$handle\" }" >> $cfg
url=https://$host/xrpc/com.atproto.server.createSession
j=`curl -sL -X POST -H "Content-Type: application/json" -d "{\"identifier\":\"$handle\",\"password\":\"$pass\"}" $url`
echo $j
echo $j >! $cfg.t
}