From 171de8808cebbbfd335756ddac5a35641f0440c2 Mon Sep 17 00:00:00 2001 From: Cyrille LOUARN Date: Sun, 1 Oct 2023 01:47:27 +0200 Subject: [PATCH] [1.9.13]: see changelog --- CHANGELOG.md | 6 + src/usr/bin/tyto | 4 +- .../program/__pycache__/args.cpython-311.pyc | Bin 2603 -> 2602 bytes .../program/__pycache__/check.cpython-311.pyc | Bin 5280 -> 7921 bytes .../program/__pycache__/debug.cpython-311.pyc | Bin 3307 -> 3556 bytes .../program/__pycache__/forms.cpython-311.pyc | Bin 8779 -> 8324 bytes .../program/__pycache__/post.cpython-311.pyc | Bin 4133 -> 4739 bytes .../program/__pycache__/tools.cpython-311.pyc | Bin 5056 -> 4503 bytes src/var/lib/tyto/program/check.py | 119 +++++++++++++----- src/var/lib/tyto/program/debug.py | 8 +- src/var/lib/tyto/program/forms.py | 37 +++--- src/var/lib/tyto/program/post.py | 68 ++++++---- src/var/lib/tyto/program/tools.py | 29 +---- .../__pycache__/logs_fr.cpython-311.pyc | Bin 2860 -> 2873 bytes src/var/lib/tyto/translations/logs_fr.py | 7 +- 15 files changed, 164 insertions(+), 114 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c4ba38..0966d9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ Tyto - Littérateur # CURRENTLY IN DEV ! +## [1.9.13] +- Check: One-Line needed tags, titles +- Added first stats +- move ini template from tyto to domain for domain config file +- Check valid date in article and form domain date + ## [1.9.12] - preparing check process : head tags in article diff --git a/src/usr/bin/tyto b/src/usr/bin/tyto index 0888f9a..a98a94f 100755 --- a/src/usr/bin/tyto +++ b/src/usr/bin/tyto @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Version: 1.9.12 -# Updated: 2023-09-30 1696082419 +# Version: 1.9.13 +# Updated: 2023-10-01 1696117427 # Tyto - Littérateur # Copyright (C) 2023 Cyrille Louarn diff --git a/src/var/lib/tyto/program/__pycache__/args.cpython-311.pyc b/src/var/lib/tyto/program/__pycache__/args.cpython-311.pyc index 17afd7ec8dccd01c0aec2d3826ba47346d03fed3..27a7f6a2478de13da1e16d64d2fd6cb2c18cad03 100644 GIT binary patch delta 78 zcmZ22vPy(^IWI340}w25mPn1=$ScLf!CsPBl%85rJlTNBLzG9bLH#Z(cSmVcd_(*K amI>(~xVe`poSj?s0|Of)gqZxE(*^)lofh5z delta 79 zcmZ1_vRZ_9IWI340}vehAeNf2kyna|lOwk@rzEo=Cv~zulZPm;P=m%@R_>0{ruc^V b1tJqNKyY&pQ#d=f+6M+UMhG$a9j6TdtO^)B diff --git a/src/var/lib/tyto/program/__pycache__/check.cpython-311.pyc b/src/var/lib/tyto/program/__pycache__/check.cpython-311.pyc index 512ec39a3f37d4cae9bd0b18c3a6d55679062556..e6c3a419faa01c95186ab2c4bb3fb6308d9544cc 100644 GIT binary patch literal 7921 zcmcH;ZEO=qc0aspuN^zzK++_3NCLP(LUKvle8DxOQ45qij&RqeP|IXZ;>3x=?xuyv zISfj#Y0sycUN{T~s#O6^MUbKsNYUwj^vC@?oxEtJMk_@^I`JdY{cy!0as0YByY_h3 zNy^9FO}uYsXWq=b_vX!;_g=nnI_(6M(|_6$I8{jy|3DwvLS-tCegl=u1W)i}h!{X` zDnyP^0~D#Z(F3&BXBn_)Z)Ske-s}LYy{!XQ?QI*d@$?Ka!0{GkNJb+YSG{+-{b`Emjb?z{GrK! zs4_yp&!7F4c!UN%t!etmFEoXMC!3_RQn+bC2oDMVv8KV{z~E@(#96@#NE+A!6>%$o zD6vA>6sjW8AX6TN@}wvaG|cQe-#F74)&2wy&;~J;@PWC$3Ln5Vz--BJEpU=0+e#2R zHxgPuQ}VfukVyl67K;ECFiS67EID$$k-T1g9W1*krV$Ck%c>T?FeIv030?t7REx$Y zLsD=e6!2wQG^wbzz&I~{9F&Gtdr~2=v%_;n&nxO-J`X*o%f)yBeG}ZeXRLrUuAFew99At8eo<6y zgTtdfr0i4W6Jb$m6eYhT`Ub;eV}Wr=^mKb|Dg(zL$ivYTg5wel12mNh2trs85NU!F zflUBZmwB|86iT33L?YEUQYb>W2)u(j-UWaThjo@czk6nPboWD4y=0lQU+=wkNT$3B ze`~i8={pkbqhA9R8=a$RQo@@7 z8-uqZf0HL_By>oEn+j;q6hdXBa5yBYmcW^yB*3jjsMc@@Ob3`0Rtid?fas+(ebN+8 zL^EZ~gRmJ*g1}LD#NPq{ttu#r9g1#8*1$T`6yGLO6<~r>RM+)m*9PXT_sZ^8%GF&; zb=MOe<<&TOp(#bVFAZG`&IMCc&&{?Q9rHu?q`OmcU5`@N^JIl$XEIndmrh+Ao*P~V zD^=H%`B6R44L@BcfhJrK>6%V%g^Jm%n0GxRHxh0}{aQihLz_=Ci-HS%BH)KdM9QO` zCf)c&!2qsZ8)==kb_*B?xc*7M$#9u86rY16Iz?*=Pnk_1Pn-3*y!;zQY^iQzu0KL4aPFLv3cw5e)b5- zaFQY<&zfa&iZagN!}P}fU~C`3R^}!6$c=qoKGq%aLVVyEVoyzcXl^Ll1rr}fpKCvI zV>jlbaf8(iBVLFPyk?w?`Alj3=e;Z&J zER1<4M2csR5|aCwYZzw$?<5z!WMK~bFW4+c~__|Jl*2S<$N z^QZ;752S~pD&s#Ho&+BpIqVQHO-jRILA7W;5;q>k%R*eG4^y2`)!cW@$N!d6snED; z2?fUkCI<@Xs(`>KJmT*`QKCeeC7h+v?JFg(T<=w?8o#e%655xHca zQnD{il+#;&K;Zmv^yF;)vZF9%*&lDc-1TMG#l3TT;Un4qjqhvU;!(MwU1?~ChNU+i z+X(Q^I^zCVcbX_-wj}z$@?G`a>0cOFA{S1`)tyRpr`EAjwq@=>;`H3RH@g-sivhW= zOR4Khm3Du^&x}Mz9y*I-0|_#AB274966vdRSI^y%7N(YJ7p7%*x8jD`q2t+;ydOUu zgE-O-lki`KuZHjN3qhbHB-eB*H9!e;tdwq^Yfl`R>$+Jr&o90u*LEni9jTH|pd@%c zh$#6WQ5^d)O<0*NNy|5dUl-o9+;uFydDkU-_9-3^6m+bVSIm8oES~%D=JCb)C5zn9 ztu%C}%J#w}qvuD_BpFI98&LusW=eYH+IFS3Jyp`7Q}Tdwe&PPyeZA~jjm+&(xE*PN zWVS39ZH^B8`*8tbFTK>7;iL6N`}~m`T{5>v;r67cpDwj6wXJZQE=hA|fy9W+)hk>* zZZCmx9SQ$j_sv#ti~TpcWv*G_AZ*Tzd!GJI*vY*xzH|QcjlDA0qHryy@w$B1qYJp2 zEz_M@&`n%$eD2YLy9klQUB*g&dV{BO4qg%+;x)zWkWN$JynYy=l56l#1Gv2=<2_CD zmTAfuP)71FdWjRSYi_Y+nu$;mCW#$w;{s+Hrl1Sxuo#1}{CRn53NElwZ8iaB=4pLY z?2QNori(fJl8ZvlZT@Q4WjQDWKd`eNtjJL7}0y;8APCYlv{ z_4oGr`}TU-zD==ji#CAGVGGg(OIIzIZb3FANz0}6N@;!c&~kw*`qoNmRpPi@`l?d; zYMP*#Dh+&Qoh4^mmtCcC{_@C|BNsz+A=$Mx8d&D+zZ;D2l3i}ak;b8NnTU{L%SKs8o{A7tz`Myuz}v}#D)7uL=)aBR zqZK2j564wJa}*Q_Hir>7jnhN_GH~3VBlL%WzIsC!A5&}Gd9&>mehDEr%@dy(EWG%dG2AeO)|LqIN0MhE zBtZ7M#l&4M5U}z#p36JJ21U>yY83}MM2<-;wpFM(DAok<+F zWM@Qg^EnZIWei=+~G6b1HFKjf>(7*A1NkLJ0rqP?D? z8yg$F#o8s9@ztfk843I9`c-My{CCZJ7IwiXVK)HPf&TsB(^HfND}fD!TA-)JbqwU~ z^T8o-`)QO;cV?E+^XzA)od9M9z-Y-`*{XmnY z&Ho|*q=^#R{R0BJkN&_>h@8U0oR_YBF0-x&R>!C3E}Xk0DVw*;)*Xr!yhkVFUUnA8 zYvWtvTVwCRg=;N;XmiH6_|~NU$0y-0wP`1~@9!;2OGmzAWLuwN>w8QSoHJ&BP*^rQ zIXk(++EeUih25NJmf0%33J_f}{@7;ZvdUbg!d1fM&$zFP$<}%D#_Lxi*CO+$@4NS; z+OW=I=k zv}Wbq(#oqkE4Fc?je=H$P?1Rfu$A}$?Z--umepaNZ|(}y!%8tu_(PmcD$K(c44H`$vYKe-O3g-k7>V_Kbo4psT)MT{QuLbsiKoe z@2|!F{#XaiHcjvB>_%o>#%ph|b3sM%3Q)%sRmOJ9I4I=?jAWGCior_14XXwx$#P6K z9MiB#1EE+{m7*%_**Q5JRlSsql~eGFmSU;I2y?rD5uX8o?I}1?ZJ9%w;L!z75wXnS zf~`Ke2qD2a@_a+$`ZLy+yzu!%%CE7lI@_9KTc6R5OMS_{L|*}d(4Ri_Ngxq;4IoJyjj?5o5cSuAMp`Hp`~@@!_3W4Cx(1IoI%~Vsa)i^UTqd@@J?N zWY>0JqCWWe-p5bW#|vBSj~BJJVZ9Bw1LD<8ex1IVx>7_oU?M(<-HSaDABRDch<4Pc z9|cVSQE4jeljo zso#448>i+uuY15zfG8Y1ymEQ9Y316(E7{I1R_hwpyM}WuBf#Xw(hbaHM-!@+CV;SN zGOD!?=#o`v2Ai!uWIeH%B|Ml|8HE}XXDOY|*khc`~Gxiz6z7kYE_kF$K1 zhYJ3sT(0U=t6X6`%XXUA3pI!^oyNx=2I*b}de?nj_T>aaUfp z$cXGBtybl5@m(`U(bcmgGh`RJI34Hq&oHezEPzPRgRQ<|?dB`e3vhPrT#A6R$dss3 z=i)Sc4B+4t8I+F#qiw3kfWF)gZG(@%B_up2dvJ#%ZG(wOQ7$I~#<12l-}T zG^q1%2QGg=puz?lR;5`5zhFG1lrr-!=*t*<29JWT`U#Y`JO6m{4=2+h&Hk=#e>ZbV zw;%b|-ucwtso9U~_T!1JB9HinBH|f$-qniFgH=Xzb?UCp#Lx2$&cp`=mpgMsb9L*k z?jmA1Hvzx5EmO<=d8aEa-ktek=1ycKqB)Nxq`YANJe2OyoNcSeCnhDA!G<7feVQcX3( z0y|Pf2oXq*0l$g;Mhe^!Ir#R#z(Vok&wm7C3v8F-IY03nNBkJ97CGZvp<{5OG&w(I zF!BjXkTgXLIb?eEostGv5i0%K%Dp=`CXq{ diff --git a/src/var/lib/tyto/program/__pycache__/debug.cpython-311.pyc b/src/var/lib/tyto/program/__pycache__/debug.cpython-311.pyc index d9f7488af6e6e7a54ef5f8567866829b7924c45d..7dc85df20b1c471bc0e4ab4093c5925dc938748e 100644 GIT binary patch delta 1263 zcmZwF%TE(Q90%~3ZFgxY+iI;s-@9E(X?a_k(?G%@;=A28KOI(r+mxLr)E=frY zE-6V&E@??}Tr!eaT(XjMb1@{zb1^09;gXZ2z{QfJmy7%sMK0Y^O$nutZ^=u#9I0L2 zn-k)O*Qnj+YApM`7iv5*;0D&HOIb%7^ggTRWXdJBaZklnj$+egQoGu^!rk7zu}fZ2 zLe^PtHcDJFLyALQNqZU|X7SNW!JGBGU)}MmPx33J&Gr7|@B(CBTF@LP9_ek_agQ7Nij} z0@9F0Fa+el%-5OZgjirZ9r;9C0z$H%n1Nn$A^yj+wJ@jaFC)m*_{bswA6#dQ>c5wPI3K+P7-xB9G fj^|kX4UFGkv>#S06OQe99V6xprEHh}Kl!qMw$&wX delta 957 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 diff --git a/src/var/lib/tyto/program/__pycache__/post.cpython-311.pyc b/src/var/lib/tyto/program/__pycache__/post.cpython-311.pyc index 9dedeaaaa88cc709ff99c51d8986e85e1e897765..40534a48e9a83be9167ea56645fc69fa4abc5eaa 100644 GIT binary patch delta 2171 zcmb7FU2NM_6ux$1Cywnne@)tCZIX3a)kzs!lSX1|yU`8UCRTwum}Ho$tk=*^{TcQJ zL0E|qJhaoqsO}~zu}NXlwu(upVlRlt@yY|4A{JSi7(zTCUV^rVi6`!L;`jdK0OfyYK#eR4Rx=4R~V)d@YB=G0VzP=>}@{<4snsyY=365Ox ztyaVMO_v`tY`jO@#z-PYE`XxA?CEBW6p0$+JkU!9Ot#P4il4yWu*q1j6Pe7?ToM@| zhL6}pPXKMl{>8`R#o#uxJ4<{%c{|8BF-LvbnWWx zLfK8~77_2X)g>0Y-Q!FQzwADazjS{bcUe3t>hEaC;xt`f)GZdCHR$oC@BlZ&?<0~i zj;FZMeLUc$2VC?%7rlzEELFKojmtCu>k2-Uf|rheadvI6^2Yk9jr|*1RT`;DBltd- zkGJXKTI^hhE6sB1wJ6No=s>qN#=) zC-O8>+e8td54HWswQL`)eNCOwUL_f`xhU~JhubWij)k^Q3a@zl!$leSH+O;Jn{tWN zchOHPWKf!T$pRLm|HJrnT1Z$HdKd){2$@q6qFQcUD?&@q7T%lJ^di!9n$8wCH@l!2 zI$gTuGPLu$OeCGoX1V6H1yryg;%ZIcNP*WasI9z9JA4L5-lX?j2PrMYW^ zO1aylz)jHb;va+^C%vvC%vyI{iCtd0xU^EfR5p)2jHN2wx05%L8@4yq%eqWM`6h67TBAsKH5&T5n+joeLW+>1*w7k=APrYB9n}zxb zqORh@{hcj4|@uOkrrOlo*-Gb+Wk@o3qJ$Cz;P=QZ zgbyp-;%PD^{Z1Ng22U%K13VCXCf5k{GyVo>!zm_3^)^i4Uz9#$7m(wo(BOd_F7%Q7@b+q{@QD=6WiG)P2xJSQY%VGBe&3q6g5dJN~H>#f{+1K8^)kUAr7<4 zk06mP5s6S$YQi*-LnG~_B~p(ZduY`IH&Bc$VGKxAsE3G)D|(0`Au(fnouJAb*u&fR zee?Fs&-d+omb?`o_(saZ*?Y843Fs$`~Fub_-X9afC@8C!R0*ovLOVhw%6MD~V zZ5cdr{q#sMLJz|jJtc$>1zMul%2;ts&k)duFdAf&$&Jan0igE+ zu^wBf&E4A+f?31k%+Bz29SS=wN9E2=tF6V7yoKv0+na_7j{$(yPgro9o$4L$WPueq zuwvjw8(Z(E8q&p>^Gtos!V;uuGyzTe5jrP{SweDz-b48|p&~gJc{l4+1UzGNSNgg* zDh)AWU!bev_z4Y2fuF?Kk78`yxv^9flO-`(1wLQ+H>56~TbWr+ZM^1Q+B&wCEuwS@ zrMFSK90=0C#dN$WvQ|4b`!*c+l`XM|hD&I88x5BOIz2Dlf}`}Yltqis71`3G^iw%x zOo6w?mxM*ZhS$VJ!IkQT3bI0VL6QC{=kfzic>h>tRgYuI33?m=N80CD#4?7rS>{eN z%StP;)?+Q^>v~IBIoAEV6&Wf8lHeRC*!V zgW9E?DEo>a20JkZd+>#w4)#v@>Gx_f&j%}rWGzg37$trlD+@W>xol?_h|Y8Tv+ACBJVHZkXjz$MvPFOJC%#92|X`@9yqCoor+} zf!2Poz1NR!PP!5I{jFpX!4ewW zMuY!P%Qn9fvH9(G^Yqb)urN0D+d&YP+$$^)T)%KmsA6j!)Fge4*8+0HvL%#}*kA+Fi^Eoc$KUBRz_-#l+ z9QrxbY9Hr}e_ZPvGD?3ol1cLKY4()o-^<|-=CY^Ad8TAd0_?khejJ{DxorRjtDp&Q s!UT_-a1m-eZbDp!{Z-I}PM~T9k@Z`ky`Zp{)R diff --git a/src/var/lib/tyto/program/__pycache__/tools.cpython-311.pyc b/src/var/lib/tyto/program/__pycache__/tools.cpython-311.pyc index df7a87c7e641048cd07e4af5333aa04b8ac5ff95..31eda4eec383b39254d9724473403bbbfcc8a934 100644 GIT binary patch delta 1126 zcmbVLO=uHA6rSD9&uspi*0zzBq-jIlCT&HuVAX;OMJV=?B3QwYW;SLuKQgSRw#P##m-^_dS_ItnkesHrt@XGJ^ z5Lk;(x>Xj~2y_d^#^9wgVPcWaQYNjES(!NiJD^iKuBV33hxA#sD_S65%2vX<`WG3hgkT2g6Ae6=7NtElFS0Er)tv zGeB?~S$<13bjzu7Ug0{Dn(w5z#$9l-AqfY)7obXZoxUxxV=cdy{~S4d#I=>LitQeObktK5@(6!8jmjWSg;At#~S)6{*mbgBg zC=DlAEOBK#adkYARwRqEtf3lONwuVMWx=Al!Sg680{6qqI&#Fg3~0H*0Ihitq|h!!(|OitC2X2SGn&hUitnQ@cq= zgme@XJO-e+cpT3Wgnj^vmY~=0uFeNghrEy;-v67PH^)`TE@K;xz~!~tH~Fb}8Hs0X z=DkmFoa7kN-bVmM=6$doamSB=&T=kr4NBE;XukDbY^L3Gf|>JkV3@19{Wqjk3VHr| z;wM2?{70FaZ0n(z(uqzaD5B-fGM3TRoS{|9FqNud2f(pGP>L~gClpPd1wqGAjM=Nv z&*1!BY-dI*Yj!92BpBSQ^|j@M<&fnrWc5N(o8vfu+=*b9^#Y!J0G0#i#Lm!iu}Uec zl^fHJ<6*bdZW6~*+Ns+7uL;M`*^b~hJzuJ@`Jy_(r$C3Jrhf<6m&{+`+@BseRId4ztic7%Q6rS0C+wnGTP2x07Vv?>L$7w?gLLxLRG>z4uCOtT)O?$8$&$==7Pc*xs z5ZTHKRWw4aO0|cUQmMI6gnG<@Yi_-P4VJJ*3d%J%ONa|xc(aa!T5$kIyWh%P+Q!d4=AYdU^a##9h@GDlZ=-7(kpO)}2J{mJFhEqmE}{VjiI75Z z-yUBa$4p%+WNw^&k8`I&&wbNJh>Dpe$+-1KZJ5fwDFDz>%GJVGByo$;pZVsTih$`yH2fnnI))w-pQ z5v~Z&U^CC*Z@13Gzw;U-zL%HVhdM$CRb;o-)#H9G>gz8%5&sjVs#KH;>O1g;Tm|OW zdSb@n38Q$zAW>s>(wLhxQc+_iw&pwF;{sEXm&(~pfhnnWuU?rspPF5mVNxMey1|4T zUGv8bGGP=ajK$d6k(jZ*Z$yoYZPD18U@XQJCM9P}Hj`3-REE7!1%OG5W`;6(W~H26 zj{BHG%Ee5+#MEpqT_|S=6S6rb-Y{*Zk&JEH`J&0hQu!9sESu)qW*%gHd}!I3;>wx0 z$|P&W%rZHd<`LzT*Qo`55YwW(a`Xs~ty-qdRV@{)C~xj49$sfE1mHX!0Dc^P>sJ5= z?fQouqv?OmFXETVWNatW|7iN@+~c{gE`yU&T-v1 z_U0}AVD{AmS!zOM(w^fK@VTw~>OEna3om%edq2W3N%@xcegKI3=o`?z5{@1Rj>)%Z z9?IMf=%)Se?;m?V2tPUf035BY@BP=s@prk--;wA!u;am3mG{-o>e0Bt7lZ&sh?6 zGj%y*Ef?}jR0OuYkxP7Z7=TIqO|%cEbCTa?uZmt>D9@gEI#2RDLaV%m-NCD|8u|}k6NPL4^tJS(xVME4-~x8fg%%{f GqrU*;jEdp_ diff --git a/src/var/lib/tyto/program/check.py b/src/var/lib/tyto/program/check.py index d996bc3..3fed254 100644 --- a/src/var/lib/tyto/program/check.py +++ b/src/var/lib/tyto/program/check.py @@ -33,6 +33,8 @@ #-------------------------- import sys +from dateutil.parser import parse + import args, domain, langs, debug, post, tools @@ -61,8 +63,7 @@ def manage(action, target): # target is not "all" ready() - if target.endswith(".tyto"): - is_article(target) + target.endswith(".tyto") and is_article(target) #================================# @@ -70,29 +71,24 @@ def manage(action, target): # Also used with multiple (loop) # #--------------------------------# def is_article(target): - if not post.is_article(target): - if args.multiple: - return # Let other articles pass - - sys.exit(post.error) - - validators() - if post.error != 0: - if args.targets: - return # Let other articles pass - - sys.exit(post.error) - - print("pass", post.error, args.multiple) + valid(target) + print("pass", post.error, args.targets) + print("chk_date", chk_date) + print("post.stats_comments =", post.stats_comments) # # # -def validators(): +def valid(target): targets = args.targets + + # Target is a tyto article + post.is_article(target) or tools.exit(targets, post.error) + + # One Line targs in head_contents post.error == 0 and ol_tags() or tools.exit(targets, post.error) - + post.error == 0 and titles() or tools.exit(targets, post.error) #===========================================# @@ -102,10 +98,16 @@ def multiple_targets(): ready() -#=======================# -# check header contents # -#-----------------------# +#==============# +# check header #=============================================================== +#==============# +#======================# +# One Line needed tags # +#----------------------# def ol_tags(): + global sitemap + + sitemap = "True" for ln, line in enumerate(post.head_contents.rsplit("\n"), 1): if not line or line.isspace() or line.startswith("#"): continue @@ -125,15 +127,22 @@ def ol_tags(): elif not post.tags[1] and line.startswith(post.tags[0]): post.tags = (post.tags[0], ol_tag_value(line, True)) + + elif line.startswith(post.nositemap): + sitemap = "False" + # Sets are done from loop # Check if tag value exists # ========================= - if not is_ol_tag(post.title[0], post.title[1]): return - if not is_ol_tag(post.about[0], post.about[1]): return - if not is_ol_tag(post.date[0], post.date[1]): return - if not is_ol_tag(post.author[0], post.author[1]): return - if not is_ol_tag(post.tags[0], post.tags[1]): return + if not is_ol_tag(post.date[0], post.date[1]): return False + if not is_valid_date(post.date[1]): return False + if not is_ol_tag(post.title[0], post.title[1]): return False + if not is_ol_tag(post.about[0], post.about[1]): return False + if not is_ol_tag(post.author[0], post.author[1]): return False + if not is_ol_tag(post.tags[0], post.tags[1]): return False + + return True #===========================================# @@ -144,7 +153,7 @@ def ol_tags(): def ol_tag_value(line, commas): value = line.rsplit(":")[1].lstrip() - # reformat comma separated items, removing first space + # reformat comma separated items, removing first spaces if commas: tuple_values = value.rsplit(",") value = "" @@ -162,15 +171,57 @@ def ol_tag_value(line, commas): #---------------------------# def is_ol_tag(tag, value): if not value: - post.error = 51 - debug.out(51, "%s ?"%tag, post.uri, True, 2, False) + post.error = debug.out(51, "%s ?"%tag, post.uri, True, 2, False) return False return True -# -# -# -def valid_date(): - +#======================================# +# Check validity date # +# set date of check (YYYY-MM-DD H:M:S) # +# Also set epoch date # +# Return True/False # +#--------------------------------------# +def is_valid_date(date): + global chk_date + + try: + parse(date) + chk_date = tools.nowdate() + return True + except: + post.error = debug.out(50, "%s"%date, post.uri, True, 2, False) + return False + + +#===============# +# check article #============================================================== +#===============# +#============================# +# Check optional title tags # +# Count tyto + html comments # +# Return True/False # +#----------------------------# +def titles(): + for ln, line in enumerate(post.text_contents.rsplit("\n"), + post.head_lines + 1): + if not line or line.isspace(): + continue + + if line.startswith(post.tyto_titles): + if not line[3:]: + post.error = \ + debug.out(52, "%s. %s ?"%(ln, line), post.uri, True, 2, False) + return False + post.stats_titles += 1 + + elif line[1].isdigit() and int(line[1]) >= 6: + post.error = \ + debug.out(52, "%s) %s..."%(ln, line[0:10]), post.uri, True, 1, False) + return False + + elif line.startswith(post.text_comments): + post.stats_comments += 1 + + return True diff --git a/src/var/lib/tyto/program/debug.py b/src/var/lib/tyto/program/debug.py index dc2f8d1..c0e801a 100644 --- a/src/var/lib/tyto/program/debug.py +++ b/src/var/lib/tyto/program/debug.py @@ -49,10 +49,11 @@ import langs, args def out(nbr, var, val, show, color, stop): args.get_options() if not show: - show = args.dlogs or args.erron and color > 0 # Show only warn and error logs + # Show only warn and error logs + show = args.dlogs or args.erron and color > 0 if not show: - return + return nbr # COlors CS = '\033[0;0m' # Unset @@ -89,6 +90,7 @@ def out(nbr, var, val, show, color, stop): 23 : langs.logs.err_post_empty, 50 : langs.logs.err_date, 51 : langs.logs.err_post_data, + 52 : langs.logs.err_post_title, # WARNINGS (100-200) 100 : langs.logs.warn_no_dom, 101 : langs.logs.domain_created, @@ -126,4 +128,6 @@ def out(nbr, var, val, show, color, stop): if nbr >= 200: nbr = 0 sys.exit(nbr) + + return nbr diff --git a/src/var/lib/tyto/program/forms.py b/src/var/lib/tyto/program/forms.py index e7fc2f7..80fb03d 100644 --- a/src/var/lib/tyto/program/forms.py +++ b/src/var/lib/tyto/program/forms.py @@ -32,7 +32,9 @@ # file program : #-------------------------- -import os, re, configparser +import os, re +from dateutil.parser import parse + import debug, domain, langs, tools @@ -53,11 +55,8 @@ def ask(q, yes_only, default): if yes_only: expected = langs.logs.ok - try: - answer = input(q) - except KeyboardInterrupt: - print("") - maybe_later(expected, "?") + try: answer = input(q) + except KeyboardInterrupt: print("") ; maybe_later(expected, "?") # return default answer if exists if not answer: @@ -71,6 +70,7 @@ def ask(q, yes_only, default): for ok in langs.logs.ok: if answer.lower() == ok.lower(): return True + maybe_later(expected, answer) return answer @@ -123,30 +123,21 @@ def ask_domain_title(update): #---------------------------# def ask_domain_date(update): try: date = domain.cf.get("DOMAIN", "date") - except: date = "YYYY[-MM-DD]" + except: date = "YYYY[-MM][-DD]" - example = date or "YYYY[-MM-DD]" + example = date q = "> %s (%s)%s "%(langs.logs.domain_date, example, langs.logs.q) answer = ask(q, False, date) # Check date format (not valid date) - test = True - tuple_date = answer.rsplit("-") - tuple_len = len(tuple_date) - for i in range(tuple_len): - if i == 0: - if len(tuple_date[i]) != 4 or not tuple_date[i].isdigit(): - test = False - break - elif len(tuple_date[i]) != 2 or not tuple_date[i].isdigit(): - test = False - break + try: + parse(answer) + except: + debug.out(50, "YYYY[-MM-DD]", answer, True, 2, False) + ask_domain_date(update) + return - # Exit if not valid - if not test: - debug.out(50, "YYYY[-MM-DD]", answer, True, 2, True) - if update: tools.update_ini_file(domain.cf_uri, "DOMAIN", "date", answer) else: return answer diff --git a/src/var/lib/tyto/program/post.py b/src/var/lib/tyto/program/post.py index 50199c7..12cf0a4 100644 --- a/src/var/lib/tyto/program/post.py +++ b/src/var/lib/tyto/program/post.py @@ -36,6 +36,9 @@ import os, configparser import domain, debug, tools, tyto +error = 0 + + #============================================# # Check if current directory is in articles/ # # Check if article from target exists # @@ -47,20 +50,16 @@ def is_article(target): domain.user_dir.startswith(domain.wrk_articles) or \ debug.out(2, "-> articles/", domain.wrk_articles, True, 2, True) - global error - # Target URI most be from legacy directory or not begins with if target.startswith(tyto.notarget): - debug.out(20, "./, ../", target, True, 2, False) - error = 20 + error = debug.out(20, "./, ../", target, True, 2, False) return False # Article exists global uri uri = os.path.join(domain.wrk_articles, target) if not os.path.exists(uri): - debug.out(5, "False", uri, True, 2, False) - error = 5 + error = debug.out(5, "False", uri, True, 2, False) return False # Article is a Tyto format and not empty (exit on errors) @@ -89,18 +88,16 @@ def is_article(target): # Return True or False # #-----------------------------------------# def is_tyto_format(): - global head_contents, text_contents, error + global head_contents, text_contents + global head_lines, text_lines, lines separator = False head_contents = text_contents = "" with open(uri, "r") as contents: contents = contents.read() - for line in contents.rsplit("\n"): - if not line: - continue - - if line.startswith(post_sep): + for lines, line in enumerate(contents.rsplit("\n"), 1): + if line.startswith(sep): separator = True continue @@ -108,20 +105,20 @@ def is_tyto_format(): else: head_contents = "%s%s\n"%(head_contents, line) if not separator: - debug.out(21, post_sep, uri, True, 2, False) - error = 21 + error = debug.out(21, sep, uri, True, 2, False) return False if not head_contents: - debug.out(22, "?", uri, True, 2, False) - error = 22 + error = debug.out(22, "?", uri, True, 2, False) return False if not text_contents: - debug.out(23, "?", uri, True, 2, False) - error = 23 + error = debug.out(23, "?", uri, True, 2, False) return False + head_lines = len(head_contents.rsplit("\n")) + text_lines = lines - head_lines + return True @@ -156,16 +153,41 @@ def cf_valid(): #======# -# MAIN # +# MAIN #======================================================================= #======# -error = 0 -# Tag separator to split head and text article -post_sep = "-----" +# head_contents +#============== -# One Line Tags in head article +# Optional Tags +nositemap = "! NoSitemap" # Article will not be included in sitemap + +# One Line needed +sep = "-----" # Splitter between header and article title = ("title:", False) about = ("about:", False) date = ("date:", False) tags = ("tags:", False) author = ("author:", False) + + +# text_contents +# ============= +# Comments +text_comments = (";;", "" } + +# Tyto Titles #1 =

+tyto_titles = ("#1", "#2", "#3", "#4", "#5") +html_titles = { + "#1" : '

%s', + "#2" : '

%s

', + "#3" : '

%s

', + "#4" : '
%s
', + "#5" : '
%s
', + } + +# Statistics +# ========== +stats_comments = 0 +stats_titles = 0 diff --git a/src/var/lib/tyto/program/tools.py b/src/var/lib/tyto/program/tools.py index 59e66da..290e3c2 100644 --- a/src/var/lib/tyto/program/tools.py +++ b/src/var/lib/tyto/program/tools.py @@ -48,35 +48,10 @@ def exit(targets, error): #==============================# # Set and return date and time # -# With local options from lang # #------------------------------# -def nowdate(spec): - # Default - F_Int = "'%Y-%m-%d %I:%M:%S %p'" # Full International date - S_Int = "'%Y-%m-%d" # Short International date - - # Get spec option for local date - # Get Used domain lang and set format date - locales = ("FLocal", "SLocal") - if spec in locales: - domain.cf_load() - lang = domain.cf.get("WEBSITE", "lang") - if lang == "fr": - S_Int = "'%d/%m/%Y'" - F_Int = "'%d/%m/%Y %H:%M:%S'" - - +def nowdate(): now = datetime.datetime.now() - setdate = { - "FInt" : now.strftime(F_Int), - "SInt" : now.strftime(S_Int), - "FLocal" : now.strftime(F_Int), - "SLocal" : now.strftime(S_Int), - "Year" : now.strftime('%Y'), - "Epoch" : int(now.timestamp()), - } - - return setdate[spec] + return(now.strftime('%Y-%m-%d %H:%M:%S')) #========================# diff --git a/src/var/lib/tyto/translations/__pycache__/logs_fr.cpython-311.pyc b/src/var/lib/tyto/translations/__pycache__/logs_fr.cpython-311.pyc index 535c427f4008c8f6b3bfced312510e2c2e3616d4..056216d2557699ef5626b11a955bdb77a9651eeb 100644 GIT binary patch delta 198 zcmZ1@wo{CEIWI340}ynqmPnmHkyny&(?s<;R=Fs-6po3jbU324QnZ2@G_@z*`pLxW zGWkB^L4F>fYS+Ay!>dYC70NPGChuU7viUF57ZyhC&7at{8Tt8Ai;Ch4@{3F2OEODxQa8(RiZXH;0Zm~9;^KFc st-1Ud6()Ca>4?iW@ZJ!VZ{WKjsM)}CLr?|8Rczp!e1a>1#Q>-n03tR#>i_@% delta 185 zcmdlfwnmJ1IWI340}yNykw~36kyny&-9+^|R*opS6uF73bXbBJG_@w)`^h8jmS2>c zSfY@Us*p1ICgVW~QJ@~zqN3E&B88O1ykdnMb=SO-!>dXruVm7Yl>$mS7L{Zs=cHOG zq~z!29bTELkeirSSelquviU317ZygX&9B(C88@qPiZF5+0+llYaq-K^&Rl+sT9YSn h=?G~w@ZJ!VZ{WKjsM)}CLr}MYck)%P1QvauIsl`_H|_uc diff --git a/src/var/lib/tyto/translations/logs_fr.py b/src/var/lib/tyto/translations/logs_fr.py index 76078fe..f35c43c 100644 --- a/src/var/lib/tyto/translations/logs_fr.py +++ b/src/var/lib/tyto/translations/logs_fr.py @@ -49,7 +49,7 @@ domain_srv = "URI du serveur" # Errors err_arg = "Argument invalide" err_hole = "Dossier courant invalide" -err_date = "Format de date invalide" +err_date = "Date invalide" err_lang = "Format de langue invalide" err_dir = "Dossier non compatible" err_no_dir = "Dossier inexistant" @@ -58,10 +58,11 @@ err_no_file = "Fichier manquant" err_cr_file = "Fichier non créé" err_bad_uri = "URI non compatible" err_post_sep = "Séparateur manquant" -err_post_head = "Erreur dans l'Entête" +err_post_head = "Entête vide" err_post_empty = "Article vide" err_ini_file = "Configuration invalide" -err_post_data = "Article: donnée manquante" +err_post_data = "Donnée manquante" +err_post_title = "Titre invalide" # Warnings warn_no_dom = "Domaine non configuré"