p>YNcrxGyjV3QePa$0rv9`_aXdoCa9wFLDYLxU>v#
z!`R+e|5)wwCi3=0C!B4hf6#1`z$~zT^5*4d#wr>#PX@ve=OV*EnxP5U`DD$#SD>}P
z(QQG{0$m2{Iz+1s;7ER#M)B_rYsv_ML$+Ki&r-Y;RLW^ODeIrF835nlk1
z1fPq*Qk*#WBj8aqASyulrIyZ9emV357q-SO&GX^Pw|(Wu0kJy_v&DBmv-C_O{aGV<
z+pHFhO?`dEih$q};^Sb<>T1jwH#VP>TmQTV4-jqMTm@=vi;w?;evt2v?Nzytma|sc
zp%(aN6PgAZ^{0)*<0jF?&Czf=RA<|SnXy-tH;!5`uLr$W2)5ACd+MJ?#`JEHLq-)b
zz!Hq_^6&_?IN<@~u8U7xhW7iDB@6&9l^U?5`>q#W4*)IJ0DF!i)9}o*cwQp!y5MMF
z+}8AKp$Zo#IGL-{*Hp>ivmK{_*+`~-^V4-?z$bHLhrB)r?4SPTsP>aU_trqwS6D3tVFK+q$4xpLJ
z9aE;aRGTYl6?EXzZF;AfJDhiobu`W#04D8&DqcU_7nuqz?ZbL$={5TjwnFwY_HbHo
zzBs8mQg3ndj{ET2k$eU3&SxKL-QkhY0BO4A@{!a4d%iaArxHG7NJvOP=B
zedqu!l&1@b?`i+?#tHo#eQ-^nIiIxO;WNg}$?zV%$IxchM5@3
z^feya&ng?I-dZp=+5`hMC`?8z0XnN!KXzO8J$@&;7ObTO_oZgttZmM5eGC921%8JoFOdgEwMu$JF<^2+;npks|@Z*ARs$V%5SHwvSTL9a*GXpW+L()>K8
zCSe1iK459@Wq%wB?B3e5^1vqQV)*gv(c$?FULa)S?j-{k{`U1EVvy3f$C$82E;3@2QoOO{
zO9Q|Jd9Tn0^!0rHnSEM<5sC+{PLe3xp4?i2`@`I`<%KIxLlkQqJOo40Tf@{cP;wg?j47)`Qr1!uKktF23nnvVUVqfUe$a
z*6+!*Ou1OZm#Py?fwc2$Sqvaj$r~?!ZiOd(2f}gcYs=H4Nt%{|8?ntd0KV)V6Rk-}
zk2vlw;OA&C1gJTCHef}OeS3E9dx1DA%mbuS=wjuj(sUYNG2ltfsDC8goSzSf&ae6N<6}?X2<)Y#Bv%%dCFuD5
z#8WKNg%rv-9q;tr0hI%^A%u%&0@p9m&JYb7KEzCWd
z0pzQj*Q`R@erY+rtp4ZRA}|`LT7!ts21yzpd`z$aCy{CvDW|BX6U=<#2B+SEy{lOI
zAqF7xk)IBB!f27~J!EMr-Y7e>S}^|RYhPTIB_5uXqhu)YG{vs@X|qb_NbA$gr{hd6
zTh%0}@lxO*pvl~1yp~umkSbo;a`ly2ZUoJuS6!Q5q)u`%;vgp)Mzw
zRr{Gc?JSd@=iOMoxM4NRONL|ywmFd0XCG-M{bm|qwO}3?-@N^+X9P6>H;#K$D{$&L
zPpW39Gs(oIHY>wpNG7
zS?C)VKb*IyXSOfXS?X$vS;m>V_-n=J-XN3>=B4!Jl`C_3ZG_g|L$=HS%Y<2A|H~ua
zI44&&OO;M`;*wgbE96qlGS3vVOgQuolNmylE>r*9eG1{K`!KY1?b&GHbJlP=0k;KO04GJRqU7SQR#~f1}WSoN+-QrZcQRo`a=R)FCYQj~H#y#eYE&qaSp)VLJ
z=>NZ6a!%K6|I+pyg}dI@rpzdb
z`nOzyU+8-_iFPd`&&}MnA}c=|9~_)ZkupbJOdHiNQ}2Qtzckk`A|8geUh`qJ?H7i-
zjoM-TZV)&Y82A|9+7NF_#T>ItFvC8^FIX2zQ8O#A=4FYEF}H~Jp{;8_jxKUo)nD-M
z1`p?#qiyJfsRv!`^j}^7H-ATL@n{zFiW@EY_w1LW{=N34YL)Eu^?UInYKbOz-dx}F
i-wqc&Ta}Mbhkrmt7t2&f`W}Q$WxSA!w^77kpVN3kVKuQzVWfShUCoG@ykL=4kr;lOW_)9O9TzO@*Iy~Hr_xO?rc`<{R5u6KTM(UN3!=guy>T>ccU
zdkzf^%J}|0CYk(s)c1S%(1*$Z|6lolhc*wGjXe)1zj)pC9$>{iZ+C5Y_-j@W{4A6*
z6m#YbE6>|awOT)x{{Kr`z$4p7%z4MR2sq#jB_Md{p$M+)0FcXhw6+E;U#{TjW*`2O
zE#RK}e)F#0y`$;QIjPmrh_lG^!>v2^=I^y)iNZBkTzL1?XCK^>+xyVH-@ACSEQBz|
z7!APr=huMR{wg!|nWNR|KWqVC`Oz8vb(cTwzEb@Ue)6ju7cXr6%wTTxAG9(3C{;AZ
z1V$Pojg&?jS6Eg8Ma%4&Gj7O^`>g)6GsG?TKV`01`IaNC`?0?D^3hC7=mjBV0=rIlO`J1~<&5O~TsW4VZ6Pg+`Tccd_p2q~hH*UWB
znt5}Q&7tRQkVfW>g%^fG38}P{QUf?Z0Bm^h{&kC%uQ*-0QWVDuze{H_G*6$w=+N*-
z=g*z)QQ6_7qUa~3F!4{1@W-MK|
zjU7g#DShF}m3q~xRc6(yRi>e(%`9wdf`)&%Vr+D`>u5l?8x%-9eYtyY2RY06AC{R
zVNEH2I0(F_T2h?-?c48b{EvXm=KIa_+qar~fAhq_$Z;$k-FV9a6MDmBnwoGef8|Ht
zHShqyuOEK+8l&~|)Q74o=Cwa392e{e7z1H|@k7>(h{fkGG8+*B&>$R)U&DBH{^85_
z(zW6pi=~tT9Kwhcjxm;2DjKn@=4sQXfBy7k%a$IC&ZCumW@u;>OGx>O+Al?H5X
zzI`oMz4r_d7Dk1bz{hwMO5@|-eQZz5cK|F)%TNegK-_ks^NOLYz5jyqetNh*8@6mV
zj%`yamR7v^w9|e&weHbv|7?z%aS6|EyM?N{i?shw6p97XnWkgk4SEj*mrX6l;*myM
z%9@l)cSpsO#;aqhWmJ9uHQbBJ524F>lvgAiDPpw6mG3(Tq{BO}_!0<#upLAsPD5kk
z)vLQI8ypAJMAT3=wr7OSbVsV|Za=1u{lZ1$#eM7<3s|%5
z?@1+XQVsIh3HZdFwL@m1SgiZCdO`2qx82l7vUnp|{Mn+Jn6NxbSS=D(N{l?b
z7EBCG1fvA^{op!K1`~!8ok<6z#rg9J8yp}Njq0Z9vCzV<=Ee(Oo*Z-AoU;!cwt%9(XrcN>5mLxN%%N^dvLWHR_O6*r?;PzL
zCfD0XVP8MRJ^QF+`=||%;EfmXRfwq!VCs2HP@NznD1lZO9e~!Dpo%a7(sqgYyPLJv
zrkEcxP*$xJ1$kw`{uWw+W7E2&!>DJ%aS;bgY8&^
z^*YDD|6EK^0z$BD5H4s9BG_*MH83EXyD(}C-I0Bd4BqoY@TzQo`(J(L@NrYA^fe3P
z3D)+U!JN5WB$8?J`8+|W4?Od=>|-~2-(2`Ir+-WqkoS(vn_sWbDhk;gS31%VV3ptY
zu2UDDH=Uu;aq{^BqeFR)zw}KLvmMqjT4MqQet9AS_*G00f^RU|M&))ge)kV>-H`PB
zX3~p}LpDuM9X_t*Saih~bJm+aL)3Q9jYi{4pV3aNp#^}3>-PLOQOX`s=c5jT-l;9-
z=Q&xvY~S$96ajc{?PD+W?cMiz-;z0ppk`?qzQwHVagq&K@d(0+A)GiuN^o2R8l;WE
z0UcmMg$Y9JbOZZ-{BN{h`saj|GUaU>d9rEcg^6UtPgcHT^&w+ddgE<_Jqz0xT)g4A
z$$MLS2hE8cGXy~D+TEt~)pE
z@w*W>$_BBFzbLFFo_0`y!p
zaPR=}M74jx#TyO*cmVvTvn8+Qy&|5YCO|Z1_{8AY{gdT~T2iK}4Vyg8F0FW=Ice%&
zxRw_$xcs|oH*bS@BcWem)2w#pO-pm_@dNl3jir2KB#QO~(gJjdj3h9|AgmbZ8gt)!
zF~zlONS}BDYg;b7d|u4C0rAWGY_`3L%PIe|KkG2@}vChj_(nPbTYVmm_%a((M%G{DIx3#!U&8388VR}`*}np
zhEV~(J>klgAZIp8`J*K(E_%5cJA5IxUOX}7#n2%ljl%URywVH9qavWZxb;C@IFx|0
znF!|=6UvV(*s-&~1z-AemUL&?`uiSYQNhyFR&es-;~6`3G3}=;<&N9F!%N$D5(XZh
znm@+GwF+q>uc9q-ok!765-yD2pGblcwE)q7l^N2Co+I>%0Diz>g4yn)HG$
zOzk-y_~naiSa%<`EwF?_;m|s*i@Rz~6b8q5+rp*a6zwTp+_Ui_ciPz<*|BwV-h0L8
zt~*>8vkyZYPznO5J|j*1&H7~oDZ>hZL5JbjUkTT1iUQuECZii$p|J%9b`$1Dse2)<
zd(|QBKb=UJWE{4g(#_cyNz#ds((n)}G(;n?ZI|ZBZ7$KKg|y7D34BA;RjAM>E^3??
zZ{z1{pJK)dEi1oq+w%_`u1C0zD^I*)+0C2opF=cx57Z*uw&r#&TXrqG9?gB|gpXE!
zIQi_nYq!kJ%Xn{~4RW;a@$xNao^wnDj4hdYk?T13%8uiaohK4L`v|IcD_#hXr;fYw
z;@@xo{*l_W6#i9=)&Pj_F;zlE6*ECX@
zHH*^d?L?e_7k16$!yo>~Lv#$kBaF4uKwN@`J~Kor`yNsqYw&&w=MFu@M*jp{p{dt{
z3C|GJso!+c5wZS30&=638)EUu--$Elq2o6@un%WSo$ao((7?bS|6+#^WP@TV~PS
z-{Nz_B?;j7$ZuLP{c#xw4CoNNeIRy9UQC|MSugyWr45p_16#%w**Yi{;Cf}s-(GZd
znc$w?TfbEM*u^NNAReb$tucG{Y$~NP6)DJ6hF=Xk0N1?Z1)ka3#fc}+V*R=v+UL(>
zWGKtnaF%khK)EoC4l7hEBV_lyL^NWECzGTarxS@qNLlcgiG&7>+pYgn`=INfYv2t`
z`2Xltic{XZk!A-{Hnb!xW;i}c2ZRt9X_2|&x0$0N;Iz|DtBPkH##I%9J)1B~l2lJh
z9oQxWJ2G}u1OVhlJbH)Ac=bBvx}c_*Fukf_S-<+ktF>36Nj$8LQ+wz7@
zDmd7wEzqH$)W`J=D-nR%y1QRAeR4Zv^^mROKHCZbfres!fY3mo4WW2>&=aq4ZKmFP
zVTPrRhW*=X3~=I*deybxxBKr-ShwoNttWr!oytGZ}8(GZGuHC-skX_L$txakJ)qetS^+0(SHiiesB-nsp*gv+9(`2dNasD34cYn==>7Eif`RNG>{rtq*Kr
z#ZBYYWgm=3zX0g#@2Fgoxq!Q_7><~DvkQSHu{e~$Mod`eXSh5(>jxSWYP6J?$!?4R
zVIeToZeP`RxY9>j0^&$uGL22N&7H%D5Uk2mn)2M?R&+>tbYOsb@mU%g=VEjSOedL{
z!}Qq;Xq&r$THU69u!b@r^RG%Xs5Ddh5VuzAe+!7r1>6mYdJv^t5cvMY$6;qNGWI4e
z3qqc#h5J=D6TpoMF&G2}yF9vlDxOI>q6IwJ#EA*%Zdy9xy8xw=n!|AVY-ntzb9e{{
zrxJH~5B&@&sMZ-xai
z13iX`<8PBnOIwtXdh$lM4Luq#4a;~D7FkO_^egpIe+{2VegKR{V6ehkSpM;fCyt=w
zkqJ06&sOjqK>V!HJrV6eB!({J8AuBNamVz?_REI6a;;iGpqmYJ!fc
zY^}uY!ti#c&o{iVBl2!qqS4sfe|KK(v1=Z{ju?7}^=3JpPbA(4p^pxI!e_6HcmT_n
zOV+d+xYJCXv_BLD1i+=F7}t5UtIFj
zOMm&nJAf2m<0dooztoQ~it*7pJGS@p!VCLoi0;NxB_foVK08isDB#bQY@#s~P)S=8
zeFN=jD?=t)OE<^f^KVP$4h=+qdGXgyeXcpG8xoIy>UVFs^53gTTcuJ9r!~YgO*E#{
z5Q$;?6__$8U@V-GD$D&*@?A%_a
zsl`TGlHvo8Ls;8CIW88H!i+DkTNM<9S`C`Wc_XLnQg87?y!H>
zmvb|sf|O$+jlqtk0)RH@7}%*JANWGRVN3RvoY?+*-6FSO{WyrYk`{I0kVSB2^^|yr
z9WemCy;;-I(Jp%Fr9EsD7p$6H1wk0r!DyCrcCzZCBK0te@A;^pM!7W3*;kD=W0Xh%
z|8h-vM4FITGQ#v(8ScA&H($xkO1DMAaA2S(faQknlAutKl;U<{!m)K2lLdV+6sM(S
zc=xUOuC&FV4}--zqFUg%S*`3I^Q&GM#J%sFGHLM#NU#qAzeMa`9|F1sodroaDq71Y
zPum&UQmzO=XhB{9$``!=*#Xnu-X?o{dkt;PG8;zZ9gpnFoPC@>9*H;v+F_%x5&z!F
zS*!O_Dp}Z(6c>N|#f2@7-KwN;jKrQkzvEfQR8Nn_T%yr9H{;DuH0bz1(XK+Lf;EcN
za>M?25o1x;qNpZ7PXds(u`G#=!4JWwF4#GhJU+J4`9b&BtKq%%znW?#ZvdLobB){N9e
zO0_^JOoLQ9VvMW^A$DQRQ%cLH5Nwu04F}TFfwB`V(Z&YGEf+d1YBe!1P*54Wrb$9c
zRt=;`872H6WTfoVU-qc@0fY(@pShauZdktjNPg~c3+S|IOIvuhO)H#TtVqq)nZrWOclQmU%0L{$q@4}D#?>}V*g;9xo^q#3E``t+uX7b`ZY-rinl
zi8$%FYYW+Ij1Glb{q3LEN~Lpb*8%Auq>b=}cmp?Z-;7
zcs<$>8WYpDhziTZ1*9xvon$a)A;c^&X^f}{%;y4hHWI4wvZQ9=dUjX}oOmY8*?B|Q
zBp41vCh1t?p(oSQGKFd`#7Qc2AevG!%ji(}D{mdw^-5kF(ZpDGBKxwU2rG#+4%XVg
zZm}aO9IFv9P*AW_Gm)GeAVD1R>+Y8Hj9N@@uuv(PZWDH4ObLt;-Fi=q78t_G1TiOa5qSi<*6q$yY6tZN-#%35C&07_CG>#bol-D^51Qzjd35
zhSC&mix|*$`94}tA_nM6_LJkAZ~9S7LI%-_4zt;(Lm)hyfGOAekEV5(1htyzs7{l;
zp(juiaUaVy?Lan~)9gHswzgr*OW1ZGW3ExYjM~E1p=D_uN{ki=X@n4_E_{QKCN8D%
zln89)`s1~Hz)(>^T*DUV>Vhp>40MT(j%l*DmbVCER%0d-!s;fKv>aWohpI86!m(0HbtDLTn@ftGo&$d1m0pOv7CGoQ
zYPAV#=mKIfLr)KMcOQJRr{^%Bli&|n+L3mY2d|ee7pz$`FdLsG|bXi82fI9Y5paOYHzQ{`CC^zPSdxjd}@DKgc1
z?&N?kJ0LIL2~O$w4-NWSl{=!m65!WL#A}@(^D6a6JMJ6uhP)yFP2~Rq/dev/null #kill secondary list writer
wait $write_list_pid
@@ -497,11 +500,69 @@ Done.
${DIRECTORY}/icons/none-1.png
" > "${DIRECTORY}/data/manage-daemon/yadlist"
- #all actions have been completed. Daemon has effectively stopped listening, so remove its pid file
- rm -f "${DIRECTORY}/data/manage-daemon/pid"
-
#close the queue-viewer window in a few seconds
(sleep 5; kill $yadpid 2>/dev/null) &
+
+ #display "all done" window where the queue was
+ export -f summary_window
+ setsid bash -c summary_window
+ }
+
+ summary_window() { #given $queue, summarize what was done
+ export botspot_message='to Botspot (college student, Pi-Apps founder, kicked out, needs money)'
+ export gman_message='to theofficialgman (notable Pi-Apps contributor)'
+ summary_window_click_function() {
+ if [ "$5" == "$botspot_message" ];then
+ xdg-open 'https://github.com/sponsors/botspot'
+ elif [ "$5" == "$gman_message" ];then
+ xdg-open 'https://github.com/sponsors/theofficialgman'
+ fi
+ }
+ export -f summary_window_click_function
+
+ (for line in $queue ;do
+ action="$(echo "$line" | awk -F';' '{print $1}')"
+ app="$(echo "$line" | awk -F';' '{print $2}')"
+ status="$(echo "$line" | awk -F';' '{print $3}')"
+
+ if [ "$action" == update-file ] || [ "$action" == refresh ];then
+ continue #avoid flooding the summary window with less important completed actions
+ fi
+
+ if [ "$status" == 0 ];then
+ #if status is 0, then action completed successfully.
+ echo "${DIRECTORY}/icons/success.png
+${DIRECTORY}/icons/$action.png
+$(echo "${action^}ed" | sed 's/Updateed/Updated/g')
+${DIRECTORY}/apps/$app/icon-64.png
+$app"
+ else
+ #if status is 1, then action completed unsuccessfully.
+ echo "${DIRECTORY}/icons/failure.png
+${DIRECTORY}/icons/$action.png
+Failed to $action
+${DIRECTORY}/apps/$app/icon-64.png
+$app"
+ fi
+ done
+ #display donate message at the end
+ echo "${DIRECTORY}/icons/none-24.png
+${DIRECTORY}/icons/none-24.png
+Donate
+${DIRECTORY}/icons/botspot.png
+$botspot_message
+${DIRECTORY}/icons/none-24.png
+${DIRECTORY}/icons/none-24.png
+Donate
+${DIRECTORY}/icons/theofficialgman.png
+$gman_message"
+ ) | yad --class Pi-Apps --name "Pi-Apps" --width=330 --height=400 "$geometry2" --title='Actions complete' \
+ --list --tail --no-headers --column=:IMG --column=:IMG --column=Text --column=:IMG --column=Text \
+ --wrap-width=190 --wrap-cols=5 --close-on-unfocus \
+ --separator='\n' --window-icon="${DIRECTORY}/icons/logo.png" \
+ --text="Thank you for using Pi-Apps! The following apps completed:" \
+ --dclick-action=true --select-action="bash -c "\""summary_window_click_function %s"\""" \
+ --button=' Close '!"${DIRECTORY}/icons/exit.png":0 >/dev/null &
}
if [ "$2" == source ];then
@@ -565,14 +626,15 @@ ${DIRECTORY}/icons/none-1.png
tail -f --retry "${DIRECTORY}/data/manage-daemon/yadlist" 2>/dev/null | yad --class Pi-Apps --name "Pi-Apps" --width=330 --height=400 "$geometry2" --title='Monitor Progress' \
--list --tail --no-headers --column=:IMG --column=:IMG --column=Text --column=:IMG --column=Text \
--separator='\n' --window-icon="${DIRECTORY}/icons/logo.png" \
- --dclick-action=true --select-action=true \
+ --dclick-action=true --select-action=true --no-selection \
--no-buttons &
yadpid=$!
trap "kill $yadpid 2>/dev/null" EXIT
"${DIRECTORY}/etc/terminal-run" '
- trap "sleep 5" EXIT
+ geometry2="'"$geometry2"'"
+ yadpid="'"$yadpid"'"
export DIRECTORY="'"$DIRECTORY"'"
source "${DIRECTORY}/api"
generate_logo
@@ -593,13 +655,13 @@ ${DIRECTORY}/icons/none-1.png
fi
fi
- # if update refresh or update-file actions were run then update the .git folder
+ # if update, refresh, or update-file actions were run, then update the .git folder
if [ "$sourced_updater" == 1 ]; then
update_git
fi
#updates could have been run as part of the manage-daemon, so update the updatable-files and updatable-apps status files
- "${DIRECTORY}/updater" set-status
+ "${DIRECTORY}/updater" set-status
elif [ "$1" == 'multi-uninstall' ] || [ "$1" == 'multi-install' ];then
From b6508e08d203bcd8bde792822c269d738a98baeb Mon Sep 17 00:00:00 2001
From: Botspot <54716352+Botspot@users.noreply.github.com>
Date: Wed, 22 Jan 2025 22:49:33 -0600
Subject: [PATCH 06/14] tweak botspot donate message
avoids falsely implying that I was kicked out of school
---
manage | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/manage b/manage
index 24e6b3b52b..ca3e9063a1 100755
--- a/manage
+++ b/manage
@@ -509,7 +509,7 @@ ${DIRECTORY}/icons/none-1.png
}
summary_window() { #given $queue, summarize what was done
- export botspot_message='to Botspot (college student, Pi-Apps founder, kicked out, needs money)'
+ export botspot_message='to Botspot (Pi-Apps founder, college student, nearly bankrupt)'
export gman_message='to theofficialgman (notable Pi-Apps contributor)'
summary_window_click_function() {
if [ "$5" == "$botspot_message" ];then
From 454efecc6869a2b076c14559c294b07fcf8b969e Mon Sep 17 00:00:00 2001
From: Botspot <54716352+Botspot@users.noreply.github.com>
Date: Thu, 23 Jan 2025 13:24:45 -0600
Subject: [PATCH 07/14] update_app: always reinstall, will_reinstall: only if
insalled
Retains retrying failed updated apps, but avoids installing all app
refreshes lol.
---
api | 7 ++++---
updater | 60 +++++++++++++++++++++++++++++----------------------------
2 files changed, 35 insertions(+), 32 deletions(-)
diff --git a/api b/api
index a85a141224..383b9eb0c6 100755
--- a/api
+++ b/api
@@ -1568,11 +1568,12 @@ will_reinstall() { #return 0 if $1 app will be reinstalled during an update, oth
[ -z "$app" ] && error 'will_reinstall(): requires an argument'
#exit immediately if app is not installed.
- #if [ "$(app_status "$app")" != 'installed' ];then
- # return 1
- #fi
+ if [ "$(app_status "$app")" != 'installed' ];then
+ return 1
+ fi
#it seems that the above code was added for speed alone https://github.com/Botspot/pi-apps/commit/d8bfc3f5fc9b42060bfbd68a11b24f66246d61bc
#commenting it out allows retrying failed app update where uninstall succeeds but install fails
+ #edit: uncommented it again because all uninstalled app refreshes were now being installed
#detect which installation script exists - both for local install and for update directory
local local_scriptname="$(script_name_cpu "$app")"
diff --git a/updater b/updater
index 867b273810..acac633ae3 100755
--- a/updater
+++ b/updater
@@ -433,7 +433,7 @@ Refreshes the Pi-Apps details for apps that do not need to be reinstalled for th
}
-update_app() { #first arg is app name
+update_app() { #given app name, uninstall it, update app folder, install it again
local app="$1"
[ -z "$app" ] && error "update_app(): no app specified!"
status "Updating \e[1m${app}\e[0m\e[96m..."
@@ -448,36 +448,30 @@ update_app() { #first arg is app name
# the GUI updater executes check_repo with the "fast" option so it skips updating the pi-apps update folder and obtains any previously determined updatable apps and files
# if we do not check for this then apps will be removed, the older version moved to trash, and then the new version will fail to copy over since it does not exist
if [ -d "${DIRECTORY}/update/pi-apps/apps/${app}" ]; then
- local installback=no
- if will_reinstall "$app";then
- installback=yes
- status "$app's install script has been updated. Reinstalling $app..."
- #uninstall it - if retrying an update with successful uninstall and failed install, don't uninstall again
- if [ "$(app_status "$app")" != uninstalled ];then
- "${DIRECTORY}/manage" uninstall "$app" update #report to the app uninstall script that this is an uninstall for the purpose of updating by passing "update"
- fi
-
- #fix edge case: if app is installed but uninstall script doesn't exist somehow, then pretend app was uninstalled so that the reinstall later will happen noninteractively
- if [ "$(app_status "$app")" == installed ];then
- echo 'uninstalled' > "${DIRECTORY}/data/status/${app}"
- fi
+
+ status "$app's install script has been updated. Reinstalling $app..."
+ #uninstall it - if retrying an update with successful uninstall and failed install, don't uninstall again
+ if [ "$(app_status "$app")" != uninstalled ];then
+ "${DIRECTORY}/manage" uninstall "$app" update #report to the app uninstall script that this is an uninstall for the purpose of updating by passing "update"
fi
+ #fix edge case: force-pretend app was uninstalled so that the reinstall later will happen noninteractively
+ echo 'uninstalled' > "${DIRECTORY}/data/status/${app}"
+
no_status=true refresh_app "$app"
- failed=false
- if [ "$installback" == 'yes' ];then
- #install the app again
- "${DIRECTORY}/manage" install "$app" update #report to the app install script that this is an install for the purpose of updating by passing "update"
- if [ $? != 0 ]; then
- failed=true
- else
- # click update link only if app is already installed and the update succeeded
- shlink_link "$app" update &
- fi
+ local failed=false
+
+ #install the app again
+ "${DIRECTORY}/manage" install "$app" update #report to the app install script that this is an install for the purpose of updating by passing "update"
+ if [ $? != 0 ]; then
+ failed=true
+ else
+ # click update link only if app is already installed and the update succeeded
+ shlink_link "$app" update &
fi
else
- failed=true
+ local failed=true
fi
if [ "$failed" == 'true' ]; then
@@ -489,7 +483,7 @@ update_app() { #first arg is app name
fi
}
-refresh_app() { #first arg is app name
+refresh_app() { #update app folder only
local app="$1"
[ -z "$app" ] && error "refresh_app(): no app specified!"
[ "$no_status" != true ] && status -n "Refreshing \e[1m${app}\e[0m\e[96m... "
@@ -537,7 +531,11 @@ update_now_cli() { #input: updatable_files and updatable_apps variables
done
for app in $updatable_apps ;do
- update_app "$app"
+ if will_reinstall "$app" ;then
+ update_app "$app"
+ else
+ refresh_app "$app"
+ fi
done
update_git
@@ -551,7 +549,11 @@ update_now_gui_apps() { # deprecated function that is only here so old updater s
local failed_apps=""
local IFS=$'\n'
for app in $updatable_apps ;do
- update_app "$app" || failed_apps+="$app"$'\n'
+ if will_reinstall "$app" ;then
+ update_app "$app" || failed_apps+="$app"$'\n'
+ else
+ refresh_app "$app" || failed_apps+="$app"$'\n'
+ fi
done
#Set terminal title
@@ -622,7 +624,7 @@ update_now_background() { #input: updatable_apps and updatable_files variables
elif [ -f "${DIRECTORY}/update/pi-apps/apps/${app}/install" ] && [ ! -f "${DIRECTORY}/apps/${app}/install-${arch}" ] && [ ! -f "${DIRECTORY}/apps/${app}/install" ] && [ ! -f "${DIRECTORY}/apps/${app}/packages" ]; then
continue
# if app will be reinstalled then don't try to reinstall it in the background
- elif [ "$(app_status "${app}")" == 'installed' ];then
+ elif will_reinstall "$app"; then
continue
# if app failed to install last time, show this app refresh to the user.
elif [ "$(app_status "${app}")" == 'corrupted' ];then
From 2102a55cde1515dccf51a8a3f1676609eb229313 Mon Sep 17 00:00:00 2001
From: Botspot <54716352+Botspot@users.noreply.github.com>
Date: Thu, 23 Jan 2025 13:33:20 -0600
Subject: [PATCH 08/14] bigger app names, fix for apps with space characters
---
manage | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/manage b/manage
index ca3e9063a1..1d0d351c42 100755
--- a/manage
+++ b/manage
@@ -509,6 +509,7 @@ ${DIRECTORY}/icons/none-1.png
}
summary_window() { #given $queue, summarize what was done
+ local IFS=$'\n'
export botspot_message='to Botspot (Pi-Apps founder, college student, nearly bankrupt)'
export gman_message='to theofficialgman (notable Pi-Apps contributor)'
summary_window_click_function() {
@@ -535,14 +536,14 @@ ${DIRECTORY}/icons/none-1.png
${DIRECTORY}/icons/$action.png
$(echo "${action^}ed" | sed 's/Updateed/Updated/g')
${DIRECTORY}/apps/$app/icon-64.png
-$app"
+$app"
else
#if status is 1, then action completed unsuccessfully.
echo "${DIRECTORY}/icons/failure.png
${DIRECTORY}/icons/$action.png
Failed to $action
${DIRECTORY}/apps/$app/icon-64.png
-$app"
+$app"
fi
done
#display donate message at the end
From d65a27b9c05e15b8127306a1cc0fc12422cbec53 Mon Sep 17 00:00:00 2001
From: Botspot <54716352+Botspot@users.noreply.github.com>
Date: Thu, 23 Jan 2025 17:39:15 -0600
Subject: [PATCH 09/14] skip summary window if nothing to show
---
manage | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/manage b/manage
index 1d0d351c42..a1f4def3c1 100755
--- a/manage
+++ b/manage
@@ -521,15 +521,16 @@ ${DIRECTORY}/icons/none-1.png
}
export -f summary_window_click_function
+ #avoid flooding the summary window with less important completed actions
+ queue="$(echo "$queue" | grep -v '^update-file;\|^refresh;')"
+ #skip summary window if it was just app and file refreshes
+ [ -z "$queue" ] && return 0
+
(for line in $queue ;do
action="$(echo "$line" | awk -F';' '{print $1}')"
app="$(echo "$line" | awk -F';' '{print $2}')"
status="$(echo "$line" | awk -F';' '{print $3}')"
- if [ "$action" == update-file ] || [ "$action" == refresh ];then
- continue #avoid flooding the summary window with less important completed actions
- fi
-
if [ "$status" == 0 ];then
#if status is 0, then action completed successfully.
echo "${DIRECTORY}/icons/success.png
@@ -557,7 +558,7 @@ ${DIRECTORY}/icons/none-24.png
Donate
${DIRECTORY}/icons/theofficialgman.png
$gman_message"
- ) | yad --class Pi-Apps --name "Pi-Apps" --width=330 --height=400 "$geometry2" --title='Actions complete' \
+ ) | yad --class Pi-Apps --name "Pi-Apps" --width=480 --height=400 "$geometry2" --title='Actions complete' \
--list --tail --no-headers --column=:IMG --column=:IMG --column=Text --column=:IMG --column=Text \
--wrap-width=190 --wrap-cols=5 --close-on-unfocus \
--separator='\n' --window-icon="${DIRECTORY}/icons/logo.png" \
@@ -624,7 +625,7 @@ $gman_message"
[ -z "$geometry2" ] && geometry2='--center'
- tail -f --retry "${DIRECTORY}/data/manage-daemon/yadlist" 2>/dev/null | yad --class Pi-Apps --name "Pi-Apps" --width=330 --height=400 "$geometry2" --title='Monitor Progress' \
+ tail -f --retry "${DIRECTORY}/data/manage-daemon/yadlist" 2>/dev/null | yad --class Pi-Apps --name "Pi-Apps" --width=480 --height=400 "$geometry2" --title='Monitor Progress' \
--list --tail --no-headers --column=:IMG --column=:IMG --column=Text --column=:IMG --column=Text \
--separator='\n' --window-icon="${DIRECTORY}/icons/logo.png" \
--dclick-action=true --select-action=true --no-selection \
From c5bdb87766710facf905bb125aedab11f8d6cf2c Mon Sep 17 00:00:00 2001
From: Botspot <54716352+Botspot@users.noreply.github.com>
Date: Thu, 23 Jan 2025 17:39:34 -0600
Subject: [PATCH 10/14] clarify new app updates if there are 5+ of them
---
updater | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/updater b/updater
index acac633ae3..b5141b2e7c 100755
--- a/updater
+++ b/updater
@@ -312,6 +312,7 @@ list_updates_gui() { #input: updatable_apps and updatable_files variables, outpu
local LIST=''
local app
+ local num_new_apps=0 #track how many newly available apps there are. If there are a lot, the user may be unchecking them, misunderstanding pi-apps updates
local compressed_update=''
for app in $updatable_apps ;do #generate a yad list for every updatable app
# get app tooltip
@@ -319,6 +320,7 @@ list_updates_gui() { #input: updatable_apps and updatable_files variables, outpu
# if ${app} folder did not exist before and install-${arch}, install, or packages file is in the new update, then this is a "new app"
# results in applications that only have support for a different architecture to show under the compressed update
if [ ! -d "${DIRECTORY}/apps/${app}" ] && ( [ -f "${DIRECTORY}/update/pi-apps/apps/${app}/install-${arch}" ] || [ -f "${DIRECTORY}/update/pi-apps/apps/${app}/install" ] || [ -f "${DIRECTORY}/update/pi-apps/apps/${app}/packages" ] ); then
+ num_new_apps=$((num_new_apps+1))
LIST+="TRUE
${DIRECTORY}/update/pi-apps/apps/${app}/icon-24.png
$app (new app)
@@ -326,6 +328,7 @@ refresh-app:$app
$line"$'\n'
# if install-${arch} is in the new update and it was not installable on this system before, then this is a "new app".
elif [ -f "${DIRECTORY}/update/pi-apps/apps/${app}/install-${arch}" ] && [ ! -f "${DIRECTORY}/apps/${app}/install-${arch}" ] && [ ! -f "${DIRECTORY}/apps/${app}/install" ] && [ ! -f "${DIRECTORY}/apps/${app}/packages" ]; then
+ num_new_apps=$((num_new_apps+1))
LIST+="TRUE
${DIRECTORY}/update/pi-apps/apps/${app}/icon-24.png
$app (new app)
@@ -333,6 +336,7 @@ refresh-app:$app
$line"$'\n'
# similar to the above. if install script is in the new update and it was not installable on this system before, then this is a "new app".
elif [ -f "${DIRECTORY}/update/pi-apps/apps/${app}/install" ] && [ ! -f "${DIRECTORY}/apps/${app}/install-${arch}" ] && [ ! -f "${DIRECTORY}/apps/${app}/install" ] && [ ! -f "${DIRECTORY}/apps/${app}/packages" ]; then
+ num_new_apps=$((num_new_apps+1))
LIST+="TRUE
${DIRECTORY}/update/pi-apps/apps/${app}/icon-24.png
$app (new app)
@@ -408,11 +412,18 @@ Refreshes the Pi-Apps details for apps that do not need to be reinstalled for th
exit 0
fi
+ # if user has 5+ "new apps", they may be unchecking them all each time. Provide an explanatory message.
+ if [ $num_new_apps -ge 5 ];then
+ local update_hint_message="Pro tip: please leave the "\""new apps"\"" checked. This is just how Pi-Apps announces a new app that can be installed. Unless you have a very specific reason to keep an old app version, don't uncheck anything."
+ else
+ local update_hint_message="Uncheck an item to skip updating it."
+ fi
+
#Display a list of everything updatable
output="$(echo "$LIST" | yad --class Pi-Apps --name "Pi-Apps" --center --title='Pi-Apps' \
--window-icon="${DIRECTORY}/icons/logo.png" --width=310 --height=300 \
--list --checklist --separator='\n' --print-column=4 --no-headers \
- --text="Updates available:"$'\n'"Uncheck an item to skip updating it." \
+ --text="Updates available:"$'\n'"$update_hint_message" \
--column=:CHK --column=:IMG --column=Name --column=ID:HD --column=tip:HD --tooltip-column=5 \
--button='Cancel'!"${DIRECTORY}/icons/exit.png"!"Close without updating anything":1 \
--button='Update now'!"${DIRECTORY}/icons/download.png":0 \
From 07ffc0d4b93d75ad98840fd99bfaa5bb087980e9 Mon Sep 17 00:00:00 2001
From: Botspot <54716352+Botspot@users.noreply.github.com>
Date: Thu, 23 Jan 2025 20:41:03 -0600
Subject: [PATCH 11/14] donation click adds runonce hash for later use maybe
---
manage | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/manage b/manage
index a1f4def3c1..9ba081ebc6 100755
--- a/manage
+++ b/manage
@@ -514,9 +514,15 @@ ${DIRECTORY}/icons/none-1.png
export gman_message='to theofficialgman (notable Pi-Apps contributor)'
summary_window_click_function() {
if [ "$5" == "$botspot_message" ];then
- xdg-open 'https://github.com/sponsors/botspot'
+ xdg-open 'https://github.com/sponsors/botspot' &
+
+ #remember that donation link was clicked - opts out of any popups introduced in the future
+ #"$(echo 'botspot donation click' | sha1sum | awk '{print $1}')"
+ if ! grep -q "8a780b08ac20332b897ecb399b25f4622bb31341" "${DIRECTORY}/data/runonce_hashes" ;then
+ echo "8a780b08ac20332b897ecb399b25f4622bb31341" >> "${DIRECTORY}/data/runonce_hashes"
+ fi
elif [ "$5" == "$gman_message" ];then
- xdg-open 'https://github.com/sponsors/theofficialgman'
+ xdg-open 'https://github.com/sponsors/theofficialgman' &
fi
}
export -f summary_window_click_function
From e7ae18a5cb75c9fc522ed832d00dfe03ae11a49c Mon Sep 17 00:00:00 2001
From: Botspot <54716352+Botspot@users.noreply.github.com>
Date: Sat, 25 Jan 2025 10:45:49 -0600
Subject: [PATCH 12/14] document update_app better, remove unneeded edge case
fix
---
updater | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/updater b/updater
index b5141b2e7c..8e5057dbad 100755
--- a/updater
+++ b/updater
@@ -444,7 +444,7 @@ Refreshes the Pi-Apps details for apps that do not need to be reinstalled for th
}
-update_app() { #given app name, uninstall it, update app folder, install it again
+update_app() { #given app name, uninstall it, update app folder, install it again (not to be used for app refreshes!)
local app="$1"
[ -z "$app" ] && error "update_app(): no app specified!"
status "Updating \e[1m${app}\e[0m\e[96m..."
@@ -466,9 +466,7 @@ update_app() { #given app name, uninstall it, update app folder, install it agai
"${DIRECTORY}/manage" uninstall "$app" update #report to the app uninstall script that this is an uninstall for the purpose of updating by passing "update"
fi
- #fix edge case: force-pretend app was uninstalled so that the reinstall later will happen noninteractively
- echo 'uninstalled' > "${DIRECTORY}/data/status/${app}"
-
+ #copy new version of the app folder to main pi-apps directory
no_status=true refresh_app "$app"
local failed=false
From 0e8a591732867bff9a775e474bc4eae9c0d94e32 Mon Sep 17 00:00:00 2001
From: Botspot <54716352+Botspot@users.noreply.github.com>
Date: Sat, 25 Jan 2025 10:50:24 -0600
Subject: [PATCH 13/14] improve terminal_manage_multi documentation
---
api | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/api b/api
index 383b9eb0c6..f6ce6b31a8 100755
--- a/api
+++ b/api
@@ -1081,8 +1081,8 @@ terminal_manage() { # wrapper for the original terminal_manage function to termi
terminal_manage_multi "$action $app"
}
-terminal_manage_multi() { #function to install/uninstall/update/refresh multiple apps - refreshes the app list if applicable
- local queue="$1" #one or multiple actions and app names
+terminal_manage_multi() { #function to install/uninstall/update/refresh apps or refresh-file files, one per line - refreshes the gui app list if applicable
+ local queue="$1" #one action per line, in the format "$action $app" or "update-file $file"
#To prevent multiple simultaneous manage instances, use the 'daemon' mode. This will create a queue of actions that are executed concurrently.
#The first daemon instance is the 'master' process, which opens a terminal. Subsequent processes will add the action to the queue and then exit.
From 48b2e56714e57baccb7bb58d6509188204ca2519 Mon Sep 17 00:00:00 2001
From: Botspot <54716352+Botspot@users.noreply.github.com>
Date: Sat, 25 Jan 2025 12:33:36 -0600
Subject: [PATCH 14/14] update daemon pid to that of the terminal
---
manage | 2 ++
1 file changed, 2 insertions(+)
diff --git a/manage b/manage
index 9ba081ebc6..fc7b7d1f2d 100755
--- a/manage
+++ b/manage
@@ -647,6 +647,8 @@ $gman_message"
source "${DIRECTORY}/api"
generate_logo
+ #update daemon pid to that of the terminal, in case original manage script is killed somehow
+ echo $$ > "${DIRECTORY}/data/manage-daemon/pid"
source "${DIRECTORY}/manage" daemon source
manage_daemon_terminal_code' "Terminal Output"