From 63f260866e8c593b25b82742a29b234ae29be524 Mon Sep 17 00:00:00 2001 From: Zaine Arch Date: Sat, 9 May 2026 16:25:31 +0100 Subject: [PATCH] authoring service changes --- ...n-shot-2025-11-10-at-18-02-10-fullpage.png | Bin 0 -> 72287 bytes authoring_server.py | 110 +++++++++++++----- lima/index.md | 5 + posts/posts-list.org | 3 +- ....sync-conflict-20260509-150632-VT6366A.org | 26 ----- recently-updated.org | 6 +- requirements.txt | 1 + sitemap.org | 3 - ....sync-conflict-20260509-150611-VT6366A.org | 65 ----------- ....sync-conflict-20260509-150632-VT6366A.org | 66 ----------- tests/test_authoring_server.py | 71 +++++++++++ 11 files changed, 160 insertions(+), 196 deletions(-) create mode 100644 assets/images/hzone/2026-05-09-screen-shot-2025-11-10-at-18-02-10-fullpage.png mode change 100755 => 100644 lima/index.md delete mode 100644 posts/posts-list.sync-conflict-20260509-150632-VT6366A.org delete mode 100644 sitemap.sync-conflict-20260509-150611-VT6366A.org delete mode 100644 sitemap.sync-conflict-20260509-150632-VT6366A.org diff --git a/assets/images/hzone/2026-05-09-screen-shot-2025-11-10-at-18-02-10-fullpage.png b/assets/images/hzone/2026-05-09-screen-shot-2025-11-10-at-18-02-10-fullpage.png new file mode 100644 index 0000000000000000000000000000000000000000..3aba68e65c75c92f23e4813469ba5f588df0ad03 GIT binary patch literal 72287 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

ZY2f4=eJ1*& zD}E553M@RMt@?-flg0Cwlx-hnf9t${$1PUNi(jb`uf@A{ALT*Q+sMSdfTavQM@eYG ze=H<9ZAkNae=a1;EUz>ICuTA3n1bWOGViqFne3qOxz#DlIAbr%Bq&Ef&Lb7&G^pOi z``)u9r3%WnIrmfKTQZ@;{yEv?*676fxVJ}3nUQ5CK@o~%Fq{u$!++idc&pjs6}1#y zl`akF*4vU;Gk6y@V!<;d0T@CQ$89Yl%ijLoPOXncKZ|uskfygZ;Z_HRU5@81D8!zN zm5^ZsQlw+7A&!)fSEP-JV36sG; z0j7${52&N3m0Lz#&o{s|`B?Wz5Cq%ih_9&iQp!Oaba93?f#=F+7t6Fh=7xU6_VSG! z^&Z-s*xOD#EaEE84u|h~4?3Znw;J>BYHnqFG7r#SjKB<4KitiWl^E{-YH&+`Xriuj z$d~9*V9(T+D|=1Pqp)&x44A#9xl$w zWP*XFh_~2+C+`Bnean;ZD_#iMAS?VkJqrot8-Tie2qPTv`wbAx-vXBKBwAlhn-PHS z!`c$LZ(TFP1%JVxL#(w`qKjlN!zw4Up|08<*R-F21RFS(I)AN3lew3P1SElO%gTXJ zy}oy-gIRGKR2pPQQ=2H6;0oLtWy>qfU6gl6VyI}WSh{3nIu6y;-;`yCV1kFgE-0ex z;F#3LO;3AnuJ6)m%bLeP;YZ+KxeY2x->W|O!W)=0{me@YI0dYBX`US~ypV%mON$(J z_c9a)_bYfSG4!fV4rd$#NU{7~ouTv{KkY6YA|a5Ik!ov2FOb||L&t*sKKvsJqBU19 zr33%|)zmK=We!hazsisct#zn+AUCI>UW8JYYx$C&i(DxX+fJ$8?>T<>J;t&4wzFn$ z!RiHrO1q(>(?QXT_i=oU{aRH0_q1Qcfr(FKg1{_`=QRR);W`E<+9UKsa7<8t2iQ{J zvi53ITPEdYz214whDBiSGV<uY)*1>*N_(T?Ri(#YAP&o zNPE-DY#U>s>lX{vc}JZDO0`K)yjrio=KRWT#sK8(WwzfpBto@l{xC2QCGi?qbSNGP z>b!GIn}Vq!?6ii!%F)6^1Hc4OWkYc$6>0^Eu?{-S^k8?sJHn^8t)zl6fMK+c3wRHH zc=B3#J8vlyLh*z;fx0l;zlU%V%0OTf8kf$|{Iv-n8rDZ9W~Ua2N~sZ@KOi^uEVaEb z3U-k_a!Io^DPf}Y19h=RU>dmeW)u_L@fx9aZL1tyWI4b)FdTBRLI%~EGTrDISHnf* zdGOK*ZUwno@hpo#lt>=JPIYU!%{4F+GVKo|3&_6ZY8+&eYbh20E)b{WIZJi5`G5#n zOs}7K9rdk$I>n$z$1gSZvJNv#CqB~VZOmhq7@;Dpos0P4nv%U9l6OY33BkK=oqH0r zi`9;I|H2lxXLl!%wvH5@PL!TI?RkJ*&hHf&S+(5R#)uzUzND&f-A<&T&R=JO-?2L# z1D7N^f$iMWoh>|Oq>{2HwVAf>k#QUP)dIXojX31FfMA{O&`hF${ehhyPV23CXESh;x9xZWLiDz~hB9fAYI zG=|YzL&~#eWh`x`z)rWB_lJqm-BY`59+IPG{GHQ3myQ1$WxQ+qB_EGhNP{aHOvMFt z@?Fwm+ueL(^cqy}#3V-gqao(~hJ%3kULGz=Drxe-4e5I8#d11m3#d2y96wa9T&bgs zg{nh#7A~14wfe~|sSf|q0_?0$9AU7lBVU^n-9^Vii1$La;L6> zAg9oVpOc=+oM4(HIEWztTtOA>MqE!PWrUb#0o(s zY_n{zUY+lA-mj{|U`Pi=sU45%HE0Qx!oYR(+fCn0Yi;H#i3M6p5?R|;mGui(I%H1@ z#6tWl8j4ySh|&@>Wr(lU&2B~YwPRF zbO+u-mGnzDB1OOPvS=+O*!wK)q6h{xdmx{lsd4UIf)-@fEL<-rjoT__ zu0gRwm3bhha>a2^8JopJ6NV`33PKHIiWAB9yQjSH*C4Xr_G%q#kr(HrnX(vfu@UJ9 zCT%dlFh6p5)t5X<=Ie*?)5TUr&1A@=b;bk%Q3>m#iAeonc?bEE#>j zLJz3N!Ob#str3Q6iY~EPWTPhY^j-*(;vn;@Gt3FQ8SAe>)NWAb)srlIGIPiKtQ7Z* zr%P=Rk+?(}{#pd*wfKR5HRLZpHiJ!Qzoc)w<2S7QJK(b6Ztv7l^X6&udNFRxg84GIWWh(nvx%`U;J8Yt#G4|HWG!3+fdbL2BwORb zTYJTy=BpP+0?rUv;&X8(G0Fe_S&5%``P1g8v*jOf9EeHySdAzcazYy}@;3D93fegd zUnk%Uc!`=L6c?RFIr>-bE&9o6_W!0riLh*NZsF=N^DBz8UJ>!J<(&<6lS zO;7cT04U|7`18WmTYHUOwg85w2VlyNFaenCzn1}Q!SPU$&gJ0Ezbc6Tl*!>Mz}WQ# zrPd?IvXyC?yFbKU7{2mhTw1$JkjA3GxW3BNy;e2l!Omi;?|7MImsd8bI02u|1^`VD zhhGdB{tMK<1NqGovifpL{vFy)889-Ib1L_LE4@G;Ao$A#@nPqF15=OKfW*y6@qB34 zpW6pV;2~{Se~bA&IRNVapWpcRto8q&xpJMqwgjrWei^TJasp?PCxJ%JvZ>8dJasSM zN6-uRn|S?{r4#q@Ix9c#vkcpvv}g+=t4`pvUhw&;^efbSW#Hx6a}Iw%-lXZG>S?=j zYfM#NrhMFlu(C)WI3YMl2a#4B7)Kv9KR!%LVB=@I6H-6e)bSexXn8rK)L!y*Q7l*Uv!T{En5{MPxa^xaMAp>sJ^Szh#Fmn3vF!Yy?+~Z&4 z_9cyl7M&69Ac~6ftnTtGjupUi?UF8dNCl=G{E}E5F4`8&cwyrHi9&ufgdMq5lKT2% zC_ZUp)Of?6JkW*sYeZD}XwTo^)Lr zF6Ut77Q8gS2w;4}C8pvNpgy2C(VW1Dkwu)*Q$;%u!{chy#ejKXPB`i@9_KBINECTq zyxg`YetI-8Y+%o=Mb(W5_(x1Ui^z6=37>*WgSOs>J2=T%@Cl1lpM!kkXMM7QPSc{k z4LzyTNzCLm>sun00_cINPDamB;24kkkti4FJ4(s~d_4sKeXAbg!RNqXiGYR;Ll+b~;@);I`sj z-0(}Ox!Vr$z8$V>Y^esrX|L3oyqF{MH3kgFhcEBh53`*-aVwSpPWS*&(+rjNAyERpx9*H6rc?97hCnMQ!JC7)aBdK4&kXNOeA;JD67D& z`!inU&CPD&+4ZZ7V@S!mRBTx9z5w;}X%A}?WqIP=Hw&^ko@%?{3yEt<_nkJ{)L>+l zgGETQy6S$zDr?!T@%|3^?GM%%(1MI8&dodQ_{% zW|1&uMNf*z;m^Sul;z=lHX%7zsjjTm8A9Wd*jn$k51mKvS|QT&>HECrjt#G1wYv6J z_Om^54sT8>c}{oT8K6fB*z4$Q%Y|Q0K!zZS3%+`O`xJ7bc2H?wJOflC*_&)p41<>S7fS%~8hZ;IL+T6i(} zyKf0uMkRf|nEFW2s;;Sb( z%=?91JQ&?pi+yz4NI1VXX44B2sh`uUwOJwt-Fuf_4EGH(6!e^m%Z4MM&vcq8@7S9F zZsZ`}lPw9J^OLMt-dneKs?uJU=}MPs)xC?*y=Nu29ejWvYAo3hAbJW&tq)VqZI^u_ z&hKi~c@|s0iVYZUh|NB^tihanXu4}!MU6BZgYvpHFTWv$z=p)v#q)U?2{EN!sZ?_# zmI(1F>pC?zCr-jaSjM6HZYF^kEZ5B!R2}rzsdsm5zEsupGGno7VZo1>ap~01)Ir_3 zaO+Nu+_Bh%tB`1Ql7Rg}>YICme5>&m5kJkWw(tn#!ohvEwYMhR`HO9McxT3NuIwbG zFYZRfgO$8NSRS*ctBmQTKG$1#>$h*ROl%wL#$~@|N4{u1fBE{4(`ok!$K!3uk<3No z93_ktQg;j~PIc;gVT+Wr9Hj95DvB@?`EC1;K{Wr^=MR9n20{f+AB8riuPaknvoa}m z@3(aPMEXw6$5mu3ShEs>YsW=7O04kC3i}bB&0anu$*i}s@TXwoC`G4=i!bg|y@L*F z!%+qZ0V{-WBERi7>B3lU!-KE9M4WiwoT|_cMcywuK)e8P9x-%+G4bSO*mi``Hc7$F zoNAWaY~jpA;v>Wx2c^d8X<~cB#M`LzmlCDonDqwiwY^bFHEA3&@ZgLs{>lD;x3kUX zI2+vyimHAMWk9aZUwN|3RFi8OHwhoRriV&YKBR`yUzk>I328kq0Drn{Ky}ZdqEAlj z(KHy1COinD+ z)G?5Ee}IGajVZBT`0E)-5{?Y>8f zNDjo?m@F}V{efJi%{o&C9GY0K&-d{AM@A+UHc`!+WtCpiYOw8Rr<{85%8I6I>AXRC ztuWZLuARcq?j@_w5oF=z)9f`PIQqV$p=&9Km3*<6ml8MBa2lqcd%b$&G@s4n!;1`t zB3-xE6jJM#F>_m+IN1yPMDWxHrh5r7oY-!hlhP;)OlUBEsp}dlmMpP}E8SkxxBrkr zOt*N^J4ZMfZS)%P8oG8lk-!t};@!fM+RHc5d>Po7K08nILy%0(`djXqGyk4=KIs78 zS|zRA`P;V^<9%zSH$owAR@qmZjg}v-3FXq1O-22vn6!OS+qmU}*w;q9mR3tKWLmM` zm*Or-SUrO9X>;e;X$6v@h6iR^f=-t~vA(oY*~J+=SU!{!TZJCPwxq|hXI#g2eF#~1Gq4na^eW9@)Pv#C{r$1pg5JloVN0Mao8ouZ~0_^ckT zJgA_|BH-t4%O^X6N98?IF$*J*<1Q-vPMQ2FZmGzqwu~%wsM@(}D7VxN(aSDgTad_a zgBm|vDJbzut^8Ds8mH_)U4aiL@($#vyrD!ah@`e2gQPUjWcVIyl5>}(slgI0S7W|w zHh$v=G}hBW&Fn-i$ScZzTm3lzRv)s3Q#CDjksyX`mbLbYRj7g?hm>K~b*WEbH~8=4 z!g_z!-50RN8ucGq+3$mlI6(vgIF%8Ua25&GNdHwL<~yR8P{p*VFHRTx z5Di!c#I*H4j!5=GAod{hbV4R(1RVDRnqSY-Mm6PHvtSAwFsX%C<4kXXgvxwBwa%RR z_mpi8Dd;)PuaTo%P5^#5FNI6qIZbn6-bYDXDR>-esY-vhf(THm`wNiA_W2dbHB zc=;NdSGa)S;ZP&wGWL0mzmoTmOUp@M%l=aw2R$O^kmE=1=ohW7KokeFmUA&mrZHE_ zm>Y-6j)mj0)pfX2mDGstqU;96K1g;6r1o!a<)vGf>OQgES*AwJIGB=uwgih+`*Y5r zbb4Kfp)x&Z;edB`ZK1V4>IdcPm9cb7WI)bH!B;Iz*u#xlBn4!iDwgwywrm-}18>_K zjqe^ziLFI_;e64!@Bv9D8CcOO;H?kNYH;uK+#}_zMuWQp z=71cO;S{gIy_&b`TAkJxWpUm8+j1=~z1Xn9IQV1KF-!o1vwWA<4>zUnt+b<^G&;?B z#n2Dj)v5N`V$Zuah$qWpTJ6?VfC1VT8=xPizl}ChK4*Wy#``C;9#sFB6u7hfB5$=y z{^!w)@Tx_%1Ecw73KDRa<=)?HaQ{te5Kf=1fdDch35ZX{rGi!>IQ8;5Z*XttqlR+r ziu4os7RPM=l{5%FPO=2LtKFUp8?8u9-I35@&VPG%26Sbg>h`j!wr$s7T=tY5@vZOnO}Lhl?#;ki4stkhJSswYkPgU912J6NhrBW zs|=+=bg&QBIZ)&V%H4KckRlV1_$%Rv5(+Ktb-OLo@1-@H=`8m>PdJ(J+3NM}3orpe zh`9By^ilt;4Pc zRD%hvAIr26b{BrmCg6P6Q;2HdvWL}+!G0uH%!#4H1$v{8-sFu2`h^ya8pn@LO@&S| z+zt*2-$z{wp6WMG+4POvOm@;M9``Kq-br@#aWyvjIA)JdtX)jdKNM~DK$`iyL&WnX zOeG*4=$VJOR+%U^3qz96Dt&ccfDenbFOpNi^hbhoEE^wRCG2Y>dE*c-F{^SFRz7?v zM5k&Iv0l1yb*?LiWSXqubo5NyVX&}*=Tg9gc2wp0!&UhBf!47T0YXaa7IR-YM33*VU z$hm`$q+fwT+b^lY$nTP0sdrno8W>`=+9H<6bu#%T)A~ij#R;ISXDG6Qb@4_KvDJ{l zE*NMN6#w!&VsC4%s&OMsKBGJsDi!@S!{`|$xtC(x8|R>pFJHW_c_)v};@Ob@IJ=+R z84`R11RI~^GF-T$oMfD$NTYXd+;;Y1%6C%~QG8Y;@_fL_KDG@Ox%5SkuZkpwq*Q3Z zL+9O6yAXM8P_HERmh~wMvR>-P?J9ofS&41HLkk|!Qv@86Tjw#c5cfe1$_{?KA&IEO zME(q%d8f={i(!&|C^wj06pRa2pzM)ntGgUUdX_tKDdd{$ATI%RzBz}6r&Qjp2Vu7r zcDb4(=R=W$QSD-O%K91B*9%0!5LK_6j0ft;u{@=&m%sL$$WTt^2G#nHFYk*aLSA;d zxlEQ1lW0cN;ok7Kce@A*+?gKbW4#{LXIn*OEpmeE_C0vnc#rHuR1LPu)?Rk9?%M>^ zp5C6po-q&?ji%rkTD{lBWl_t*btANlqdgnVbFZJT&Wc5W&o@}YjX-=|F8=0}U=_OF zPeEBmO=ICNxes5?p4}TZbgIl? zPqKNzbdN`-^_K?+-e9(QEr!TsKHgyN(^~k~RKVX}qYDaHhvFLrJ|Qnjg27ATBHp5i z$b2r>t0rn{_H@X88!FWgKUk{aJ5N`6R^Y`ofBI#9ib!(ykii>nY!rDU2lLcpTD3ny zo5{=)vDLvF(D|zh4}xlruDe-R4l_kLo)F$d2%g^6A(Q=Wk=a+?E{$o*n;cW0r630{ zKdXll8PtfqsIOD70Nj20MixfQ1~|5|WeSly1^3DnDJY7M9)7 zCaqkVl$H^+4#OijJ4VJazraAaQjPmlhV*Vb;`4W8v-pucQ5a1(FpiE3*Zd_3ut`nr_T4c5yB3p z#yJb6{`Z@Pfq4ug2(ey&I)(44I_TFWx5tA#e;WOiKuckC+Q#3BAc+8Do_#HI`R^>? zr{)!ClsGSi#@p3DFHr4P2GbgalKT5i23LVYT&3vU{@ZuZJE{L$AELt%i~iFuY-k`X zG(+sH>Bj_#|N4AmA=$O(F7U+#O21+vuyfb6QbWDG4uI znP$=j@SimTyJWTlaD{iP#XnvfL^`rLmi(ADb{}i!s$VNxczKRA9+g~J3rwcveb6Y!}_>ONwQ}{d%x&($y2DYniVBFqtl?B)CFC?LrIE$hef2Eat zL5#%IS2@(oz0Pr(Y0B|EJ(1is4YwBs21XZIiM;t|U+b;G`w<=|n95(%p#b*mK=?UI zK6-^&J`4fm=4imJAqzg}N6Z?1>qXwt#g57wMVwb)u9u$OFk$U0zcy-{ zVg0O!a{H6-h~`S7Ns;@H{QHml%9oxS*KUSKFo-0AVPP78HreBCqUJ^sty0WTQd`wkppkI_gx(o(4Z~JP1tvpVjCcocfmk>cs{1TLHe+h zlL7GFaCON&d+_d8BDU`tHSSqcphF}p?L#b}U$Nl~`qxKRG)J)J2on=-mN&@k;!OR` zx~H-j%`dUz8=9*lxJvxG+p$Qa#{2kxUfMxmVXQdAi~jaR;3oLY!4{3)qqD9+QJNr2 zV>}2n>@*8i6HoZ$>0M-`5fdH@37zz=-FL0h1F6fxSy0;*1FC#(Zf*-ez;qX2?V0<> zyEE%dnkGGW+Ab~RWqzCzr~ab_h$!0~85v2!h#ht(zxWoiFyYi(x%>TPBd|Dh-DXy47tQK0N$^#C~HS$<=r2*;MBaHsg$!LGr>20*AIb((MI|z=?S{Gg2Y(5oC zdEj;r&;rr5ARVZ~irH6ylsPUSJ)d;736Ic9e}W!tfl-aEnxPj1h{*&2PL!yk4{`0l z0(vPq^s+@A*ivW-6(APRL5Gv@QggW{(=MG1J3hJ!0wO@+o`mP2_P&w&+Z&1CRpYL` zlEeu>NvyY1J&gbtZ(YEKh?*1`c*rM!ee)qQr`j@%42D(jA~9sP+XZUzdso?2lTm6% z#Gb-yrEQn0#LQX=C&)B^YCe)pRisr+xs#3rVniW#2SpYypmmK0ybao?N6)MouuoOT z;)VICwWYKE7Zbr)r!N7CF&@6EDsr5ts$3RHfju%D)dD=!Ws3TWMgNODr8sqJLx;N} zsn_g_>jAg2e%$v?aC36BHv&%sbPG;6RHb&i#%07VS!<5{8Uqf(?hq4ion4)+hL=B& z;dSX1&->|LU9jkyDV_x2P6Z;cXE1%r2G3nC3IY%biJI=a$ z=M)U!#Wnz@1xN2Xl+q5@&9w#P7IWL$>u6)K9(Re4v|D=I<8wz>Mn72OCgzS_ceFxQ z*$#9RH;&$L9pu%wKj13wHeYR@)-w(65d+*DH)nrDIrSA`RkL;TfX@J&d2-s^3gH~Z zIR{)8EcMMDE1t>WmpgHD$*>+Dzf?~5q^89IIFR88y=p)ydX~3S8;-j9ZIX*0ZAk~L zXE)yXwvypkc<8eEK&;EoaJ;@adiOQv^9=Jl!D-a92Az_y@pnHX!S81)WaO&rQ8(lb(sO|VNay3~c%^;7 zQb^4%SPSDAiVSk28e)p@E8(nT;F1g)RZwi#E~EMR+uKe_U!eKDZxmV1)OR*2X4ORx z&rw0lY%!Ut$)3T+(aOAygQ2DOr=Gp1N+9O}i0*yPCUthHF&#rkONK+A5IF>^KP$gW z&X4%J7HcpPgzB>&2$>?l{*EKx)c*R)nWW59`{}_51#w1?{VUN|H&$e3+tS0f5Bubq zDvjP9%#H_d1)jU!5<>Y}s1_8jg<`TkGR=jp9tCG)DPTCXa`enDP{jK%H*Em2LCZzo zrJV{5WPWysk+ZFf!Q>m8;NT%;P{BaL50vP4*;AgqJN5*sd%^0-r*Eh(lh4*5cUa_1 zz^wwS2;qf0cutbR@P(YL+ADb>b6ufbTF*6h=$W}e-&sH6Zg9=QhI~v&J_O_{1y1@vdp9 z?WNTdYg!5Si0k7RTH?dq!n&F-r(B$8Tdn|#k=O@Mjzx)UJHcT z+^DM9`}Ssn&m0Kar?mTAL)c@hPu|kCSElaCce`}FYWau@#^Gz zK{5)01dG9-Ef|`AARf;ghNeA{CUO&^4ud7#Ev4-U-uF|f#ZcH#Jf@H;AC9dM=%RsT zHe~qUUi)xi+)pp!&X@C$4myowk8}1tWF1!Ik8KSr9v3Z-UP+QFB_eFRsw&h1IqA-R z!`n3a>)UlC`Wnk%xtMG5UH9;hKESnGjTg@p7w!hv3qlcAMd&*LRIAidFgp6B5pdFQ z9JwQSsr3Bz^I;*m)zGKmO{>2uxYvz!zk0SgDJL%_@K=AI?h9TFn=$cRw;VAUzBw#E z{1&g_KQMiOef7UZp#Mz>hmZ8W>2(arL^Dc}`!n{qLn4gmXJqU&$tM_nk6gBgbWO)j zcI8{`kk)yYe17|kw6wZzyL*LE}j3l~i6 ze{OQM55$=j)ETtdAY^%cTV5uxLTu0C)m5g2IAiw&H}$I@0=_d!z6<6O>KA)8FPgCk z0xtX4qzraUetWOpmM!NbsajI2I!ioUFzBF|Ym+^Ovm&07GWfGr%|jv(2gLUD`!X-C zq|ZYHB_DJ2?B^|osN7rFxTKK*rD&Yppg9-?dbj+QY*j*vPhO)ekHmLIEiPA6z`OL? z(&#||aakk03|yVl_q%F_p;~)=dIKt_#ePGMZ@AHOw~E3}X4Va$A&^A}Rf*eew``kD z`xlIjLgB2m6eW*7PiCcz#&VJ{cfZL}P+KGJBTtfhm6?T>JZOz~Y}#KKE~YgEXX2FS zs*lmqYwyu#!0z)_-)Dcm=%XrOi7EZX`_=oGG_EIEN8nwnmaM52?oB0|WB4=7o9|TY zh=Z!Oy6y#XhxjEG!3)g2TB9#p>q6cxX1MKp3@2_Nm)G8S#*2V`pxRh1c#jQAd-!=7W$jPh0iMb zo*N^pvKv>GJe>BpzRRf1kRH{dz5Cqxp7dR2ZLk1BRd&v61^h4&V#Lkd7XZV*V`t;a8J9ZhgDF zvpyg79wF)yq{q+O#fJ#VE3*#IYvQtWx)z5 z93?=Oz)2E^4T!EE_2VrYs1~ADy=~-*7NF~g9l; z0vCsiRv|pOb@m{xGN)XO0v2|A4Wf}1cFr{%N9uC*Y_tH<#r*p@+&!P8ne6DEGUFMs z@?ntlN*mj4kd(Q3b%R|hZeLEx4I~wR9aHGS1;=t#I%4~LM`8}9ox{px)O?@R@19%k z|Dq}3cg~)S0#{7l()F4_^TGcoqajIP^HIm4%+lo3PusJ3J&3$;$|!G8xMgT6^j59CTS0gO$OCRh{dLsHhYAVQi*QGqdh<9!WMF_Mo|6hj@onh_E4xN;w+d@W<{}~oUC-6`zBZ(EMILb_ zAxI*Ya{0?%Yq*UxYYB(G>)ZWT3>Lg3P9(cw@M&SmW83YwD#Ycr3P9`We@J<6NXmeuj0$ z)CQN%u$nHptcUKeYNY`HqLeR(Cm3-3IWNAA1bd%X^0S!Vr?y~;tE~7_T0o$)p!p|~ z)oXJ65^FBj2%fs73>~8uGc|1ne;QJ)SETHScbb$gpF{4D#BUr)(XSar4ouR(D0qT3 zZ)#qlxcD=`dTX*`aSq#=uQINbp(;!q#Yabx?)>ikyJ+n?lCwe>;gYw(sd-zHE7JXf zb*^$0;>%2ZNhHxEFd5i>20QBo$BvK)h3<0lZwkkua{9@HBMV@5Gci1fX8X+Ke@4B=+pq6i5S3RMVr zq1sHrw|BqKE{tkNW?b7LWVQ6N?qmXTkVrn`An)o~y83o%axDrSmxHTwpKDlSS)*k- zcfeiA(nXegf--VzN?q{@&by{%IvS+#yOzMU+Sj*j4-Z`Q$@K8i`t^)uL0%Sj(K zhY^{xOHm6Z-$by|TMTSTJjx0O)@LJ2XeoG+S?Jzybb~8Fy=qd>V0+D@`e5v+QiTvT zi6n`rL)}Me@-wunLOQm`=03pge7rSGvV)O@*(B|w*-0acPC*p{DV}=eWAqY(x9Rls zb``E}XttJFT`>+%ssAaj&Hj`zJpz3#x*-bbF@2+$_et9Yd!i(nvf+iLaXA@LI@Mq- zZshC=rVPW?$9GWNHBgoHJY_;6dKVa(+doEDi0*b040wx7Pk!`u0(>yt?!Z=>tM-VA-Gog|aUa%JvE zr^c#`n#`?F1fLXGN$>)T)!UsR5jL%3uTS*DgXic*m4Y5(LG*%+l6{aJwUwM`Z~ zD~&l52eV?jg6Zu$pF$o&CeEHaKT4uMt{BZqz~C*d$9zSgfXqjP;+KMWsKgR$9eD!z z@`#ahHLSG+}9zqzDfILt)-YE%|oef1UYd8};1=gA8_#mm#-r5JXjx zg0v2yZlf{y*eiBP5hf#lg;r7K-m+UloT!KjR>tU6{u}q#vS70eATYnVSlAl*?zw7> z0w&8t!I%UaoIe^)XOa5eqUCyL4a<)Y%jeF%Rk`L;ScVV%ISo=V7Y%WlN&^cVt30lO zm9IZoZ+s}eGXf-^uo!L-_7}Pqs>zJ9USgGUb?4fCcMkxDi9k-%`(*7=+gT#X=p`4{ zDt%rKFj>WDMC2aBM>+DHQh5h1N5_bJu8ViIn08r<>s4SCB51L48O&0BM7V&yqq65n z%&+OK{b(pcZbHSlLF58ptdOzXu zJo9ro3!!)-0&I(7484PDAfIlCD0}|_IKNce z+J+4OaAJ*wpRm0AC~Vao|Jv0mjxfyzw7j{6 zI`}&YcB)|d(LoZI|1Ng$h6GO}ND#}R|AOjy@t`G?0!8p=41T>}5SJWf1{wdf`~%qI z8!c}R{s*^`fk!S9^H#3@LE`g-!E^{P5eWQC1O5A#SsnE29K$t%|DYDkK?|o`9^`LN zrSQ~31%-y^-xlyj3QsLWN2!baZ4AW|S2h_awZHiA0-jp%A{jjMpL;5S_j=DB4RZZy z^b5s%y=&>vzY{?c4#wOoC$moRr|G)) zw^QH^0iIgu_0uT-+X%(?)ch6d??f>3Dt7+U zWFM!3{Dh^s(;MU{hS#&Y7t=3mNMHV-;zK9xlzPi&n^}FM4j#KiJ02HgKx$SyYd^M- zk;;93o`S0SS54rHxQ=_DG;D<(?eg_$40=fZOIOIx`{CimG&@4R`Awix=Sr3)KYZsUSZTL&hwFq)Me;N+`9H<$4uSA4-NokOp{Mbj%z;i*8+Y&cZqz$9?|WGfRgAO zttexO0a$tbRW;E*dLXO=YwG&7O19esEQh30TLpo==K&j|LMw2KoM67t7|g#P7XBYh z;oo)r_l?a>0$mf2Y#4^`)6;GA{iMd7an4UUL?bx~4|*)Ajco4n*$2@+oS@CEUZ)dZ ze!l&^hGXG<)F+5B{Il^vAxz&)KBoxvh0SCjn{0fy_lz zj(3tR8n8gNw^WmDfE53chyXzR69C6D)(!4vEW};#ji=ykd~}ld3u6uaZ5X}L`0Z0E zGrQ`)&e5Mm6D)BVe5CL!)}K*Wx_%6O9TvxTwKGy6)$3Qt{%T3HxjholUuZynIpjFO z-qY?JbuE-Aiqi}dzyX1!&Pf3Bui)8_LG8#Hvmk~w;m?Zpl11aF#ZUTICE_O(=KjnJh1A?Xq_GLJiA)uegn`&Ii8$2 z7VZOJd_54CQcuUXYmies0N9{Y%qHFT&>gMa?@2qSZ+PnR_KTV-J=O#B1K(LWOs^PR zAVhjB(3XS5FtN_^1NG5)i(^(v+?8`PzNd}*Ko=jdISKTeR`}#V+u&N$XjKomrm_H% zPzcm-HhFG2>YkHLqbJ}t!Q!(wq4BWy$>GdtA|9@%e~sQi0vfh&W2J6B*3f@t0wh*= z(h*K)jr2LNE&p;WDIO$*I<}7swJ-H`)L~y)S$Vj-F@**bi*&P9Onp!N7^IKk2idR8 z6n6!N-gwu4xt?mnv_HQH(j46f!gr(g<|TevAF=vVko(grTwwT)u91tZ)|yhgBWd=j zGS`P!`T*KS&&QdXxTI!K(LepnvHGo`xsz+kfJyKjMxdRxsnWAf*tU52g-a z&UA^pvjJoVrVl5o9MKx`4Dcv%5CZ(ldmiuYQ?9go`VSdoqCMkguXTS0@!|fU?@n4i z-Eo@j5GsZ$J1Fu+=fnTi)tSdb*}nbXGH!d#*w--jEMsdZyJkp2Bn`4f2H8oGeINT$ z$zJxlRd!0*VkFCCiLqtNma%0p82qlef8XbMJ@?mt{K3n09p`x-bG$#F&q;E-(QxDX z9^8y(z?SGS{;oh*iVQFZbAtq9fhSv^n~XUNnnpXf8h!?^=g@KAt?uY)0Jsp~L^;H= z@WW-j>zF^klO{!m+Iwbb>A}yYgV*1((geJ6FsiJwm`C-pSzkcmTVhRaym*->H`vI@XnFSBe4zSPmxfjBm{l=(ngadXl{6}Dd za7ydl+9+z1MFxQ`{ zUhCQlhdf080IrVZuiI#xnzZ#Iz+Frf-Y1du*ga`?`E2GwUqk=9?2Kb|#EVz-`8}Og zvN5G1KSvadpPjaclLBKFV~aK={a8J zneWNhUE>+pRt|-ylZW0!2OU4F=;LFb84Y1nDPP63xlrt5t+F%@UY~aKcLC8Ps+n|i z=W`A4EtY>7uq`%f_uyi@Q?voAQNPvqTUEY^jM*d~* z3$vkREF+ufR5oeN5R%UmtK3vG6Lls|%>pVF;1d`h)atKu0w z_(R!r!ZzQ-Pu$YM!$L7Q=yhp5m!A(H5!JV`eCL)D3K`}{Beze1w`~05cHmG|!yBj{!AMIamSZkWch@_KD+qLtg#kxbRM5S3t70v_r<8_hLK)v6!`kcO+lk6F-#h=%t-|9sx`#W3v z=V(J745%*LR?f$!!6uU(I&SNJmeAijwOEAeC3~6_@!*9vy{-?d#Yt7JZ9uWu*k5_j zqsJ`gO#2F;86N8+nt+Y{t!Y7}(L0gm=yoXR1_C))-9?Yf&AOe)p;=&;N$htgb>VO5 z3E@#u49$R95p_mPfQWi1Q&_%o!0JtZV4vrybzs}0p9MIw2($4!+>j0>^Kcgc|1SV3 zThF^4(nW~mP79Y6SaTMz@^{jzyGsW@Uq7!;)Bvn^Rf7+Q4JD0ZbJ~lZ-Lab}e+pBY ztC+6oqBm7YWzLngmaI%%HAGWC0sOfWwz{R&?bVV%|L~=fI&HO`n-65pRq~JOU_!Wa zTQzA+W4GVw%$Ufj4la(pQYpjyjpF4bU7ZhxE`vECZ&1QP@c6@40DG~fIhY|?-Xf}< zYL=|z?HgyqKou#fKk@qb8gTP9(-_89gaq>H@VmOfD}7Ag5SMEc*p0v8q!=zwn-WEs z1(MYF*n7XtcO`shh#IAx1&U=_E3Z2ZzH?avAK8Hd`{6o!_7L-m+ zqxf@zRroFwZD`Rjp_5zbB)q2~1Gh%&`66_G!n0l!mrw}lpuw(~Y)joH#vB8tGY?A0 zP6^icR>V$R4zPgMz^Fk8xoJD~g>W&p9oW<3cG3HT) zZR$qj& z>P^-N6217hbnsCgp+u|3Pc^iQRpXvS2g;Sbl(Q$?I8d3XbrNX4e$L5!K^s{JFSwe~ zy^UhP0XAXn#_KDy-RG09#qTfDV78+n`BC;9ubu~^lD1`rvt73V)$xa~(4?-Tx~!1r zR;|{9)!nMse<^OsdN5LR7m1wuhGErHq>So0nN9dG^wnz3HrB zPO?3_y_S{-oO^C0jy2q$bwlK>W@Iv+!CEBh5@94D*^f|ru~?Fs)^SA*4-x0l5Wq69 z@kp`17*w3&VQ}aTPx0rKlC>s)=B`Lk)64?;2K-z=TA+$CvCHk#d>lU?7eZiIpld+* zJ6wV>I^LColLnk}Ei{SYtB}A#nMv3%3OeXxCl=Zr0YO*tE2b+S-^8!Av1>xELp)zh zGn_}fLP{#1^N*p|Li;)R5NQ`3YaHlVSQM4GXqjkavT`x;W}>V4z>zzaGl=qmjSq88 zViC@=4mfTD>~~Cm5Nir1&WG@)NV!!u@P;s#SeJM*zaysFbJ(+d0+|V10ImNHIa-`1 z&z7Z_T+Z*{2%KdH{KMGi7lYa224Yf}B(y}i__bhrtXj#8DNyXQXjdZ5T5^aa3M7z*G2UdRr4XDd-!wn zB3y<9Q!g|Okio^k8avKv1nuM*YWn56?%IJ)j`r#x$;skHb&-)r4()e48%v-Nr_K{! zdx;m?A&OB(nFY%Qw7?KQcJr`GgmA^kX(jv+vq_M?Z)Y&I3hjf8lJ56-Qe9)$3=*k@ zD|+W^LY0&Y-HOB~+=qh~w%m7*iyFgrm*m_+77D){^<=lKF4IEQb5ujjB&_)(bM(}~ zh>7Y5!CFzKsrz-hlWM=LicZKUTvL+Iz;_RbRW|my+-XMsw;=k#79yMHVK;UkNwTyWMHuhw`4aB_8YkcU= z{rimER#~;O-!$kAq9?z(=*V7KzG~HX7+Lh|=`E9*dk}-i^R(UGDX`e~bl|y<9X*r| z83T0E>)r;gevy`l#(C||gQu#(We>*R!PB8Ke;~e08P6KKIfthfvIAQ~$)gNcPhHO3 z5y3~E9R^AII_(&HaLIR#;+_wjj%y@aMxx(qqmqY5VGc36@I!n50d0OIhSF&E#h!BJ zE-R8aCXX!exkoV40L-wM@e612$I9ic}bmJZ#ytW z0BpGbjBBmeg!QpGAlt9JcdwMP;4oAWPtoyO{C6*=C^|?t!@V#^h|8ajv?!hUP# z*6V|Jm|^mERd`9*XzA`DcoE!Uq`5c-P{dQ<)|gWguhTb;4$JCWT#|&uO!43=isx)} zKu&j9VSixMKejZ;RzE{6^BlS|bw0h_|vnC8QtEivhBPrM)hGFE4c$=><#>uLq) zV?S6dT^_ecOVnfCVM(ljnfwOX*3N=}#jtCxaTiPaOZ1xTn#2GKF_l0-f-Ajy%*sf9_>5V=#mDUaE3)SCXy2ucNM%e4Jq~rZ}=0j6w~S4bht~u z_s?5o=*l3rREO@yf z@}tSWo6eWlXa)eiK&Dy3!#%tAX@}d<2USH?VH2Xpw(+sI@~qDK!i{IX`fptRJ4v=N zhWAfbiAbQ4=NpkoY$CBVX_bz|yVFqTCeU^%Oh06S6oj!W5r*$rsThgqqMTPnnK;6E zblC*9VvCw5>4Z#FK6?_?%G`lNwruA~4Q3X`;FpRV5-1M4Lu0wB+5t+9?<1|yP;L8) z2C&sfdPSS2@Aw%=`oY2+SJoeSrm|nnB2Tyq8fqC4i^W2_?&p2sUS$e13}$ zLwvw661(PBrte&uf2lz%AM_X>8qplzS=3aDDLhT(>hj@I`BPItsei*K#h%Ig8G_6V zYx16@>(NhkJ_ugEp%xPqbN&u^8YNtu^z?y@9)D*EZ1^x4^$YyoXuxVSsW9O-{(KVh z?mRN$alcUqV+kNj0dx!Raoj?Om(?v$_{Bjn<2wGHqA*dhx@LVN;9x@^c(H($PgI&m z0T~xg%I99#PVGEhme{$y&6%k%H@&KT=AnoxD<7a{?E2~X zy5TD}*Be74=!n_#;ZR*=1~=!Y0jJjWbnvgDt{?S?lAXMIEIk||3G#q+Vr(`_E5mXd zV;*AM(N;($A989~4X>G~m$m(VQ64@?1-A#fh-zDFOrWBycZyc1rA3>j8~`M6qdL&YFm zm})T}knV+7V=xk^7am_89mv5QD!{2ZLQW5xXOFoh((of7rq zmq4ATFTY2hE2ixfWM#CMxUubfluHF{N0|)2CFFwHg7hs)`lL-5WKsjTIP+Hm3hOy_ z96O+T98zi@AsP9TDQX!U5`)5}81-M9`g1;Oo;eykqBL^ihQu!4l%XB^9ZY=`PoSO1 z^N+k5AQ~=Ky%=6s5NP(r$u-k1)52JA|2rzY;|tmTAw64#DDI0I>~Y6d)hHiEvx?^L z4dWLuVmO zp)GSOT*7vLG3X_1#uSQHfsqM#Dta!l-{OhiKR4rfyMi#k)+Lazs^-B7rYHf&CBmFk z8L3!uu`?<1DJ?@dLJgWIjQvwvK7-i&llk&3;%?m{Mv%*-|4&hY7#7K`a@1jz5u_Jh zEmGWc_$YUVH>>t81G?WUeUr3k0yh`o>7pI5 z7OP4>TK?BDKw-v7(23@~fES_EBmRfoZ?zeV98aRo9{oaP?=AB0^v+D(VSto$fvF=C|UcgVve)J}Iv+7o3mx z+))N;W$UKG+0(I?1|_expX*fMUD`H0Dgzp=@FH07AODcIqj_7Y-RBmyNU{5RtTe`9|#{?5< zRTIZBx&>y41!Ef&y-OuwR|4IIPj6OR*}cFspT*IyMcIZu9=y4Pj1&IV){N45{Nay( z;P+}&_0<^PIl8Y4VbEfBVYWKHN2LCKBmfi5r zD6G#Q(&5$iMofk??zQ=@({G?@LB-q;*qvB!5%SHSuJ&pWZ@E-6f?BTS`k(se$b>-V z`)H(FA#%He4`zQp<`rG7mFO7RaeTL{Y&ZJp@!=P4Ri5gfzH!t}^g@G{uQc&$G=Y<7 z-^Op)D9R#RzMpn;Ab9@$dBgQblcX-qo}v~levgPRwKbj|^!#&u{?;dM>oO0~Z*f4$ zViRl=3F&$)E*Eyo@*c+fn*U$gPGNA7SPCbv!EhgZx@~EX8$G%F^9UvV4-PVg-5U4J z2tPghl7|h^oE|+Ps2sLauN` z@qs7qcASR?tbUJkYOka}yi`c?i#lnLw z42>LME*CkM#YMeO3p~EZ7pBp5lSx4TwoTe5dnA|v9F#yMc+f4iQ3syY)vzP>~V(?@73?@d;Ap>=o ztP~l|A24~IFL*o2EfJZEDMa|P@uhw<72{f?I@x9T(p6@8J5NWB5S8w0K6!**;T$rx z3qiPKwh7GN0(3Zh)Pcj0SW}T1x}nzy@49u#jk@wN+|8+VWfucpNXyVJSkJR%QvBZ_ z<2#wb0va3$1ZQ2DE^#9Zh}RbRmSz^oRdGbIY1X+JPX)U?(HQRcEN_5ZmtSOu+(s;H z(+f?QE|vpmR@3`5S4pwOoFZ-lYf!_#XAKP?OEZ^J>OVSHT0kO~uf23BmYi?M7mwe~ zpFt9SE##{`dv2@~I8@tX|M`4U`*RyFw-IoiNmgNmO2;NkbUm)~H*&;-wJqQRfc@Yn z3V9Nw*r%g}>z-38J-6Qe$4UJknZmLT<(-^nbx>mI_B~*2+v<{T=Vc}odS{7yH-CD7|D_Zde)3@{xgq%CzaD9WSo>i> zzJGQgmz~_?_^Ye*{=g(VrzG{tMbtkEh1mP6Ia-nFo(iBgYX;8*YmWra#7PUIab*2B ziz1!N53&(BrXF!(cSYys(nnhsKgXkSY1TUp% zD48$=dK65^ar?f=o(FJ+j|=b-@DgCsd%kMLV0L?0fH8)k&hU>k0YLFRITc#BufNQ1 z_#03j$2I=?s;_#}OEKWg8*>BbuiRw3mVB9a2* zkuQPtspS}U69oX`B=agcC-ACz-8H5TAmE3HK<8h0>$2;2VPzn6Y^v}(+5hPC+j5uU z__H*f%0Qkdd$}067-Qk9-{(Y>Mx4FFK;LYeu5)RYMA^IAi}5+R7JL-Aozo{6gLU;E z!hxgzBqZ7dP3wI!a^hX6tj~vwPuTZ~ye#}LA;4&q&hh?+F(tE^B3}V8@Pnb4ICQFz z_RnO#OW&pe6o0G0h&wUdq^;@4s0MKxMDq%lhV`&dX#EVH`juzCx-rt_eF1baH2hS1 X`?3rV^L~RW74T( None: + with self._lock: + job.log = (job.log + chunk)[-200000:] + + ok, message, log = run_build_commands(append_log) with self._lock: job.finished_at = time.time() job.ok = ok job.message = message - job.log = log + job.log = log[-200000:] self._recent.append(job) self._recent = self._recent[-20:] self._current = None @@ -643,7 +648,7 @@ def save_upload(filename: str, payload: bytes, page_path: str = "") -> dict[str, absolute_url = f"https://zainezq.com/{rel}" relative_url = relative_asset_path(page_path, rel) is_markdown = page_path.endswith(".md") - insert_text = f"![{target.name}]({relative_url})" if is_markdown else f"[[{relative_url}]]" + insert_text = f"![{target.name}]({absolute_url})" if is_markdown else f"[[{relative_url}]]" return { "url": absolute_url, "relativeUrl": relative_url, @@ -654,7 +659,35 @@ def save_upload(filename: str, payload: bytes, page_path: str = "") -> dict[str, } -def run_build_commands() -> tuple[bool, str, str]: +def parse_upload_form(content_type: str, body: bytes) -> tuple[str, bytes, str]: + if not content_type.lower().startswith("multipart/form-data"): + raise ValueError("Uploads must use multipart/form-data.") + message = BytesParser(policy=email_default_policy).parsebytes( + f"Content-Type: {content_type}\r\nMIME-Version: 1.0\r\n\r\n".encode("utf-8") + body + ) + if not message.is_multipart(): + raise ValueError("Upload form is not multipart.") + + filename = "" + payload = b"" + page_path = "" + for part in message.iter_parts(): + name = part.get_param("name", header="content-disposition") + if name == "attachment": + filename = part.get_filename() or "" + payload = part.get_payload(decode=True) or b"" + elif name == "pagePath": + raw_value = part.get_payload(decode=True) or b"" + page_path = raw_value.decode(part.get_content_charset() or "utf-8", errors="replace") + + if not filename: + raise ValueError("No attachment was uploaded.") + if not payload: + raise ValueError("Attachment is empty.") + return filename, payload, page_path + + +def run_build_commands(log_callback: Callable[[str], None] | None = None) -> tuple[bool, str, str]: venv_python = ROOT / ".venv" / "bin" / "python" venv_pip = ROOT / ".venv" / "bin" / "pip" commands = [["emacs", "-Q", "--script", "build-site.el"]] @@ -667,20 +700,33 @@ def run_build_commands() -> tuple[bool, str, str]: ) commands.append([str(venv_python), "search-index-json.py"]) combined = [] + + def append_log(text: str) -> None: + combined.append(text) + if log_callback: + log_callback(text) + ok = True for command in commands: - combined.append(f"$ {' '.join(command)}\n") - proc = subprocess.run( + append_log(f"$ {' '.join(command)}\n") + env = os.environ.copy() + env["PYTHONUNBUFFERED"] = "1" + proc = subprocess.Popen( command, cwd=ROOT, + env=env, text=True, - stdout=subprocess.PIPE, + bufsize=1, stderr=subprocess.STDOUT, + stdout=subprocess.PIPE, ) - combined.append(proc.stdout) - if proc.returncode != 0: + assert proc.stdout is not None + for line in proc.stdout: + append_log(line) + return_code = proc.wait() + if return_code != 0: ok = False - combined.append(f"\nCommand exited with {proc.returncode}.\n") + append_log(f"\nCommand exited with {return_code}.\n") break message = "Build complete. The site output and search index were regenerated." if ok else "Build failed. Check the log below." return ok, message, "".join(combined) @@ -1058,9 +1104,21 @@ APP_HTML = r""" return String(value).replace(/[&<>"']/g, (char) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[char])); } + function previewImageUrl(src) { + const value = String(src || ""); + if (value.startsWith("https://author.zainezq.com/assets/")) { + return value.replace("https://author.zainezq.com/assets/", "https://zainezq.com/assets/"); + } + const relativeAsset = value.match(/^(?:\.\.\/)+assets\/(.+)$/); + if (relativeAsset) return `https://zainezq.com/assets/${relativeAsset[1]}`; + if (value.startsWith("/assets/")) return `https://zainezq.com${value}`; + if (value.startsWith("assets/")) return `https://zainezq.com/${value}`; + return value; + } + function renderInlineMarkdown(value) { let out = html(value); - out = out.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '$1'); + out = out.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (_match, alt, src) => `${alt}`); out = out.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1'); out = out.replace(/\*\*([^*]+)\*\*/g, '$1'); out = out.replace(/\*([^*]+)\*/g, '$1'); @@ -1173,14 +1231,15 @@ APP_HTML = r""" } async function refreshBuild() { + const wasRunning = Boolean(state.build && state.build.running); try { state.build = await api("/api/build"); renderStatus(); + if (wasRunning && !state.build.running) await refreshPages(); } catch (err) { statusBox.className = "status fail"; statusBox.textContent = `Could not refresh build status: ${err.message}`; } - await refreshPages(); } editor.title.addEventListener("input", () => { @@ -1224,6 +1283,7 @@ APP_HTML = r""" const saved = await api("/api/page", { method: "POST", body: JSON.stringify(payload) }); setForm(saved); saveMessage.textContent = "Saved. Build queued."; + await refreshPages(); await refreshBuild(); } catch (err) { saveMessage.textContent = err.message; @@ -1509,24 +1569,12 @@ class Handler(BaseHTTPRequestHandler): def do_POST(self) -> None: if self.path == "/api/upload": try: - form = cgi.FieldStorage( - fp=self.rfile, - headers=self.headers, - environ={ - "REQUEST_METHOD": "POST", - "CONTENT_TYPE": self.headers.get("Content-Type", ""), - }, + length = int(self.headers.get("Content-Length", "0")) + filename, payload, page_path = parse_upload_form( + self.headers.get("Content-Type", ""), + self.rfile.read(length), ) - field = form["attachment"] if "attachment" in form else None - if field is None or not getattr(field, "filename", ""): - raise ValueError("No attachment was uploaded.") - payload = field.file.read() - if not payload: - raise ValueError("Attachment is empty.") - page_path = "" - if "pagePath" in form: - page_path = str(form["pagePath"].value or "") - self.send_json(save_upload(field.filename, payload, page_path)) + self.send_json(save_upload(filename, payload, page_path)) except Exception as exc: self.send_json({"error": str(exc)}, HTTPStatus.BAD_REQUEST) return diff --git a/lima/index.md b/lima/index.md old mode 100755 new mode 100644 index ad3430f..ad47b50 --- a/lima/index.md +++ b/lima/index.md @@ -9,3 +9,8 @@ I made quite a few changes. It all started when I realised that not everyone kno - I probably didn’t explain it as well, but you can create folders and files under the `lima-website` directory. The files must have a `.md` extension at the end (markdown). - One other thing, a more personal one: what do you think of all this? am i doing too much? am i doing too little? am i overengineering things? am i forcing you to do something you dont wanna do? these little trinkets work for me, but i’m not sure if it would work for someone else, so at any point if you have reservations, let me know okay? + + +![2026-05-09-screen-shot-2025-11-10-at-18-02-10-fullpage.png](../assets/images/hzone/2026-05-09-screen-shot-2025-11-10-at-18-02-10-fullpage.png) + +This is a test diff --git a/posts/posts-list.org b/posts/posts-list.org index 8759e3f..4dd7f3d 100644 --- a/posts/posts-list.org +++ b/posts/posts-list.org @@ -4,8 +4,7 @@ See the categories: @@html:Categories@@ * Posts: -- [[file:career/career-list.org][Career List]] @@html:@@ -- [[file:posts-list.sync-conflict-20260509-150632-VT6366A.org][Posts List]] @@html:@@ +- [[file:career/career-list.org][Career List]] @@html:@@ - [[file:career/ha-dr.org][High Availability, Disaster Recovery and Business Continuity]] @@html:@@ @@html:@@ @@html:@@ - [[file:career/javascript.org][Understands the Javascript language]] @@html:@@ @@html:@@ @@html:@@ - [[file:career/restful-api.org][Restful API]] @@html:@@ @@html:@@ @@html:@@ diff --git a/posts/posts-list.sync-conflict-20260509-150632-VT6366A.org b/posts/posts-list.sync-conflict-20260509-150632-VT6366A.org deleted file mode 100644 index 0e4bca5..0000000 --- a/posts/posts-list.sync-conflict-20260509-150632-VT6366A.org +++ /dev/null @@ -1,26 +0,0 @@ -#+TITLE: Posts List -#+OPTIONS: toc:nil num:nil - -See the categories: @@html:Categories@@ - -* Posts: -- [[file:career/career-list.org][Career List]] @@html:@@ -- [[file:career/ha-dr.org][High Availability, Disaster Recovery and Business Continuity]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/javascript.org][Understands the Javascript language]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/restful-api.org][Restful API]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/monitoring-and-logging.org][Monitoring and Logging]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/pipelines.org][Pipelines and how they work (as well as CI/CD)]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/database-permissions.org][Database Permissions, Roles, and Accounts]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/probation-objectives.org][Probation Objectives:]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/airflow.org][Datamarts, Airflow and DAG's]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/normalisation.org][Benefits of Normalisation]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/wireframe-designs.org][Wireframe Designs]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/management-of-self.org][Management of self training]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/requirements-features.org][Requirements, features, user stories, tasks, walking skeletons]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/career-intro.org][Career Introduction]] @@html:@@ @@html:@@ -- [[file:career/invest-principles.org][Invest Principles]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/lean.org][Lean]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/retrospectives.org][Retrospectives]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/owasp.org][OWASP Top Ten]] @@html:@@ @@html:@@ @@html:@@ -- [[file:career/solid-principles.org][SOLID Principles]] @@html:@@ @@html:@@ @@html:@@ -- [[file:posts-intro.org][Posts Introduction]] @@html:@@ @@html:@@ \ No newline at end of file diff --git a/recently-updated.org b/recently-updated.org index b57c673..0c0f9f9 100644 --- a/recently-updated.org +++ b/recently-updated.org @@ -2,9 +2,6 @@ #+OPTIONS: toc:nil num:nil * Recently Updated (top 26 files) -- [[file:posts/posts-list.sync-conflict-20260509-150632-VT6366A.org][Posts List]] @@html:@@ -- [[file:sitemap.sync-conflict-20260509-150632-VT6366A.org][Sitemap]] @@html:@@ -- [[file:sitemap.sync-conflict-20260509-150611-VT6366A.org][Sitemap]] @@html:@@ - [[file:home/notes.org][Notes]] @@html:@@ - [[file:home/wird-tracker.org][Wird Tracker]] @@html:@@ - [[file:home/status.org][Competency Status Board]] @@html:@@ @@ -28,3 +25,6 @@ - [[file:blogs/2026/04-april/12-04-week-review.org][[12-04-2026] - Weekly Review]] @@html:@@ - [[file:blogs/2026/04-april/starting-new-rotation-08-04-26.org][Starting new rotation]] @@html:@@ - [[file:blogs/2026/04-april/action-plan-07-04-26.org][Action plan to change teams]] @@html:@@ +- [[file:blogs/2026/04-april/weekly-target-06-04-26.org][[06-04-2026] - Weekly target]] @@html:@@ +- [[file:blogs/2026/04-april/making-notes-through-org-noter-06-05.org][Making Notes through Org Noter]] @@html:@@ +- [[file:blogs/2026/04-april/05-04-week-review.org][[05-04-2026] - Weekly Review]] @@html:@@ diff --git a/requirements.txt b/requirements.txt index 6f83e94..b8ba271 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ beautifulsoup4 lxml +legacy-cgi diff --git a/sitemap.org b/sitemap.org index 4d00ad7..35e626d 100644 --- a/sitemap.org +++ b/sitemap.org @@ -1,8 +1,6 @@ #+TITLE: Sitemap - [[file:index.org][Home]] -- [[file:sitemap.sync-conflict-20260509-150611-VT6366A.org][Sitemap]] -- [[file:sitemap.sync-conflict-20260509-150632-VT6366A.org][Sitemap]] - [[file:wip.org][Work in progress]] - [[file:recently-updated.org][Recently Updated]] - tags @@ -44,7 +42,6 @@ - [[file:blogs/blogs-list.org][Blogs List]] - posts - [[file:posts/posts-intro.org][Posts Introduction]] - - [[file:posts/posts-list.sync-conflict-20260509-150632-VT6366A.org][Posts List]] - [[file:posts/posts-list.org][Posts List]] - career - [[file:posts/career/solid-principles.org][SOLID Principles]] diff --git a/sitemap.sync-conflict-20260509-150611-VT6366A.org b/sitemap.sync-conflict-20260509-150611-VT6366A.org deleted file mode 100644 index 4d5f753..0000000 --- a/sitemap.sync-conflict-20260509-150611-VT6366A.org +++ /dev/null @@ -1,65 +0,0 @@ -#+TITLE: Sitemap - -- [[file:index.org][Home]] -- [[file:wip.org][Work in progress]] -- [[file:recently-updated.org][Recently Updated]] -- home - - [[file:home/countdown.org][Countdown]] - - [[file:home/backlog.org][Backlog]] - - [[file:home/status.org][Competency Status Board]] - - [[file:home/services.org][Service]] - - [[file:home/wird-tracker.org][Wird Tracker]] - - [[file:home/contact.org][Contact]] - - [[file:home/notes.org][Notes]] - - [[file:home/categories.org][Categories]] - - guide - - [[file:home/guide/setup.org][Setup]] - - [[file:home/guide/wird-tracker-guide.org][Wird Tracker — Technical Guide]] -- books - - [[file:books/books-list.org][Books List]] - - clean-code - - [[file:books/clean-code/clean-code-notes.org][Clean Code Notes]] -- blogs - - [[file:blogs/blogs-intro.org][Blogs Introduction]] - - [[file:blogs/publish-pages.org][How to publish pages using Org Publish]] - - [[file:blogs/blogs-list.org][Blogs List]] -- lima - - [[file:lima/lima-list.org][Lima]] -- tags - - [[file:tags/life.sync-conflict-20260417-233423-VT6366A.org][Tag: life]] - - [[file:tags/review.sync-conflict-20260328-203248-VT6366A.org][Tag: review]] - - [[file:tags/introduction.org][Tag: introduction]] - - [[file:tags/learning.org][Tag: learning]] - - [[file:tags/notes.org][Tag: notes]] - - [[file:tags/review.org][Tag: review]] - - [[file:tags/website.org][Tag: website]] - - [[file:tags/life.org][Tag: life]] - - [[file:tags/update.org][Tag: update]] - - [[file:tags/insights.org][Tag: insights]] - - [[file:tags/emacs.org][Tag: emacs]] - - [[file:tags/education.org][Tag: education]] - - [[file:tags/reading.org][Tag: reading]] - - [[file:tags/maths.org][Tag: maths]] -- posts - - [[file:posts/posts-intro.org][Posts Introduction]] - - [[file:posts/posts-list.org][Posts List]] - - career - - [[file:posts/career/solid-principles.org][SOLID Principles]] - - [[file:posts/career/owasp.org][OWASP Top Ten]] - - [[file:posts/career/lean.org][Lean]] - - [[file:posts/career/retrospectives.org][Retrospectives]] - - [[file:posts/career/invest-principles.org][Invest Principles]] - - [[file:posts/career/career-intro.org][Career Introduction]] - - [[file:posts/career/wireframe-designs.org][Wireframe Designs]] - - [[file:posts/career/management-of-self.org][Management of self training]] - - [[file:posts/career/requirements-features.org][Requirements, features, user stories, tasks, walking skeletons]] - - [[file:posts/career/normalisation.org][Benefits of Normalisation]] - - [[file:posts/career/airflow.org][Datamarts, Airflow and DAG's]] - - [[file:posts/career/probation-objectives.org][Probation Objectives:]] - - [[file:posts/career/monitoring-and-logging.org][Monitoring and Logging]] - - [[file:posts/career/pipelines.org][Pipelines and how they work (as well as CI/CD)]] - - [[file:posts/career/database-permissions.org][Database Permissions, Roles, and Accounts]] - - [[file:posts/career/restful-api.org][Restful API]] - - [[file:posts/career/javascript.org][Understands the Javascript language]] - - [[file:posts/career/ha-dr.org][High Availability, Disaster Recovery and Business Continuity]] - - [[file:posts/career/career-list.org][Career List]] \ No newline at end of file diff --git a/sitemap.sync-conflict-20260509-150632-VT6366A.org b/sitemap.sync-conflict-20260509-150632-VT6366A.org deleted file mode 100644 index 4d5dafa..0000000 --- a/sitemap.sync-conflict-20260509-150632-VT6366A.org +++ /dev/null @@ -1,66 +0,0 @@ -#+TITLE: Sitemap - -- [[file:index.org][Home]] -- [[file:sitemap.sync-conflict-20260509-150611-VT6366A.org][Sitemap]] -- [[file:wip.org][Work in progress]] -- [[file:recently-updated.org][Recently Updated]] -- home - - [[file:home/countdown.org][Countdown]] - - [[file:home/backlog.org][Backlog]] - - [[file:home/status.org][Competency Status Board]] - - [[file:home/services.org][Service]] - - [[file:home/wird-tracker.org][Wird Tracker]] - - [[file:home/contact.org][Contact]] - - [[file:home/notes.org][Notes]] - - [[file:home/categories.org][Categories]] - - guide - - [[file:home/guide/setup.org][Setup]] - - [[file:home/guide/wird-tracker-guide.org][Wird Tracker — Technical Guide]] -- books - - [[file:books/books-list.org][Books List]] - - clean-code - - [[file:books/clean-code/clean-code-notes.org][Clean Code Notes]] -- blogs - - [[file:blogs/blogs-intro.org][Blogs Introduction]] - - [[file:blogs/publish-pages.org][How to publish pages using Org Publish]] - - [[file:blogs/blogs-list.org][Blogs List]] -- lima - - [[file:lima/lima-list.org][Lima]] -- tags - - [[file:tags/life.sync-conflict-20260417-233423-VT6366A.org][Tag: life]] - - [[file:tags/review.sync-conflict-20260328-203248-VT6366A.org][Tag: review]] - - [[file:tags/learning.org][Tag: learning]] - - [[file:tags/introduction.org][Tag: introduction]] - - [[file:tags/notes.org][Tag: notes]] - - [[file:tags/website.org][Tag: website]] - - [[file:tags/review.org][Tag: review]] - - [[file:tags/life.org][Tag: life]] - - [[file:tags/emacs.org][Tag: emacs]] - - [[file:tags/education.org][Tag: education]] - - [[file:tags/update.org][Tag: update]] - - [[file:tags/reading.org][Tag: reading]] - - [[file:tags/insights.org][Tag: insights]] - - [[file:tags/maths.org][Tag: maths]] -- posts - - [[file:posts/posts-intro.org][Posts Introduction]] - - [[file:posts/posts-list.org][Posts List]] - - career - - [[file:posts/career/solid-principles.org][SOLID Principles]] - - [[file:posts/career/owasp.org][OWASP Top Ten]] - - [[file:posts/career/lean.org][Lean]] - - [[file:posts/career/retrospectives.org][Retrospectives]] - - [[file:posts/career/invest-principles.org][Invest Principles]] - - [[file:posts/career/career-intro.org][Career Introduction]] - - [[file:posts/career/wireframe-designs.org][Wireframe Designs]] - - [[file:posts/career/management-of-self.org][Management of self training]] - - [[file:posts/career/requirements-features.org][Requirements, features, user stories, tasks, walking skeletons]] - - [[file:posts/career/normalisation.org][Benefits of Normalisation]] - - [[file:posts/career/airflow.org][Datamarts, Airflow and DAG's]] - - [[file:posts/career/probation-objectives.org][Probation Objectives:]] - - [[file:posts/career/monitoring-and-logging.org][Monitoring and Logging]] - - [[file:posts/career/pipelines.org][Pipelines and how they work (as well as CI/CD)]] - - [[file:posts/career/database-permissions.org][Database Permissions, Roles, and Accounts]] - - [[file:posts/career/restful-api.org][Restful API]] - - [[file:posts/career/javascript.org][Understands the Javascript language]] - - [[file:posts/career/ha-dr.org][High Availability, Disaster Recovery and Business Continuity]] - - [[file:posts/career/career-list.org][Career List]] \ No newline at end of file diff --git a/tests/test_authoring_server.py b/tests/test_authoring_server.py index 9e314db..69aae75 100755 --- a/tests/test_authoring_server.py +++ b/tests/test_authoring_server.py @@ -103,6 +103,24 @@ class UtilityTests(AuthoringServerTestCase): self.assertEqual(server.image_dimensions(gif, ".gif"), (320, 200)) self.assertIsNone(server.image_dimensions(b"not an image", ".png")) + def test_parse_upload_form_reads_attachment_and_page_path(self): + boundary = "----authoring-test" + content_type = f"multipart/form-data; boundary={boundary}" + body = ( + f"--{boundary}\r\n" + 'Content-Disposition: form-data; name="pagePath"\r\n\r\n' + "lima/index.md\r\n" + f"--{boundary}\r\n" + 'Content-Disposition: form-data; name="attachment"; filename="photo.png"\r\n' + "Content-Type: image/png\r\n\r\n" + ).encode("utf-8") + b"image bytes\r\n" + f"--{boundary}--\r\n".encode("utf-8") + + filename, payload, page_path = server.parse_upload_form(content_type, body) + + self.assertEqual(filename, "photo.png") + self.assertEqual(payload, b"image bytes") + self.assertEqual(page_path, "lima/index.md") + class PageRenderingTests(AuthoringServerTestCase): def test_render_org_writes_metadata_and_body(self): @@ -244,6 +262,22 @@ class PageRenderingTests(AuthoringServerTestCase): self.assertEqual(saved["path"], "assets/images/blogs/2026-05-07-lunch.jpg") self.assertEqual(saved["insertText"], "[[../../../assets/images/blogs/2026-05-07-lunch.jpg]]") + def test_save_upload_inserts_absolute_public_url_for_markdown(self): + with mock.patch.object(server, "datetime") as datetime_mock: + datetime_mock.now.return_value = datetime(2026, 5, 9, 9, 30) + saved = server.save_upload( + "Screen Shot.png", + b"image bytes", + "lima/index.md", + ) + + self.assertEqual(saved["path"], "assets/images/hzone/2026-05-09-screen-shot.png") + self.assertEqual(saved["relativeUrl"], "../assets/images/hzone/2026-05-09-screen-shot.png") + self.assertEqual( + saved["insertText"], + "![2026-05-09-screen-shot.png](https://zainezq.com/assets/images/hzone/2026-05-09-screen-shot.png)", + ) + def test_save_upload_rejects_disallowed_extensions(self): with self.assertRaises(ValueError): server.save_upload("shell.php", b"