From 284075257591e01a56a9fefd3326df8cf5d47601 Mon Sep 17 00:00:00 2001 From: "Muhamed H. Asadi" Date: Sun, 6 Sep 2026 22:39:57 +0330 Subject: [PATCH] Initial Commit --- backup.sh | 74 +++++++++++ backups/konsole_backup_20260906_221707.zip | Bin 0 -> 13933 bytes restore.sh | 142 +++++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100755 backup.sh create mode 100644 backups/konsole_backup_20260906_221707.zip create mode 100755 restore.sh diff --git a/backup.sh b/backup.sh new file mode 100755 index 0000000..7a40439 --- /dev/null +++ b/backup.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Script directory and backups directory setup +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BACKUP_DIR="${SCRIPT_DIR}/backups" +mkdir -p "${BACKUP_DIR}" + +# Timestamp for archive name +TIMESTAMP="$(date +"%Y%m%d_%H%M%S")" +ZIP_FILENAME="konsole_backup_${TIMESTAMP}.zip" +ZIP_FILEPATH="${BACKUP_DIR}/${ZIP_FILENAME}" + +# Temporary staging directory +TEMP_DIR="$(mktemp -d)" +trap 'rm -rf "${TEMP_DIR}"' EXIT + +echo "=== Starting Konsole Configuration Backup ===" + +# Define target paths relative to HOME +CONFIG_PATHS=( + ".config/konsolerc" + ".local/share/konsole" + ".local/share/kxmlgui5/konsole" + ".config/konsole.notifyrc" + ".config/konsolesshconfig" +) + +COPIED_COUNT=0 + +for rel_path in "${CONFIG_PATHS[@]}"; do + src_path="${HOME}/${rel_path}" + dest_path="${TEMP_DIR}/${rel_path}" + + if [ -e "${src_path}" ]; then + mkdir -p "$(dirname "${dest_path}")" + cp -a "${src_path}" "${dest_path}" + echo " [+] Staged: ~/${rel_path}" + COPIED_COUNT=$((COPIED_COUNT + 1)) + else + echo " [-] Skipped (not found): ~/${rel_path}" + fi +done + +if [ "${COPIED_COUNT}" -eq 0 ]; then + echo "Error: No Konsole configuration files found to backup." + exit 1 +fi + +# Create zip file from staging area +echo "Creating backup archive: ${ZIP_FILENAME}..." +( + cd "${TEMP_DIR}" + zip -q -r "${ZIP_FILEPATH}" . +) + +echo "Backup successfully saved to: ${ZIP_FILEPATH}" + +# Retention Policy: keep at most 10 recent backup zip files +MAX_BACKUPS=10 + +mapfile -t BACKUP_FILES < <(find "${BACKUP_DIR}" -maxdepth 1 -name "konsole_backup_*.zip" | sort -r) + +TOTAL_BACKUPS="${#BACKUP_FILES[@]}" +if [ "${TOTAL_BACKUPS}" -gt "${MAX_BACKUPS}" ]; then + echo "Cleaning up older backups (keeping top ${MAX_BACKUPS})..." + for (( i=MAX_BACKUPS; i~pXLx+hYaqVo z`-b11_-9>vufEs1P?5g}g#fsDQB~0x{PX4CH&_4>fW^+y%*2jWQv)7wkFhq(=H_zu zLIglSZQKI@{&`cmQvmW00j^diF2Mg!F*v`AvGuaIvvjw9@PCxY>`D2{bCKLB&(_hw z)zR+X`^?r!yX$eWz#4)BeDb0+Sk|2_bpUGu7Zm_t_^)#RmG5rN;$rrXN;mYjXM_EKy0x0=dl6Siwqdo&EHA=cJ?UwA%TeL;f|4 z=`=^fMF9`uX2Ywm&DVZDYt*3+TM#xrs0#!m1{6PekKv1otgYpOrTfaQCzN8EJSpVs zk`Jme6Fke;GsmknM%LF5n))s)&enmwkIy;~Le4t^)(fA!mey*TLs(bdBxHjZ*z|(v zfRHYD*s`p1eTZlciwIjbAtZ^SpP^M@>62&r<_!0q>1u|d4pnW?vlA2-2Ob;s)^cM; zEZ+x>eYV($la(EAD9@0lv&-dCd`@N)ba-SLAM%7*svuXkrKvtn|D_<;9mqnLA2+Xg*@Wl|3;7*ZuE`o7^GU))!&e`4e5 z^9>D0`5mX89mml$ybHs;b=x^ZRUn;)i`Jv!?TxZJHb-Zn%WX!j9&F{nHK``bYEm=x zHX~Y(KvXQ7e3}MHLDmRf!*iK*Ted?JQR? z6=k&pCop4&?qTt5yV(tcZ>9ss9{9#~j(Ch_g~rg9c{6_{{ZsmN!btSBfAz(uxX8Ef z<;|*nK&k{snK<5(QgjV+2wR|0{p@~t&x6-_E||ic*zseOFc-4>9mR<6M|lH+dSUNF zr?vX>l*{@Y9Bn8xwIvKaz21@Q5?ZqoSLjB&m)l`b$eF&tV^{MbZC>SqBYqq%G=t&` zDPyG;(Q*LO0dkg38D}wB(`$pnEs#Z@;D?p_`i9!I1QRcgVkj0zn(E8aFCMN3T0o)< z)VJq9+Q{^vU4*XQ_pEmGEFdLV;f_BPQhS@QvA7NG2v>i4o z{TKRKLqph9&H)yZ<(#bY7)EN+OUA&82_LmE0;DrSE`dPW6i2dUt{A0W4nw|^bM^Mg zyuCnDQP)Iq&cGaF^ZZzqJz<7C>~0*GdYpG`lZTS1LQkwfZ^BwAA}C2$J!;4?_cpA2 zmPvsAyt1m_i0j0s9K7OZQ-RJ5qW{8f$vUx--e78nW50?mU38h%N<&i z5FUIR)aOh1*iEY4F2|f;iOXBZ@FGPFxSodzJ-nxYU~kN+0V0H$Enpl$JhNg{f#;JA zV<6tlpoE$+&XX1($*Y(k9exmuX+=3FBaVMYO)V>>ipE8%*u*u9_5OVoM0Q@{cua9i zh@K5Ab*-bNS0j#%JNme&tP*@*%JXO4i-FME?ex%w;BTMY%FBvpmzZ-`J9pHIQ{i2jIjeGyRoPIyP<3Yel+Y+vGR|2j>h(9h9 zs~YXAkRmgw(jyO552`D;7LoOejaA2iCp6;4b{Us~nv+;d(>Y^}DP8eB*;4bSzV)c6 zK4aRrSxB3&-qas?izRCa4wf87BRVuZ3&6E`~XD`$UG_d>%9U3M!23g;Srl?$f0lJb>+AEm$I5!Ej>7W-B$ z{JFGtRiyvDv}V5I)V7DpE{THx0A!#50P4HMiMp6sv6wm9Il8!-Spn^V|5R17HF#i1 zX!`F})jdhkF_;Z0Z2v2ct(*czA4t3@(mGXfhGAFb6m8T_asZ(EXv6;sDS1Ri6OI00 zs@!PZtck08*i$d3{Nx$(^o_FjH_hq($IL@O;CXw`NS&sL@h z3$yKkdMh5IB@8H6#6IyNl)6po8GiVlHD)tSFFv0-ez9z$0Omr zIVbJu!8MyaB;^=O|8_6)aATb3!_%I+X@Nn5X}h7=LBnl-zF^*6(jQq@3S(VkNm@we z4BS=qfelV`m$6M99c}GRTx?xgzzraasfq1B)+W5yW2!8p3;eAuja6-O=ww5hJH{^c z(A(9*tKvLiuOlAIDK|QpteN-UI@1F10%ugay+lnHnKT=Jt9Too75YR}8 zzpYesF3@c8*wkouV*dDYe0h5Xy6nN{!yE*O7c2RkJdb?nB?&to%J3?xlT>DYl`Rvj zRD$b*qvlo=2+>D5LjIxFw1*!wmYsuZy}&A!g$4ka?^3In zor#&PvV*pjwHxqOEJecCnEoM_UL}hv2eT1%?_XhE0%EOo5Rcp1t)FEpWcH&Bpdj1U z^~@xe5q&DI7oktii)@Su5W86L7a&RAO~l@ZEnuu&1o<%6_G8NBksiFAFbojToXaBe z5>ieu(&f~{w+PjG6@(6HJlm>m2(jGQgb-YM!-Js^QQc@(QYx4n_*< zVv~u-Y8sNJi&!*L&zXQmRuLj}?P7g7ccBR6cgh@@*kPb;2!7j0(6r<`y)nDD#-d!0sr?LUV1O&R+GAwlHg`C@6FO~@(sGCSkGcgriw!N!Kw~y;^ zslZSx+toSxswjhED5nMI?Ar| zVgCF!s5JF) zu#^YJP!7r%9rocc2)Jd|2W2F&J%CYrLeE#{dtF8-u;P0zk*C!Qldq4~^o^f9AEdwL zuCO+3VD6fEnQ+G5jnQLSN4P$w42-i}<+VJ2Lv>PaA|Umdn&b?~!xZ4bTl6@ioR|0* zZ@ON53UyqXb$XaBF5D@i$T9%%!wYWeF2Y%#*GsS$JOmfY`*(VQ3lR7SNT#O_bnyVX zXu1Mj3~u?tOz->yfbdsiG`}->yJs_f@t&sy5>*2|M8K)IzgVMyE~;ZHg&p2zhpP zp1%y(`Q%SD<7gm|uwxAJsrr_J9YYK380`PeF;qm= z)U_nkZ+k^K*ehk$fvrQD2X5y2iNUZOm9jL8X5 zx`sT(`+bozDx!$dfra~rg9qLhu;?@w*25B0Tki1qX z4E0o#3n-#`DlX{8H0JM!$t=`(3!qHU^pg(X;?paXu+->caZmz9;M9W>-N%u|%mD5^ zwzi7h88CKQ&tr%*lLOa8N*prsS7lUjS~$2NLo@?97~LWzMjhlbGTt$GTAHLp%%vLk zDkkU<)L>-vXQgeYg$yk`+w(1(4`lSpLLeScSt@eYgB15NN_!uxZs*GqA3oyWr{8%= z(eELXckR1{5n3J=1`|btU!J5d@$C|EPn}IXg+kD-F@YBkS6qiz~S?v1F7fYz6WgGuIZd&D&9;n3(RM>3o~wm zz6I;goxMC4?1go64rbg!20bJG#Ghs%Q?i1teySP~-c$z9XI^I@f!!hre9_+J7C-U? zi<66^g|*%H*7|8#y3Hr!TLUY56?yqCHnf&?ZLBW6uF09;aH5&FQ8SwC+b>SodYlPm zk~sRyHp)F4N%SQkF+Y6~ym*w24%gf+TGI|aX3+(&DIQ_;^pwE*@d-u(OeKQQ3w{M; z&?&nfEUCHb+iEebBaY#f{H8j&7!5{r9uFmFlL&4VA8F2`@9TWCO^IgU_*^tu!=&$+Qz zo?b;^7_cqjd6*@ck)@N-9|CsTMn^Ews!lZL-4*8-a-uCW#X5v-dkukCoBbF7LV*@-vmd~amgf|E=`K)ZBJ)9{z%R~U}Z-@QxbiAN)CmULr=eH=Ch{1?w@t}6`#1c4}yb?tDn(%80xbMV_j2rgm^Oh~01bhX)Y-wT_~U zhAh6eY99GkD)A>{((QWWo9cO$X-+uu`4d4&dOuk2%?e)3Y4A1F++jD?8e*Pd$EQ|7 zr;m{FF)wvI!xF$oRi9W04RP`sK&Qb1Mi~`|Lncj^LZ4BH;YCwoZZ|_FVb$}c7mDHJ z8=u8*1aM4>JgrD||M0-w$8(6w%CAfKL8~~!#dwl$Gpd4AuGdOp&YY+zT>p|-k{2{) zynRBchq0Cj|L&MZ%TIOi<_s|vxy^$PR&yA5dP8xSs((2{{OA1ehZ$^lVv|cJ8JeU| zKzEoS#fy)lWKDeq3Tix(a^_k%ln?|sde>hANjwr|6IigFQhh$N1W#ov!qT1;W-(72 z_zwVf7wGL#seKj&Ep6-OOS=YFwmbJ$cHxJxJq|N*BDCZ~M`7eALq>2jQ9I*5kf@T^ zwx2c}!zzjDQoo^4iamK=wc1zniZ}!PiR-I`mMcmNt?F(m#A3}UAHR#R$Qi2~TOKky4hyul1VX8^v|N zqxRzc6Zju~tq!6zc$sN2lmS+@9JsdJnMB0?X*zE889g>>e@Y_YKI5jMG#~5XKsWeC z@NK9RJB`XC-iLVv=R!tQhyGR$l9_a;e0U}7?L~b?UZJ5v&xQFv#SOD=C#ZO^GRxMxjD{Nr)fnOAm*i-*7GvQ}&6@Y$dzrd}38x-V6`CJgPnDL*7Uk(VBrTH#KX> zhwg{=nOxMY$X+lR-ze%28Y8NRT}zdf=ku3drsa9(i}q}j;f_fMEZGv7qHL=Al6)Rc zz4y5vlDSg0cW&?to};92=fVB!?O~I>-n>iVG4d$Z!;0Z6x2vjt_UwYG&-C-d#aK-S zIr-=8p?<859X%>p>a^co+3Dj@P;+dm8D#5DrjUIlD> zwz~pN#l#8dB7QTOQLwhOa=YaObzmo`2VcLn6`@J0w&1YqUA$tFj%4Q=6epRCjcK3i z(V7z93@$8t!i!nzw;^<;Ft%|Y6a?G8_-*ex+oH+h^h}i7vUV}=Qi`ilp&y|PG%|S{ z1rKzH%uZh3>RJb08FFwa(CK$p=JsZil?YR|mvKLfhoTZ_hw5E06Xi<;qCkgr?S_}p zgRs`)(R&LzUbedkxqMV}MMw@J#D+)2g*MIv97b}+A#TM2DPwJyQjMWg2C|ib;@=vnemes=w6d2Pn%APgpo!hhcWLXn#fsuShHz z75Ey=7UmDlMu2?6sM2MiwvqZ?z@_^^62DvVmYHXBDDhlSeyzav*aj!5+Cth4xA4bQ z{L$w}(fydxs9!Z~M?dpBmaa8w3q^O1=E})@F=0teB_!v4WUs^gu3M|#_0n9eF017v z=Ly#Cr?I1>qD>(|JWlqDdq0Ah+LX$Gj?;!j7Hml9zh%tt=KHw`hy%~o{?G&fRph~? z2?^W;oK)$dzv|&3TO09+(e90Jj1+$#oSODPH$_7!>b}3AAtMxKl}m*1rO)f3MifvR zgPp{lRrtw5{-DN44xMnD7gi`|9K-vM=xc;-GU5djms}B{>TgKT!pam(SsZ4`a@bd) zW-hEYOQXlFeV_DHpVQ!5Tx$}bzAUPH=$>0MKalpY)8in&(|T3e(c8t>@}PX9XGP~s zL8T@$QUscc_1-C+gu%%wvE)k@D@#Aho`Cl*6lomSfjICAlyb#wY-hT#oiT19WVC)7 z%AXY7a1~3vpj*10enW=i-J)O|5MVSc>n7NI&is^m#86L(Y>Re)YYK7Tx}==1X6Iz- zcw8T|L&vFBlqlD$qhInOEqRI~>a^&w%@- zgUAA$m**ZmmtSO9%0Yzowx{sZ4f}@rmlq!*;a<46yl*AyFXCD(7jr%InCk9Pc1dfR zojKFJ0ygd$M!){DWaJM$+qow~!Q2lhG!f6oPsRz0R;)s44Ka^f>Ei@i98n%LH#E_{ ztl-IyBZ4kwd*)V*%4LGQ@lJ`fbb;XD39r4TppV7VlB@@KRt46Vb`J>^XV=GB#5~2v zc8jJgtJ4GnC}bn2`ZH0}oYcBv2t63j&IS2kRb6^4D-fAD8O?3y?Y2C^kRx9n0%*J| zy>V4}1D>QE^U}rC;U#uJA!xxC-;--H#^Zp4F7{WTSmFNS#dl8CosVl2^o~dZwnleJ zLN|*syq&j(uVXMJ^u!*5(l29Mdhe4L%fs<1#HaLZKC~56eh)${KYVkEaB|Jmp6f{j zGW$#sqLeYn;$Ugx zTZm*{P<~%z7fSr=epM<5m(z*GBh$dQyplMjDaM)v3Ir8zJ2*H9~0jxl>g7Mkl?6!d4&eO3=Xk$_HNo_kcI6)z`#RBFq2oMO#qa@b~(UN>3+jJyB zTBFGG>Vafo;6Cac<+o`{Y?>L%3FRfo5^#?mJH3ML-XFpG+{Uqot-dwyV%sGxTV4_C zg1aZNT}{S8@XP&Hh1S(gj;j>l<~OZur3_uY4hw*pb#bcAy;*K@uIy_dx|9FA)`4^V zE%v1@AwTuqZvNoNKFijUS5he1Ntfih%6aO?Z>Bo~`Eb9|VsN}xdbQ&mwVb}RPd2#_ zh`A6OtK@YKr^?z>Xi(a?%Agb9crVfl+E)d&jgEez`;h_8`@zr|GE!zx6ZC=(hHFVy zRSr~C3aaecy~IA@kfWNa7#gji^iI^ESDpT!4`nc#Fr#bT@q|Q6-n5TT-aE@mRJVSS zN*BC$2rq>T?TF+<+u5XaRYm?t=)q^`Q(y`(sO6=CO$ZN1RIXY&>X@+QY2+^UP0IYv zV!1g9{7Yc@=i@djCvm(e9c*Zl zm%NfJfszU$c}}1y^b9zIsbf8vJWV8zu*DGd;IiJTIr!$(fQ=3fDvPaTK5Y^&_iVQ4J z!D$k1v*+j(U})DWzMF+vJ~U1in`dz#b;opIUD9`NXAJIH)?W3m9M-Xo`Iac3l5zEj z?~4;6rCgXG2C~dltkACEMypF}M8nIK1`Gm+AC-<19E=U5>cn2K000sN0Dyj5A^&n_ zO8y*tPjm;>=6KLrF6lo(%g9zy&%QVU4TdP%q=w9p_p8yPSfDLMRnpH^BVC>_PES5A zN-<%57juy`anbmGK9MZLf6;m2WS?8O))u)?RaR_sXI-JkMtDa@)$VlLtpq z$NYp@Ekt6t`Y5OFB}_}2G^U@1x>07T=JB322Hehm^Rj`Cku>Sdr?SRxLrsQOddB1z z1@;$ppD@cmj9MGi53e`#X6~Ie<79=^ZPO+W&s^mR+fwHWJE98aq2?^Q>9ZT1IViQcd-|BNG)wi&C4dPlP?qX5IMwP zBYvSJ%kb*{$O?r==`sYFAF0{#5C!7?OBVKO{UkX~ry$jG5u-u+XG}1FF!g2Zk&S{+ zYE6N5LuAQ~fk3PZI-(U&Y%OFE9vY6$RT7%mF`dR+F)~F9rX})ti`YUsQh9@dUD$vSD>uX_;b; z^;U53yKOy3;byN##EKfH9DJ^2}>1em55bG$YGFdlArCK@U)&mm4FESzOOaC{_j zhufWls2REJ!^O8HTRt6cIsV4;Dj4;lJyk1EOnte*Los|Vq%oyh1P{LjPlV#J%spu> zk)Fd3u*aFg-G&4pr3|Q|1rm^4@ag6UZpgrKthMWf#-leBQf|manH0y|$Jk3a@1n_! zkyog307aXI(yUiOh1uQZfcji>dxc#*_9G^FJG9y=N6LN4VBEdp-MDC%Fk z2zGFU*bgNVAzymjD`PR!wwOn1C_!8cifXPVmxO}?#su0e2QH@ydwceu|=#9?8Huj zG4H)4rqS?W4)Jq#PuUYdlAmuv(u5KW%Y zz}GsGjK`&lJ37)vD(A*+TyWu|Gxr&f2?yds0GZ+2OW4UkJmTgQr}~!nTpXIKk6;IP z3Hbqyih{40I2V+3P>swcRnLmWSd6wmE#l*-(#uaMdpoAW<0hB)98I5@sV_`?<+_MI z6Q6a)emFF;NIlN1uNV8Wp-w&RPw)REc!#p_@j!-7$U{Jq+`EfGjQ4LVh6dObz4`hdJ~8xnKJjnu%-@6|gPWx9uNz@E(*70pzue;g zcab>1h>ZAMselIsT(czITnc8OPr-zzrmz5X1)l z_(diEx&Qyg`1kW)wjvnshJXAQyxV-ppYb4XSO?$v;onVg3-4EUBpC089r;JR@BVX} zMfS4}1>k_)NMY~&rn|ANBvc6 ze>{);!)^j&-LRYff_0nZ^8+goG>mu$*4>n!8zX@!KYxL|O+5JlSqLgaz6B=|#cyu!(SJrBME@_yf8MHtVgImE|DOE5 zyX);e?a#2Qn0LVbX=@7xyV=_QMZ356ls|*1V&4IFYikKcy4hO(1?l#h?gvsKs2S%D zq+gEeni^o7{}L9rH&j1x0zvfPAAj+eUsn}iu$z6=UmoiAO5_JvA&8pb4zRy2NWiE! z3zEN}-k#t8Kn(=#5#E9N+cY1Hb2H8V3(oBk^beduP!jPSIKL01!9X_y>AwKo9>@Iv z3IrXH-2wFLa1IP}Go1S)%=a2|dp`6X23$hHHM9pjdibMj{NjQ?rbS@9J6-Y5JrUe5 zJqH6N81FxmBe1kT{)5#`hjrK7=w~I_{Uq)76bUT-W{UJj-F%mRdkFKhbU&&e_xi8& dn~@Ay?9E8#mRM+*8/dev/null; then + git diff --no-index --color "${dest_item}" "${item}" || true + else + diff -u --color=always "${dest_item}" "${item}" || true + fi + fi + fi + done < <(find "${source_dir}" -type f -print0) + + if [ "${changes_found}" -eq 0 ]; then + echo -e "\n\033[1;32mNo differences detected. Current configuration matches the backup exactly.\033[0m" + fi + echo "================================================================" + echo "" +} + +ARCHIVE_PATH="" + +# 1. Check positional argument +if [ $# -ge 1 ] && [ -n "$1" ]; then + ARCHIVE_PATH="$1" +# 2. Check if piped via stdin +elif [ ! -t 0 ]; then + read -r ARCHIVE_PATH || true +fi + +# 3. Interactive prompt / selection menu if no input given +if [ -z "${ARCHIVE_PATH}" ]; then + if [ ! -d "${BACKUP_DIR}" ]; then + echo "Error: No backups directory found at ${BACKUP_DIR}" + exit 1 + fi + + mapfile -t AVAILABLE_BACKUPS < <(find "${BACKUP_DIR}" -maxdepth 1 -name "konsole_backup_*.zip" | sort -r) + + if [ "${#AVAILABLE_BACKUPS[@]}" -eq 0 ]; then + echo "Error: No backup archives found in ${BACKUP_DIR}." + exit 1 + fi + + echo "Available Konsole backups:" + for i in "${!AVAILABLE_BACKUPS[@]}"; do + echo " [$((i + 1))] $(basename "${AVAILABLE_BACKUPS[$i]}")" + done + echo " [q] Quit" + + read -r -p "Select a backup to restore [1-${#AVAILABLE_BACKUPS[@]}]: " choice < /dev/tty + if [[ "${choice}" =~ ^[0-9]+$ ]] && [ "${choice}" -ge 1 ] && [ "${choice}" -le "${#AVAILABLE_BACKUPS[@]}" ]; then + ARCHIVE_PATH="${AVAILABLE_BACKUPS[$((choice - 1))]}" + else + echo "Aborted." + exit 0 + fi +fi + +# Expand relative paths +if [[ "${ARCHIVE_PATH}" != /* ]]; then + if [ -f "${BACKUP_DIR}/${ARCHIVE_PATH}" ]; then + ARCHIVE_PATH="${BACKUP_DIR}/${ARCHIVE_PATH}" + elif [ -f "./${ARCHIVE_PATH}" ]; then + ARCHIVE_PATH="$(pwd)/${ARCHIVE_PATH}" + fi +fi + +if [ ! -f "${ARCHIVE_PATH}" ]; then + echo "Error: Backup file not found: ${ARCHIVE_PATH}" + exit 1 +fi + +echo "Selected backup archive: ${ARCHIVE_PATH}" + +# Extract to temporary staging directory +TEMP_DIR="$(mktemp -d)" +trap 'rm -rf "${TEMP_DIR}"' EXIT + +unzip -q -o "${ARCHIVE_PATH}" -d "${TEMP_DIR}" + +# Interactive confirmation loop (allows viewing diffs) +while true; do + echo "" + echo "Konsole configuration files to be restored:" + find "${TEMP_DIR}" -mindepth 1 -maxdepth 3 | while read -r f; do + rel="${f#"${TEMP_DIR}"/}" + echo " - ~/${rel}" + done + echo "" + + if [ -t 0 ]; then + INPUT_SRC="/dev/stdin" + else + INPUT_SRC="/dev/tty" + fi + + read -r -p "Choose action: [r] Restore / [d] View Diff / [c] Cancel: " action < "${INPUT_SRC}" + + case "${action,,}" in + r|y|yes) + echo "Restoring configuration files..." + cp -a "${TEMP_DIR}/." "${HOME}/" + echo -e "\033[1;32mKonsole configurations restored successfully from $(basename "${ARCHIVE_PATH}")!\033[0m" + echo "Note: If Konsole is currently running, please restart it to apply all settings." + break + ;; + d|diff) + show_diff "${TEMP_DIR}" + ;; + c|q|n|no|cancel) + echo "Restoration cancelled." + exit 0 + ;; + *) + echo "Invalid option. Please enter 'r', 'd', or 'c'." + ;; + esac +done