From d4caf069680ad31fbfed08494ac209f1484541fc Mon Sep 17 00:00:00 2001 From: Dave Walker Date: Thu, 3 Apr 2025 07:09:52 +0100 Subject: [PATCH] Fixup exported PGN compatibility issues with some applications --- alembic/__pycache__/env.cpython-311.pyc | Bin 2994 -> 0 bytes alembic/__pycache__/env.cpython-313.pyc | Bin 2525 -> 0 bytes ...875a_metadata_values_table.cpython-311.pyc | Bin 2083 -> 0 bytes ...875a_metadata_values_table.cpython-313.pyc | Bin 1917 -> 0 bytes .../175be63b0ba1_moves_table.cpython-311.pyc | Bin 2065 -> 0 bytes .../175be63b0ba1_moves_table.cpython-313.pyc | Bin 1893 -> 0 bytes .../29dea8817c10_games_table.cpython-311.pyc | Bin 2248 -> 0 bytes .../29dea8817c10_games_table.cpython-313.pyc | Bin 2081 -> 0 bytes ...137_analysis_engines_table.cpython-311.pyc | Bin 1837 -> 0 bytes ...137_analysis_engines_table.cpython-313.pyc | Bin 1666 -> 0 bytes ...741fcc800ae_analysis_table.cpython-311.pyc | Bin 2766 -> 0 bytes ...741fcc800ae_analysis_table.cpython-313.pyc | Bin 2588 -> 0 bytes ...ebe5dd234fdd_players_table.cpython-311.pyc | Bin 2559 -> 0 bytes ...ebe5dd234fdd_players_table.cpython-313.pyc | Bin 2322 -> 0 bytes ...ffa024_metadata_item_table.cpython-311.pyc | Bin 3418 -> 0 bytes ...ffa024_metadata_item_table.cpython-313.pyc | Bin 3072 -> 0 bytes ...c_mark_fen_as_a_non_standard_pgn_header.py | 38 ++++++++++++++++++ docs/source/cli.rst | 4 +- src/chess_analyser/cli/dispatcher.py | 12 ++++-- src/chess_analyser/constants/__init__.py | 3 +- src/chess_analyser/pgn/pgn_export.py | 2 +- 21 files changed, 52 insertions(+), 7 deletions(-) delete mode 100644 alembic/__pycache__/env.cpython-311.pyc delete mode 100644 alembic/__pycache__/env.cpython-313.pyc delete mode 100644 alembic/versions/__pycache__/0bc8b67a875a_metadata_values_table.cpython-311.pyc delete mode 100644 alembic/versions/__pycache__/0bc8b67a875a_metadata_values_table.cpython-313.pyc delete mode 100644 alembic/versions/__pycache__/175be63b0ba1_moves_table.cpython-311.pyc delete mode 100644 alembic/versions/__pycache__/175be63b0ba1_moves_table.cpython-313.pyc delete mode 100644 alembic/versions/__pycache__/29dea8817c10_games_table.cpython-311.pyc delete mode 100644 alembic/versions/__pycache__/29dea8817c10_games_table.cpython-313.pyc delete mode 100644 alembic/versions/__pycache__/4f04d4da1137_analysis_engines_table.cpython-311.pyc delete mode 100644 alembic/versions/__pycache__/4f04d4da1137_analysis_engines_table.cpython-313.pyc delete mode 100644 alembic/versions/__pycache__/9741fcc800ae_analysis_table.cpython-311.pyc delete mode 100644 alembic/versions/__pycache__/9741fcc800ae_analysis_table.cpython-313.pyc delete mode 100644 alembic/versions/__pycache__/ebe5dd234fdd_players_table.cpython-311.pyc delete mode 100644 alembic/versions/__pycache__/ebe5dd234fdd_players_table.cpython-313.pyc delete mode 100644 alembic/versions/__pycache__/fefca1ffa024_metadata_item_table.cpython-311.pyc delete mode 100644 alembic/versions/__pycache__/fefca1ffa024_metadata_item_table.cpython-313.pyc create mode 100644 alembic/versions/e99865562d6c_mark_fen_as_a_non_standard_pgn_header.py diff --git a/alembic/__pycache__/env.cpython-311.pyc b/alembic/__pycache__/env.cpython-311.pyc deleted file mode 100644 index 9a1a0ec0e54fdfb696ad98d6f68a3f6058432bf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2994 zcmaJ@&2Jk;6rc63KX&cd&1aj$lxds9btyKjNUN%dDoG0}ps4D{p}ANa@5I@#-Ziu9 zd{nIzBn}{P;DE#lDW@RR9=Pxaq#U@~)k?Kiid4Y`4oHrgqN*p}%zFKiri^#rzIpG> zdoyp|{Kh}^^(hD%{^zgK#TY_=vQE&%7W2FY%nwLInqZ)^upkJG4;i7dxFB*~1YTN@ zI4>FDa%3SQAQD-L2Cf#OB)S6r{r2UN5F$diWLrS!A-sMAKj8&gleOqq(t-lt7<}U} zCbE(UY_@@U7<3R#fL7_1F)z0e$m55}v&!FWbXM?`CEXx%mbs*tpf^Cwl5Ud161B>O zVjz_&mSuo83KEB`JM&(I5~oVdVtWd}u;sF(J^vTT56A%;w5|5y0tx$SLhr&KASc|> zuLK)_?jxt2JQx+yL`~9#N8xP=k^ryYgx=9@Prb{ZMhEO7!T4S~NMD5gwnGpD-XMk+ zxrI)lbI6v~LhIsPvSqm~IJShevQF^n9>vm4m{T(4Agv%~}Xo^X*8K3hIyjbP0(GY%%J z#Ka~c8qDJA?97ep*s<^;xLZ|qgGFeqWKJ~O7OvWSHMXFaEY*n2~)oD4sm$bhyRHL{|${V>VHEw%KMWt%lb~X&+g-x|gw5;Tb zpz>0VN=w8kl!>Eis-t>+hVBrm8ihsO)NC)I>8e4BPQj`;_Ix(#Mf|*bDLzWoO{Rg} zqO2Y~xxFit9XYRmk-)JiI8-%lwaDzeB(0i-&L(FC8V5_86*_)(Eq})*)Xr<_D#>4^ zR%Ovz&tHXX8djxDOecSXS}QOeJ3qHfY-S2B9B7bfJYDE_1gnLrL8u01XA|x#gS?BKyXqWedijuFF0(; zt@cRlod=*)_b7f%G1G(I57@C9xz-PXO zd)G}k_W)FOk(esgEr2E;WEg-j90Gs|Ag&F3s%=|Eo$DCNm~eXF82UKb1)KqP#JjK~ z8}cF*N|y9>Pi8k+(Ew*4R62h6F`v&SD7#K5%e)t7$YA?nya68&3c9HWGRkVhi_KRJ z;|4h8mm`}MM-bZ2{4ngGY?J9A5QrFWMP$%PM?q$@QpK1K!N(guc-(pF=-Z&1X0}(L z-r=+-(ct86EcrAx_9Qm;;{|v8{a+UAu}g03QX`e#9T@rk-DXr8gfk9gpOMW^n+c>0 zKb6x@Qh6XyfRKU#~R9kgV(>Ap49o8F>*y$ziu|s@`|n?K=%; zRi5NzH!ZepUAm;hX8DYzDJL7oI$=$3WHb~qmrUbl+F)cE{3*<&-^XQU&0 zBgb9-pQ(KT61g*!pS>(T7Kdg}g&!YHF#eP@n~@)9M8=;H82=9EFH5smqQ8X%pxF>* z_%omF^OA;Dg8QJ9^Q(d~RPdBe#rajl>m%BNbiXQiVI67J68qy-V7HiGCk)j2UVACs z4xqlk{x1BCo`VkYB6$`207O-Td`L4OV+d&f0R;9y5E^K**84m|*;?<@K;yOE=UHzT zw9OdY2j3pwi~u7kt~gc`ry5dn^OLVv-PBZF%D7UdCS{M~4E~Q;5T??LP(r8T@txMysG+qlHIt9!8589Q) A)c^nh diff --git a/alembic/__pycache__/env.cpython-313.pyc b/alembic/__pycache__/env.cpython-313.pyc deleted file mode 100644 index 12eeab417f0f3248e64840b6ce6381b5e56a9597..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2525 zcmZ`*%}*Og6rc63?cMcPfI<>OoxuVeM+DO*v_kz7kf=(iP-G{Uf@H1jvDtLJ>&~nR zM5@Fw?WO7=>ZONVd+VY90Qn07ftswyp{gRaQY+Db6e*{^+4ZuJk}=wO@6FryX5O3M zZ#hULR0IS6^Jn8j8KFP8;t#Pa9Q+N!LsUW~VIJKSsDQZ~nh)I+sp!fg$P$%YS(*>u zjL-;1OOayI4;9Qbx)d#*33Oko^dht*WYOuXQ-bFQ8NyU4$)!jd-Ib^cQq+}VknNlw zE10urs;gY=&KjI@Ne%26HNs1=lX_nHi+kq~n^uiXsOs%yonfz} zZAuunmkC#SJ@Gx=UdDIZ%*GnNQ~W~J%o;W=&`f;YZOAydTkXbjV8IYgt5!+N)+z>3 zmkA|UWB491j0ucq*D(7^Z?$x@;U@B;;3_5V4%K@E*DNz1$R%Boav+1P5^ zt+oxp?kCyThGtZkNpo$YO^w@*+R~`jWcHdtoUo}iNi8oqA}l#6TcZtPmz%`aYMQM% z2}8FD)r@jQH*3s^*L2MwRl97pY_^b(IuWnFPRe~t(@nkt9ijYwIm%J>X^iVV6#|#N zY*Wo-T9x}bN!m8cK_l}5<@bw0hY@zJ7w#}ZS)rz_kis=;wJO$X;TlxXuv$%G+J#%x zx(nN3g}G(I*o>(eYfNVa*kiMzR|~{knP{y!11EEoyBCGN14-WH*}jCwIyyXuVm%!d zZ>spo@Ow|y_t)q4q*zDl-;(-wcUo{o~;QnEYB z$ex_)$eArUvn}ISB2q^?%E)iZ$ZN(?uptl3r*SOm89 zMoF9o*dBX>7y6A6(11%BLG*z)96=3yfifii^H2AGy&=7wLKer$Gd_c9&CoaQij9FFPwR32jaCHF#9vK~DCl1=! zG0^5iPNYRiU0-z+{$Z#Z5D1KF5W~gSLOxD8!&6>OC&nSkycABahs3gO>b{NgTjj_L zZNs<)LEUc+-;oPl%0H)WP};*K-do5R>t^IUMftap@k@#^?Sskbe-meJxo8H~_*G)x z!2@8HM17-sa}0FndMZ_-J4@8-Cm)gZwzF&Q2@nqRt6X zUVcjKHZ>RW2`6b-4Ir_`gjZ22LKH_0y5)7it!=c+LtaJQrkv^af&ULs=G5!em;=PE zlatb!&rfCk9s3y_z#8%jEPo89wn09nIk0i2V0C!xi-I6LN24!L{y7?afd=~ z-)7b$AWCXSOmFhPv1d~9!Ad7JwwW5+mU2+tzO(D8!!!ND@Zn^iFuFgEfbhihmYD8{ XL!08zGbz0z4gD^i-;oCC7^M0SDrPr5 diff --git a/alembic/versions/__pycache__/0bc8b67a875a_metadata_values_table.cpython-311.pyc b/alembic/versions/__pycache__/0bc8b67a875a_metadata_values_table.cpython-311.pyc deleted file mode 100644 index c3bb05e200dfcfed74ea425fed238370e82027d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2083 zcmb_d&1)M+6rWwKq|sWk9pj`;X>HYZXw_m%{*dh`rcmT0xW#UW>q3QLS!t%S-2G5y zS8g0A_>hASJs4VO12(vjx+%`V$DT|7fE9>h22u*Wv^N#^V0Om#2Ree+?k?yO^|^(j1)p41=%H3L+?nh(u&VGUc3X266#O%mapE z26Ms2STRDmFbU=`jZl?@=0KB#b6qq*BSiT`zS^>lK#ChuB^MP^D$~ewDPRN7XMl|~ zv9TAxsts&6i9S?v-K3ku;M+r#Wt8Z7P+p|2PIOm~Z|FvaI&oLe8&p;A(v6Z+vaR^S zd?udC7iRO*Gy3dITK6T?$;2nF6ROY7j?WavQ)-q`-KFt)U?53Nq(@Veqm!w4>Ut)X z%1oukW+umHr_!qWr#Nv!=6IRjt5B;zd2q#ojS>={Q{@0qhi&8q`oWI%w*CQFJM^~zPC`$^FJuk>uht?R*4pPk z=Ud=EeG9b?LF5C7=3zUc9k#=5RIn%!wJ06PfQ9b23$PflUFWd}7&M{#4ayEdYDbrN zx5#bCNd2QmYIC_nK7=&uDzlQQvrX+&y2-;u-K1KH+yVi%Dh6bbL3yv)tO~8$KoH$?O_+oOdnV*mO!xQa7lXFBOs-pbXXKB+r(a);_NP2>8B_l_5Np za*^qTvO(DVGIZxBU|Z;!5_XG8%bQPy-IPI?{_U`WH9|TF#WB0~UzlW!*c)EtC zK~lqm`$`pGtKnMKN$md@te?@(al_wmsmGwC1gJXR08+n$B?}W>y6FW0E~D5Ac+TqqNs{VvNK)#k&AO2^?4hB5({JdC*Gb3dC9g$wj4lms;cd_z0IH&a zEp49Ep_|m r&hXCt{lHhB?-Q@@ty=VL4^047(L_C@N{|=j8GsiO;6<1+pMPlx7U diff --git a/alembic/versions/__pycache__/0bc8b67a875a_metadata_values_table.cpython-313.pyc b/alembic/versions/__pycache__/0bc8b67a875a_metadata_values_table.cpython-313.pyc deleted file mode 100644 index 5c348b091cca2d60adf14ec6cdbf04e5e14b8449..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1917 zcmb_cTWcFf6rR0kHCjowW1L>nHdbthR4umF7x~suD0Wh8V<&j)LKDF<(hl;vt6gPw z<;I4B$xBUN>QV|#Vz5aAb>IBhpCMJ0nrY}uDYS2sRFjX`1`lw&k_K?@I!OSp>T4*gfGEGpaTMQK^GTD*Ddb}zpZphI4fv!U zKL^%i(xE5yL?Cq*<#fkpc@g`_L_SKbBfEmVl#lW@R@G&^Zh4mLq~>O)Q(C?-nIE4( zlM`9gV6Zox8ksUNnw%V-C=6@r48h39sadu$MjOcvYNLarT1uOm*0kv{ZD?Y2cycVO zs=qVuL0Y6x$G0ljDPS5|ao9s?fr@Ts8 z*!HMu;xcwj&v2arf3CTbOkjxvC&vO$(#<9gmc^FX68c!WZZ^{jmX#LK5}1bArU6?- zOVA}yB!UreP^1HjG(I-AsgoBKlLHgk3Z4RhS5xcB1k8eXa}!$R-@?spxCKsneVZ} zi`MAVr8VMR^6TZvTy&=oo>}ndH zV;USuL&AHMCJI4w7(r`M(L+?3aqUXUq0u?V$3;x2qWi>hinQl?!;=NPG2=R(PmtyK zwCAczuvK(Uq2GcN9xPhQtazAs856DJ%q(%sdG~f^7O!L5Etjz4XRZ@>4HtYbGqZ|4 z?;Qu(8=mE5kc~@utB_e|ms$ULnfAsrTEE*E3k~0g$}BvUa*-etlk@EHv+VO8ux$%G zl9f-c-MMxIUwQ=9&tjj(b_RCEJ@u}7DA!=NiKTa!_io&~aX)u>r3R-%wAwxJF#pZk zgSD^i?^bGXrm1{scVuts-qiiK4tr{FoS{F$-tS@WzFdbFpPXLaj~}cZI+{ZqzlWmQdE#6tIcK7`t_XjuFU{nb9E5un!chRU}m~O!^ zsN!#wS$PodF5xqYM#J=luY0#_WEWO(X@l^bkSN!YSpCpW!$6MX`pD-=HVhKuJnv!> z=NnHW;eI{sHoRPN&5DiRCTYg|bIgARq(AcK2xU7SPyK@aT@kU$4B5GeH0-c;N}2|e_UR#L1KLnwK?d3rPN zbLPFb`XLlj5x`IX{GR*XgV1kc(*>o&oc{vMw`da)ltx4%vLO}av|RM0J(Ada45jEz zd)vHX_|ksjO=B9MD)Fs=CGn>RsD}oKvMmpHeItMEnULnCWIQjxjDTyiEcKQo_*BtA^dCQ>&SVu_{X z&H1FN{vqxel{wy^56jfdQtsU}Ay8D}vQ=8=!HdB-W}Q5E@M1U~BG#9t))R&@OgFPT znxSW?VRMzx5;cjfStj=}>Xez8?L99rAy`mSbpE#_%I5&>LZQbK$?)ro<=BB;@Z@%u6 z5cwEtbK0vL(di8lTXiZ_&HX;4peU( z$~E#PBwAUJ&hhdsHG3KYFp24)p4qUQ%#(5CDVtQTH(N`8P7KBc)5X>n|Rrk zOdVdW4IhlwMo-GGc)LW>#N$Uw15Y*a6nGH3;iG|*!pT+xuQc(>pH~82-(LtwtDmqj zxJMRN55%~Nbsht9`NyEY`8q8mud_k0ipp-`RRZO3ACbKa=j~u@95@~jA1wDtCt*JU z%YFxl`=s}(?=_T>rZQ6RV%rq_20>>%`WE+V8nLpP#(hqu1f9b~%1nGbxW7}`P7d}% zLpQQJv{+%+g^m~v=vIgEu%_vzX*s$h>aS@mAmrj-jtvMB5kzG7O7bu8O3@-^gMP%O zK`JKD7N7B!N0OwL?30uh>XAVtP1e!GfALrJcD*0Z(Diy3TNqs#-^2T0I|kT5V`meI zz0iKSy7AqO>gUbycpW7G8z^x$o9qbQKbo)2oD9{k%{0TYI!XdIQ1UD`x2Nvks!moP n9eKX_>WI{@PB()e)X^MZ1I@L3sswG(PevqZw1qAq?PB~3LwVE8 diff --git a/alembic/versions/__pycache__/175be63b0ba1_moves_table.cpython-313.pyc b/alembic/versions/__pycache__/175be63b0ba1_moves_table.cpython-313.pyc deleted file mode 100644 index df7f6f1a70ae8e5b6c31c8a2d2130f33064d922c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1893 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 Xd#4h-QU!@W#ULlXyvT7~?#28KSBk{} diff --git a/alembic/versions/__pycache__/4f04d4da1137_analysis_engines_table.cpython-311.pyc b/alembic/versions/__pycache__/4f04d4da1137_analysis_engines_table.cpython-311.pyc deleted file mode 100644 index 80bab0d8c67f5ece066b9ac96aea6bf8adac0c2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1837 zcma)7%}*Og6rWwM*W(4pG$K?f4Y+&>7hxM?Q-q>Oe5FMVZWM#mSd~_bX96bcU1xSp z<4Bb_aNy7bhe}N)B5|Uv;E+F}f52Mu0gV)?QZMbz6+Pup^^L!PRzw}Wd7d}#&Ad17 z{oeY=P)I{C?)?4xX3U4sZ$fAfrL{Q!1s30q!gG)Og~-i4Dy$#qd54HD&ve7k)&0&SqB?G{=p)8K^`Y<(9J*y5IL=zrJ- z8@3_RwWs86kPzvH-!M_KD0<_?SIgFB!JYN#_8(H0psTpC#dHWx`IlIh9B^yG9Rl9-*FO3kGcu~afSJDbw9Kg8>zGRIl^ ztW2#u<^FXGE{{rFwo4h_ec1uWtmT`Bi2b#tUx*vbu<~2FX>3r_;ToYOY7s}bEv_=^ zmYJ3Bq!AWfFrjqlJSmAXxxm|FyR#;e>u>KOv@Pr#gUD{X%ph-f*2H(J9D~(K$MTx< z{ww<(AIEUpNz(;zqMiocahuvUB={I2KIue#ngEA(O?z*DXnnDGK%y*>|(2ILTya?qVK_S z=F_#$#@8OLtd0wHG#a@VN$|e;%>0AL*_AA)S2D|bW`1>9U;i>Hu^tE{8e}3*ygT0j zmfnCOmmPzvi?&%VT0F2~xpb27_P1Sr!tW@EFa%qzpgt7tfeha3v2W%I;QPjOJ&hYIw zSo=13F!D-1)LttdPFHcdhSSa6u~$Qf(H|xbCtmwKJX6IpH9P~F8velRpRVFm4W}C7 z;E__rqcuF*kosTV_oDM2UZ~=Q8eaG_6!5EmAz<~ZjC}}!5wA^+ zvv9F!?@Y9Z2Xvj-d0pqKTPXo1n24E)hUI})nOZ?O&rHM2Z_#3f^$Hu&INS%w;b9$W zX4$UcielOM)5>ar>+b<|-u zkTmR}q5smasL#7fXXt&eO?8ak8{EbFaCQKwiU!Vx#&$#d<%8_Yk%Pyz@SumrfU0Qh zY%1MSj2}%OPX5&E-I}b0V;)KaRZ;pZmfY3$mk)*yo*((X`{syvH$Sd*Pk1N^R7J_U TiY36sRn{j-qjhu*YZT)j^RBUX diff --git a/alembic/versions/__pycache__/4f04d4da1137_analysis_engines_table.cpython-313.pyc b/alembic/versions/__pycache__/4f04d4da1137_analysis_engines_table.cpython-313.pyc deleted file mode 100644 index ed65d4887f6d0ca972f165c9fd7ea11f183ac452..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1666 zcma)6-D?|15a0XIX?2z?H%(k>H}&DK`WkG>veY`J1RUFGZO2OR+0YQdan@~RC8s@Q z@8m{-g2_uwU+O*-k~R=OCU5yuEQ?aJ$y+G2Z=r7JTj}oUq$nYUF5L2)-^}jJ?9ALr zBB27d&i?azX-Wd%ITzYX4#CMI27Ux%zyJgof+4O7DKMF+m!8UIGPAQ;RsDlS3UrY|1Kp}2TtqaoiP`14 zKt;Ejr}1tF6q3+4P1x?&*nA~!5epZ$O~=|ojz?7+RS~v5)5S&ZpuOS@u(E)Yivlmf z^)?UI#SZL%VOEUm?V^EorK9KoW+8T2z>cB=49SqsOI=1o+mGPWw{5@R8*Ijlwwy3>DoDgXJ#7ZV%n%WD%{t?Swa zElvC9^YfRl8OsJ!FXxxc{QTOIx%s6okR%I5j}hL}G+qoE%nVwRik?N41=p!nFpVx_ zAC(ZHis6$oF45$|HY(m+aIxnTtBiem`f4k(RaEa{`&iqt4t&Kt1}8jsic^~&B3{b2 zc2H`OxYaH9c4`srAjhp%5cX47iF*STeJ{lvd0zWDQkH`%TjgSEhaF}O?WMXq*|fq} zGf``}TA55$>oi)cmWX8|a+Y~N!#=Ofwq5W{R=&M*_sTJR{~1)jk9`;0AAKM`RPU=# zk2@jX>(WTL_ z454@LmSZ`^ZB(g~cezcJ+eoZ4Xwqag!LD!lyjZ45_%xFk-}poZ)gT&2Z-fm$tGIT} zK^Mpb)AG6V2-{vrf*|}UDuVoXFAzq41N~3IdoLh(XJ{AhjWofB$HU{hiM`ssac^}0 zS|d5s1mnlkxsaMTn7Kds==9;4$wqRj33A6%nO${nX@6w@_JQ=nHwX6NsgE1+b4`%> POM!y&vR@F!f`|DR8$owu diff --git a/alembic/versions/__pycache__/9741fcc800ae_analysis_table.cpython-311.pyc b/alembic/versions/__pycache__/9741fcc800ae_analysis_table.cpython-311.pyc deleted file mode 100644 index 67e5e88d7b80831c1f536c1e1fe4073e255b4e05..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2766 zcmb^zO>YxNba(wVUVniLEg(KzAQaOkb`l&C%c_(nL865eNOP!#v|8^Bj@|XHnOz5r zR4E4z9D2y1QX9#Uf)r9Hsgxr>pg&+&+CwxFYNejIrAkkn`qpb342pzMMsMD}nfEy} zZ{F;0v6#p~`)mGXc{;#x|G0y0^LL2dKY{p#o98fBr~m9Gg!q2??4cz5hm{k1?b z(5C%ruo%LDA|hcT;$Q(Zai|y}J`%?M+rrVVZ4S7o&Gi?fE|&--{F)20zSkp=4R>T? z?;$I;W#c&dz+a5xIF7+Lf&Ft_I&r@;smW^7s2C|zE~!KmZ<57|QPH*3mFawH;?l+8 z+ln%t&C0~%5F?)&zLYDGvC&etBoB*Il*lGYO#{lOMzSNh!R+YZXf`#R%a4o$42_Om zyf`*4iZ9)zrUi!P$ejk!6v6`Y8aPVxOwjAIEc&K1hG-`a7Jbtli(&n)CiR%H5|uS& zK~m)sQ4J>l@ey<%^xfY9|H7I4Yi6}aW8Q?5@3yKd-)>ki zyBPrEYLCXgP5%Z+J?lyCp&#g*@9A%VwP&6Sz&N-WdM|5eU#*4r)tb1k)*}0AE!t?Xwr#+KLzYoTroSlECY@~n4D`fQ_~6e{!hK$+hVKo+{!_K*#L z?7_EXH{zfP-D^-oIjB>~S%$iWiU}3`9Tbg7omOfxZAw3oCQHhlGA0qNT+xVB!Iwb> zX$=)hgGyMarZ2j)EM9kuhu$zGL(wS|A@Ac;>MD!et!Pr6P=#nFL$abYsH`-ZNET(a zA)8RFm?&$SZno+B=o;8GhAQ}evK!n?+q*lL4pTR`SX5~jNU2?3nPA8)IHjwNn#Mv` zG?SDGWr548E}JYkXVQvRW{0kO3;TvNr*zFQsa%0@4qb+5D`l;3_9?gP?$fK=nR$ay zBZK8dl9{G@y`h&5dCUc$YRic>LMmO4wtdd%(qGT398CGXx-mJk= zZ%^B?57nD2)To!Kj0rslUJpYzBuI!Q?u9@2;M;AKe1XKD!pmn@g_gMGw@}VTIS1w1 zvsUulAHt^iG`bmm-muV&jbgC;!A7mtPY@T16j!Fe+VTb4f5P#fu)5Gz1-ns@nN1&HAxXlzB1tT0HtUes)D4-s&mIeP60Z}3aYvO^ zWr5V1^tdbI79Hk;%x4J+vaoyM3`wG4m+$_f(TI!OJfv=PZw3Df6>2(esN_qU1+H7Q z4EG0Q$H(*hju7PiJ6sRNIsS~roqiYo=03LiVVnEJ>cS4<4xU;<4?*`NfX$uUKAl~P zJ!~w`{d#u!dna+q;<5lXm)#!Dbr|Q@Mq7hV4q1l>oy3sE>nnBtD#3KC^sp n&G++?ZfyVd(&La diff --git a/alembic/versions/__pycache__/9741fcc800ae_analysis_table.cpython-313.pyc b/alembic/versions/__pycache__/9741fcc800ae_analysis_table.cpython-313.pyc deleted file mode 100644 index 4be0818332f1ec61455ad5a9f2433202c23d4897..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2588 zcmb_d&2Jk;6rWwM*W4DbLYQ3I18`it- ztew`CkfL6wxDXDNXc8$=TB+efBFFw2HWnfpDsey@daDQ(S7z3`#(^MOl#yrr=J($G z-rJcsZ+0UQ3DEZQm8ba$KLEe5iPr>I*xjPSJ~~~gTEqd_k6|X5k!0}{T`31}DC5fnWnq}7E&#=$g9|v!@C=^`GMwstu0H7MBmbh8 z9DPI%b%F%}x5*JX>`3i-A>MXdKX0l=#n$auNzEEalIGB&ZtIpAyEu`Kjh!7HxUOlV z$)t)J8f2$q17}lNG%}P;X4L^{93!=aViR;o#|D#wslMb;-%v6(kV+4Z(qI43$nfyU zs3bk5VS_kNpp0&mk*Oi#zhY8HagOj-ah8Nzoe_xLI7qnF9f{i=4{0>HRjH1uTa59`)-wv_rNs|2XlN=Yzp1n2k4+y!a_&9XrYhk;0-U@bC~ zv=v!tvC6h$YZj&@s`2O3iUtYY)J>&`u!hVMfvTpJv8q*wgcen!td?jgBa&*GR>_fX z!x_qH_v^XaQ7^bj$2-H~LCnfG32RRIRGi{Vcv~gnxMh?JCJ9_LODK;p@n0}3wM0a@ zgmp7d4qtA3*fgq)Tc%yYs!qc>e1S%*=gmFnS74XzJ-ME^Vk2xPa_S;VOkk^+wQeOQ z&>}LdVu5~4;xe`tkXEu285e_!}lIdZB9LS|8c4Y&wIwF)&|$pE9up9+r2e7 z>Y=@B(e=)i&eb=!{WUn^p?wddkB)90ebBj$YVe$go>|MT&#%m{E^JfYF%Ny`A^#}2 z8GI1hWBU*EN7(f}?Aj3Ou$QiMXRmLBwidQBb;m~otG<=0#zv}RGu6@AI{e`Iv39?R zd+3Jkd9>Jr#rkfN4lnX(d6&<*6#OiX&~&I0;;ix`#4*qn`bkbt7(EKN~}SgI6hZekWKW-liRxVhsx zw{IA#q0OU01;4>;0?fuolb5tBG?BbJV=D>{GCixkIK&2)N|=T8_o(5yf|V;9=v~aV zhm{>0)8Uzq!qf-^C72 Me14MSjyoIkC%3Tw>;M1& diff --git a/alembic/versions/__pycache__/ebe5dd234fdd_players_table.cpython-311.pyc b/alembic/versions/__pycache__/ebe5dd234fdd_players_table.cpython-311.pyc deleted file mode 100644 index 6b5cb28c0ff9f5e8f29f4e3ed1f59b1ffcb33e4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2559 zcmb7F&2JM&6rWwM?TO=$B!rJb0E>@;NfSGcO=${LGzm0(q$wd%@nyB~OcKL-*UYX{ zfMP$+<)J??rv`@4eBA7W8&uy)&~1D~JK6e1{th(u&v%F7u!@5y*1vG(Xn-kb5d zb4B-M{J`_-INz3O1D-DvpzSnB{HFnh;7o{mXgg76106iE?nU|{gmz%ZklO`{_~hN8(tGToOL>>Er(6Q_of zgF}f_e=?O$ok|7*ufJ|?WTA&88RMX%-M(rXqvW=&PNeG4q#^!IbaH}nC3vV>$ zM6$h2e4+0)BHQ(_fc1^WoOsriRnS^%XufB^w}sz0V-?WWYDWMizIFcxq2U&^hBa@a zk+$`~DoEEF8ZG-8Hk0-izOQc3|HSjx_mSW#yy#lvRa?+;LreY-t+s}imxR{CtKhRW z7`3(v7;6n2snwTmVhg=i>+hi!54LYXp;E9uYyRFv>ycLL?n!s0l8B*qn!SIUMLI|) zc(JS1i>*i!0;I_Hp6ywy#ZW{LB zq46nr8Y@n;c^V&KW?|aA9Ur0d@O*_lHSG8VGjGtWZN3!jK@X0bhS-~f3lB3VMR`x#aS?PJ>DiOR0XHp<-w9t#z!mosJq(t8>c=Xz@J+}S_Qbi3CM$%yi9eTHKpj}RD-$1*a zdfz|;PHV4X)Om0bF9F&C=w)OpKF+_>e?}Sr diff --git a/alembic/versions/__pycache__/ebe5dd234fdd_players_table.cpython-313.pyc b/alembic/versions/__pycache__/ebe5dd234fdd_players_table.cpython-313.pyc deleted file mode 100644 index d593693d72148ea544343e511ca766a2fd519aac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2322 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 VIj*ycUZK-G$Mr!*zn<7T^goi9AWi@P diff --git a/alembic/versions/__pycache__/fefca1ffa024_metadata_item_table.cpython-313.pyc b/alembic/versions/__pycache__/fefca1ffa024_metadata_item_table.cpython-313.pyc deleted file mode 100644 index 9747911838e40ce93edc712df62136413e3e97b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3072 zcmb7GO>7&-6`uVexm^C~U$G=xjAS>W4U;q_CZ?P^ku6%0WYR8I$`34HyX1}}M&vFt zODd6p0%|Ui(}Pr?0rF$OLQ z?0esP^XARWdvE5*=aUgU$#?#?avi9@FsAv44dUpxKzxGEAO#Vma0)-q&GCev6NnIG zyf81$If%oi#d#-j0p^&O=G?>$n3Kp$o+Yp1dI_v367ekwOCCj>;2ppN?zVA}_!+*$ zFL@Xaa-kuY8}h(^kb7*oU-1s0cSX{n_!XZ`b*_k^z-=Ri%bKp0wP3!Ci@~y%Enr#B z;Pt$fH;v%z^ki@uFXyxi%gb6cHc^*gYchzlIIiol@rh+!m#-46m2q$yn#o`+8jGKg zj-MZo2BQ}z$D@-IFNZI_a`8eUA!_Q9z{8h%l4`|#AKo9`QHOX$lI&B(2)1ucsU7L|2e!iH|CrjcXAH=h6y0(?h1 z(0+n$HF1>TTV#tEfsMS?+;Eg}wgfE#H25|RsU>I;ilB%Ip-ty_D~>h|JNQ}#Y+?k( z8-U_eT;Ic<)MoD(ul{d)?lybgr+s7GQ}$%VlMvhVkDsx(P2<1MSa@c}{^Q11d~vRh zx7qDDR+B$Qv+Gz*2P94)!N=WoDI~6-bSRxlS6Be5Tj^;~y-Ht$>Th8$w5Ss;YCsum z=nW|+ZOW;fYDkB}ZlgUOdyey{83jgrT=qS$nK|)1w#X^L1ZVJzC^PuHv}w5;y)lMR z1+t+uvB+mmKCgLexQV?zp}fcn(xRx0H2$M@p*o!qn`<0Isj~=qP!NH&7n?nw{F~zj z(FzKkNmE~YDX=J?*B78bcuFK+)X0XqhBv5aXhnPtP|2tiAm0lZib38g6|@c2BswP4 znYYx^ib1((h$n1oso%n69TQc@%UY#Sh7NT?UDpZ~e7o;@GCi~K#@Iq;HZ{h~heE;2 z!6@xbB^RcqrxvEv*@a|EO;4qg>f+lWj&y?28Vfk;S~S)SC`BQGI%ch#GimC$VLRcP zt`AXTm4$Mz)mYuREx!g&*nVrQwA9#w)mVzuT+mSNY>nkBMKu<5Avbj-*RfHiq5`#= zimcjFN5-reI(59Y$}q>3f|gsO&J4EL%!F&nG!?)PSRgT*H*_)th6vko!gezx+Rl@1 z2CyI_{S56S%n|C%*;QS&&jiX_8g*VZ3zeclU9(0Rudu~c$|P^BP}ddHEMU!`fvc-H zw|3PutTNH^;A_v#`fknRjW)Cciayl;Hbh#%WtF)|1(Ou1OTiX9fT)8VOBNM0T_ff=OPe1%r`62emJR5c~f7s zaA||ODy0>oK_p&-@q6L3eh;y-iT)}&Kf3YZjRUFwp(Jm+KX&h&zRTZ}Ka=l^RVm)Y zesFi>Ug-1C7w7Ifs?y6%H1f;XuO`2o{OZ-O&s3$?o9NixEBEF;pZnta{rDfct5T|o zGwsBeiLWkw-BXn=1NyBr@IV^a8yw%4CTw>2fi%1;?n`HEZt#IL`02I1(Cbxc>T$R1 za2^Ix-@rj{-$8%ykxT5754}x(0Qk-}e)Jih$)DB#Uwn6)y%W&C!{!I=@tM62`H{kf zd!3u<$5{?}{o9v5zVx#nZcab+cWf`;S>8787`vypj6MHLn=^+_bn@J{L(%F`^p8Wa zs`SE^cpwF~J$F36xW23Z?yc%%YVXY-?`f;mH}i*(k=!&7za*dLA2IF*`}N-B|A~b>kydr zF!~K5Gaw;JXsDarb?Ol{54;MW#rkcchY(Sz4^umlZ^RM11KhKm1eYtsNQb(pOI39< zr>fLh-Y7xR66Pvlb%(kdk=+>Cdas}ra;vzwK_-~^6wsEXYIYuA5@y%MtY+bG(bVCB zW#=WaE0q9gPXj8b8fIB5vm{Yf!j5#}VGX-3*oi=x?_`cOPo^fl3I;0$e3>kOfK^oM zeP|8^j^qB$J2~-Re#DJ_hx-16`oBZ397?EjcvIRM-AAVmMxvX(t;&w_>FJ$!s)6Bs z6g{{QZ$M+aaauCrC|xqTFS?404a N-hV9c95-q^_HT*9s;2+| diff --git a/alembic/versions/e99865562d6c_mark_fen_as_a_non_standard_pgn_header.py b/alembic/versions/e99865562d6c_mark_fen_as_a_non_standard_pgn_header.py new file mode 100644 index 0000000..a2e3bcb --- /dev/null +++ b/alembic/versions/e99865562d6c_mark_fen_as_a_non_standard_pgn_header.py @@ -0,0 +1,38 @@ +"""Mark FEN as a non-standard PGN header + +Revision ID: e99865562d6c +Revises: 9741fcc800ae +Create Date: 2025-04-03 06:45:46.210127 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = 'e99865562d6c' +down_revision: Union[str, None] = '9741fcc800ae' +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # Get an ORM session + bind = op.get_bind() + session = sa.orm.Session(bind=bind) + + # Update the metadata item + session.execute(sa.text("UPDATE MetaDataItems SET is_pgn = 0 WHERE name='FEN'")) + session.commit() + + +def downgrade() -> None: + # Get an ORM session + bind = op.get_bind() + session = sa.orm.Session(bind=bind) + + # Update the metadata item + session.execute(sa.text("UPDATE MetaDataItems SET is_pgn = 1 WHERE name='FEN'")) + session.commit() diff --git a/docs/source/cli.rst b/docs/source/cli.rst index c2e2031..5bb0b15 100644 --- a/docs/source/cli.rst +++ b/docs/source/cli.rst @@ -6,6 +6,8 @@ Command Line Reference +--------------------+----------------+------------------------------------------------------------------+ | -h, --help | | Show command line help and exit | +--------------------+----------------+------------------------------------------------------------------+ +| -ve, --version | | Report the application version and exit | ++--------------------+----------------+------------------------------------------------------------------+ | -l, --load | | Load a PGN file into the database | +--------------------+----------------+------------------------------------------------------------------+ | -a, --analyse | | Analyse a game using the specified engine | @@ -40,5 +42,5 @@ Command Line Reference +--------------------+----------------+------------------------------------------------------------------+ | -d, --docx | DOCX file | Path to a Word document to export to | +--------------------+----------------+------------------------------------------------------------------+ -| -v, --verbose | | Write analysis details to the console during analysis | +| -vb, --verbose | | Write analysis details to the console during analysis | +--------------------+----------------+------------------------------------------------------------------+ diff --git a/src/chess_analyser/cli/dispatcher.py b/src/chess_analyser/cli/dispatcher.py index 50d6003..509f6f9 100644 --- a/src/chess_analyser/cli/dispatcher.py +++ b/src/chess_analyser/cli/dispatcher.py @@ -1,11 +1,11 @@ import argparse from ..reporting import tabulate_analysis, tabulate_summary, tabulate_win_chance, \ write_analysis_spreadsheet, write_analysis_document, tabulate_players, \ - tabulate_game_info, tabulate_games, search_metadata + tabulate_game_info, search_metadata from ..analysis.analysis import analyse_game from ..constants import PROGRAM_NAME, PROGRAM_DESCRIPTION, PROGRAM_VERSION, OPT_LOAD, OPT_ANALYSE, \ OPT_RESULTS, OPT_WHITE, OPT_BLACK, OPT_SUMMARY, OPT_WIN_CHANCE, OPT_EXPORT, OPT_PLAYERS, OPT_INFO, \ - OPT_SEARCH, OPT_DELETE, OPT_ENGINE, OPT_PGN, OPT_REFERENCE, OPT_VERBOSE, OPT_XLSX, OPT_DOCX + OPT_SEARCH, OPT_DELETE, OPT_VERSION, OPT_ENGINE, OPT_PGN, OPT_REFERENCE, OPT_VERBOSE, OPT_XLSX, OPT_DOCX from ..pgn import import_pgn, export_pgn from ..management import GAME, ANALYSIS, delete_data @@ -22,6 +22,7 @@ def configure_parser(): ) # Main actions + parser.add_argument("-ve", "--version", action="store_true", help="Report the application version and exit") parser.add_argument("-l", "--load", action="store_true", help="Load a PGN file into the database") parser.add_argument("-a", "--analyse", action="store_true", help="Analyse a game using the specified engine") parser.add_argument("-r", "--results", action="store_true", help="Print detailed analysis results on the console") @@ -43,7 +44,7 @@ def configure_parser(): parser.add_argument("-d", "--docx", nargs=1, help="Path to a Word document to export to") # Flags - parser.add_argument("-v", "--verbose", action="store_true", help="Write analysis details to the console during analysis") + parser.add_argument("-vb", "--verbose", action="store_true", help="Write analysis details to the console during analysis") return parser @@ -72,6 +73,7 @@ def parse_command_line(): OPT_INFO: args.info, OPT_SEARCH: args.search, OPT_DELETE: args.delete, + OPT_VERSION: args.version, # Values OPT_ENGINE: args.engine[0] if args.engine else None, @@ -164,7 +166,9 @@ def dispatch_command_line(options): """ try: - if options[OPT_ANALYSE]: + if options[OPT_VERSION]: + print(f"{PROGRAM_NAME} v{PROGRAM_VERSION}") + elif options[OPT_ANALYSE]: analyse_game(options) elif options[OPT_LOAD]: import_pgn(options) diff --git a/src/chess_analyser/constants/__init__.py b/src/chess_analyser/constants/__init__.py index f2e47f8..a499cc8 100644 --- a/src/chess_analyser/constants/__init__.py +++ b/src/chess_analyser/constants/__init__.py @@ -1,7 +1,7 @@ # Version Information PROGRAM_NAME = "Chess Analyser" PROGRAM_DESCRIPTION = "Game analysis using UCI engines" -PROGRAM_VERSION = "1.4.1" +PROGRAM_VERSION = "1.5.0" # Members of the analysis options dictionary OPT_LOAD = "load" @@ -16,6 +16,7 @@ OPT_INFO = "info" OPT_SEARCH = "search" OPT_DELETE = "delete" +OPT_VERSION = "version" OPT_ENGINE = "engine" OPT_PGN = "pgn" diff --git a/src/chess_analyser/pgn/pgn_export.py b/src/chess_analyser/pgn/pgn_export.py index 68f48aa..313e36a 100644 --- a/src/chess_analyser/pgn/pgn_export.py +++ b/src/chess_analyser/pgn/pgn_export.py @@ -50,7 +50,7 @@ def export_pgn(options): for header in headers: file.write(f"[{header[0]} \"{header[1]}\"]\n") - file.write("\n\n") + file.write("\n") # The first evaluation is for the position before white's first move, and is written at the # head of the move list