From 76481bcf37be6c571a5e17465876c559f890447a Mon Sep 17 00:00:00 2001 From: mkdryden Date: Tue, 16 Jun 2020 03:48:39 -0400 Subject: [PATCH] Add title history plot (#1) * stats.py: Add title history plot * Add title history plot to documentation * Update CHANGELOG.rst * stats.py: titles: fix end timezone issue Co-authored-by: Michael DM Dryden --- CHANGELOG.rst | 1 + README.rst | 11 ++++- examples/titles.png | Bin 0 -> 17238 bytes telegram_stats_bot/stats.py | 84 +++++++++++++++++++++++++++++++++++- 4 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 examples/titles.png diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 807e657..1dab008 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -13,6 +13,7 @@ and this project adheres to `Semantic Versioning CNGgH|5`wfeiqhSUN`rv3 zpSFSWSUrx;9+0Pf)n_YRWap1?n3Wyk!4QowIMIcL(Qi$175DDTGAG&)Xpk7|a) zvWg_xkKYI<4S!O~pFNo`qpRXLaN~QZ4xbd;)w1oTZVJj)>fKiL z+C5#Ag+tOS?;jA5QhY}{Xjw|)o2VjOp!3VN3Q6-;XY5Rm;fKkt>b0k;I#oq)oq7~4 zaRs|38N;_|TYYih^C>P}zML>WZ@;>}-e8_vXJ2U3m8O1CUjFixD`7dgxn2GJrvj=H z5))a})zwc52&~3AlM)kKb|fn;ZFoKi3hFAb8_2V4W3d}4*9!^?qNSl}8*&?Y&7M{2 z6sB?CvF(q~(9mF$_gJbsk#Aae=*Vxs?YDKXu~Bt)&OJ(czSUWBXQiWfu3*4rV?5HP zCYau1cVp6ZXSHXxOVglhZEnEz`!}PqrFwP>y#s8NB-C)zJbuAKrbHTm`HtB2EvX_>Y9>>QoFs5f_c9RGVJ})j79UmKeRbDP>82{me z+{X_eEJw<{JQhDvsjI0awMcF$4h;=?e9f*|sl+8~^*u|IiG5(zq?DBNUS3`v;}M!; zi#HxeM7Z`l>*(m@*$oIvtahqiR8;J|g-4X=aL7mLk*@`Y+-7#hEdbb?)BH}C9Ko!3fx^;-mB~z zo{}W6Gw*KUg%{x83Bf0Z3q|d>va*_)nz|$_d)p@?FHen5(Dss^-qQ??bX_jZN=dFr z1^dFQv)!-5S;xo6Q{TST($sf!zWfRMUB9U_*xQkN)G;kSJ33V2rVvI*M6_c9 zuhl8{+@P8CfE{ZQ_U_Sho6anmCoEJ`#G&Ou5ML$|_w)Q;mVf2j4`K`0-YxOuA>eFi^TC}8Vt`^va){Gt$oq7xV6hOwV zH(aVsrRyl&JB!D9D+dj6ejy@ z*;cwnIYl)(I$HVweFbC$8vokb(Z$8ZE|4<;x`!Q4?LB+(?Q4r3c8k0s_#Of+w8yH9 zLqkhE8tJaZHT2yIZfIx_5Enn{(z-ZTIFea7;(fJn&?yjN!h7Wf+X4MrNJH0sav^Oq1=({a7haiR;bc^o!*)l;%NRqy}>#ue4FP=Pk^5VsdSFT?#(7Aeb+)-E! z(l9OU)XU`LXU@%jemHjhdGeC+D%siD{RMWhl$<)O@=hf~#cTaGtAPgF#*OaHNz1pD zIStA^2e)vjrLfU@`k@fd+l&mw_WQn{Zr!@&J7;HSXKio)r0O$4v42Xuw@%^E^;oWo zZKt{3Y}pnmOlfzP0k^!zM6`v=RBHmc2EJhqw$8;>)%m?!a%Y{^GW>Rzz1pj$e3V36 zRW%&8r?abt$ks7PR^CZ#l_vZ*`BPP?TzK*@(dy8;kLt)q;?lW zW@cwQ&Qj_9Hh%?2abJTP6~r^o)2Dnq!g3!!eyne3Q1$jM_sJ+O);WIscv^b8shwYG{JEmCPA-@BA>tLLG^F6b~dq%p);Xdb`Ph?+@5+7l9r#ZE*Pr>6;j~|$Nf$x z9L3Y<&GOhp2asL}kPM|vez;MRSx2Z@K3_b$GJJEv3hi8zPu*5V88KQR5^KHRsSX(G zB%*7U+dj2m5YbmYtCie?8R~1zS(>@la(LQt{NY1liLI}>VM!rUyIS|}-#5zqtqzIB5AEwCR-d+>lz&wV_Cxo5xO=4V3a zicwyqUQS=@d+N@ee_6HllE>k+PtK+H5g`Mm?z!_tlMF+i%T1f(+&-yA&bKSJSbV1g z(R$h_Nu0{(vX_J@1732(1zWo zDf`XFG9~AP3_tJZIDblaBUo(y5_Dnv@(uIoR9O0B(e zavCis+~3@^7EcQ{WiN#iRE~Wbf+E{UdrUG*uwa3h+Ic+lU>Z*Pt5=uY+zL0hw#;(- zObZ9{t-DUWOiKFwq7Ot+YS~Wc31YDCdFqf8* zq2}pX>a(@EIxFC_>nR^rGkV$9HlutgBFhq*dl+j6zZvzpD0V!ar{t%gtC>GNJ8uN7 zA>z|=E%h~p`D45TZuBMW#`his21Z0irfhF}VjyAiq0*{pYNo`+9qsDrIq)?+D(Y2K z6!qLdp$d2T_rwPe9+>9#xeU8cqN%yFx#}eP^oMA44GSTyOKhur*VblIm=y9!kK*RP z`rbc4qQ|UWYkd}{PM&NNs@PD{a~pDnURc@r0vim?yCTj4rvh0=?n?)r)p>MuDbC+$ zs`EzI%8HA~Q)PfqX)j-%)pz(rPd(y3NiVVceKhU$>xd!mj72)Yq)*+3Q%mNH6*To+ z)oWLgsAqc-<;=sSpT()qR&yq6Lfgbti-XrmGvG*d+>+5HJ z{%oZETBAre)7MLvD{|1ju>1AZ6Y@}rJ4)S`S0<$}+T5kzZt36nj3<9ZPfxGb6(>r6 z?=x05znJyMMr9~XNB+)yl5=WewsXYv>GqBF`Ju2R*m{hXo!y-Fzo69Y>q2~WBHt-l z6nU|HQDm-p_l8?9QTBWQ+w;VZy*7G~I#< zJa77FF|pwqHj?@JT}bty&XX45BW?GwrRGM52;A5eRaJFOO)51dB#{n9^HE1gt3NhG zJ~?^p-ccST>UXrtFtNap18DK#O{uJ&^r)!1jSB!8+aMag=n)`@+=oHx*oo?gUSg|I z23_6U(km(qpjtamHg~CO>b-pY_%~>bC&k3BzJC4MN%-igQ>U(|t4F{mw}?zuR{8=) zV~uY~K@s0Tfl?qPXS+#=L^6tmu3fu^rW0WGq$flOGxkZ0_{iuVk$SOkD$*>kt7CKh z4lTDqxo$%w_qxLmlguykz2URttK3{wvFl%3OBTx0XJ)J=HpapeILQ%~JLsz1F*xwT{{>h`g6X9z zwkphnyu7?Fqd`I!!=P8lWFACVKJskH7}=^+%S5N3PkC|VN!*nvv4%gTj}*bOj#=`b=jFf6yMkRiylxMckDj6eHGG%hlq;o0~OkY|@XC z20$HFQ&)f4+1dGg=2cqSm2>C(2?+^JW0FxgZw2FOjFeBg_xCDB>*@BFp;}zXornL9 zJ8SzbE}9pTK{^>G_@^TyBIHFWN=rRAmV8I_^YZgki;A>K1CCA6;vYDWZ&Za3iN=2H zm~7a}0%mtX)bW$=^{>4N!^8SO4NON{JUe(T0wJftrmtzu?I_Oq!|qqjx45FIGO5>_ zgnypc3vByXLTZkc3}x2WU;J28vsFk&LSi-7pARj1HN@-Ny8}A;))B;2t$0+r&&ede zGd+yhcgFP51t*lL_`~Y z#xa3;$ph-@*z!haTU)~J?(QR-eZCj4n2BI$|NhhQ@+vAJ*4EZAgh7VoHHH^O)hqHbd0-*Mnp%a zK6ygvUN(GsaszTW z;+$cno=C-f;13Lykp#}@$A~1Qrw?Q0jN@|~+;SRDVaR%ihH6=zCkZ;7RuT)1(Jvl2 zuJV{VP@S?Ws?`LkR7Cp;{Nc;8waHfVK?#3$H>FFO70M(=1p{-NU#Kcx!Ju%@pGTn` z`d=5UCR##=iq)s5r;T1yAS`}+k@fEhJ$Pd)OI0?Ch>&n!`R3tN@(BnWO!wA8MHao- z^(nWCt*6gCW=^7To;ec=VgUB-Umy7C13Ec^*=2yhgqGa!2Vf?jSZpYYdAaDTV z*xn$*^Ce)uM+3QJ3ZEM6r+@srIPbZ^u&sNIYkIt7^aSqB7w+nA@lMmGhmSLDfQ5cPX0#rKKKp4vr zxkG5DBdB}#_C{I3jp(DeWib{(p+?!YwR-d#C@D8Lw}bz_{dG}Sa~jn>r}OI1iM?)oo+)QWA-7p-jy6jkjwU1u8?o!vjZ$< zEZ18tqFV&=ng1_5O{*3J^`O4C_L8);A1xhSzDW(Ke0%7z^DB`R+h;4bh8C&|Es=Xy z&^pn0X_Q2si=92(h2^)R=g*l8ZvsUZ6B`SI{jE$RN5@MjUj=C^G7aB4WVHGMNXEL<+Rt zNBOa_ux=>+o9x*Gy+=B|eRgIIR)N8@*;pEfnfRfl63q5!2jsz3lDm*&M9r(jXUHKT zp|?l%SX)_z_S{@6IsGi7tW3{fqh3=c6Awu|f(8_y+AHQdi|~JFYTeJPLZr68$#QDv zux5B5Otjb!xqbIg*jE?Pmd(E+(6^JN%gti9;r7iBL8MeZ6wyyN00y zmrNY3btkZG;PUSqQ;#@kNsb<+k04!$d|x`WT_IGevCow7 z3sO!r zY}ty!<42DvHI@Y;zB@~;-XKY)ob;Jdny{%nf+l<~l$?!rUbFq7@U&4La3j92_|QSx z;p+$sJ(WpzeME_QKk;BL+c&HY;7kNbZq^Ui5{);m)$(%^Vcaq5g0raf{)t zO1$@G>i;-d)2fl|Rf2B;j4&Eo4wt%z1rOzYDc_nW@{mA$r%<*#stp)cvz=F}$zIb@ z6`_!9-9Q)Yy!%iS`*IWroX){Pj({qPmBj;p#UT8=you0!0JR4BNW-n3L$8&cNj()| z@?3LqVWI8S$5Y4L@;TVE7}mvW=yH;i*&uCGv$NYOUT0;g>@mQhL-v|xW-q^tj_wQu z`1|KwpVP@NDA=rlq;&z&Vd(mR9jbAFP~iFwkLpgo26D#bjiM`z(293{9--^RU6{s1 z0{`<29T%4o7Z>My8e%Hnre|hjGQLM*eei`+tROJ22vadSRq-4<&PX42_J!Z=7cbgB z?_AmM&@=ouvhMV{cCkz9Ps}mGQ-&tFdD4#agtZ!_eEH$ql!19nB4Z*XRjsLu(a@)1 zO0REhR8vq0EFI2XX#QT$p7jdm3>a&GO>T$#VRTZ0y+H@Ms8E>9X7fKbj8RW@iQ7CR z4m^8qe&)^l2S5~}P|DvQAERYul?r1p5Xv0sU8f=&1SZ5W-^eh}f2Nh;;ZX9;JmV)? zSvh4nBgAcCm{a}~2ggcCS9f=?jWR6Ic}6e(S2|GUh@jXRUU?`azM*@IL_@OKIw+LF zB(OFc2O&7{mp|bnhQ;X2CKs`|pIuW;?Nv$1)t#N4oIYFNNl-L-<;s=Ej~^#}{b~yv zT@Rz#t5+A?2CoG?;Wl7Uqu&cx0s@=se{#k$si~<(uMZBfRGRjdHeOMU^)`C?R^evnwhETe%qUWFvQm~2oRnD^w|^N*S)L9GQ@9| zP=?r|>VIK~Wo2b`N`U>odKGtK8wHghN9nn=oi)lhgz$9i4S2V%H5-oqXF!~B42y?T zn(_ff4*6hqn0xjiQS>MjyhnJLBEyqSLP8=fH8s?T8hEAp`g&UD_@`oS*5maNI;A(R z$=To_jpEq)!9($`-ruN}zsWcIuLIgbZ(*~~f24d7zQeF#OxAa3GyWsxOY8jXJcIiO z3?>je-JD&U{I zCa>-By+DcrQZuBaUJADSAhf1A&35JC$5Wc~G4~qHa+i9j5GK(@A!?*?-yVY)*G`LS zP(1h2HQwDhQPH=VEG1q9^1@W>sA^R>qu0u1G-}Lq@mAGk5#&9#emMpXR^@nip6n=h zX&kXr(zvmN!dn3RD(J|Mj;oBA?=?`@7$)lxgqjg;u6K%!pKAhE{a8_P{sm?F!@;hc zj8c!mWjRrC5g4#QSIl6Y9u1Mwfbp9;eLun^y#F*V!qx~)6rkh9Z|Zp0{fK? z&uA=wgE+FG`+G3gr&%|so~6#sxYan6k~ILD=lk%1fq~W7k?nIZh&_jbX-4f&Tt!gC zg&?=kp(u*y!04CN{x4?0U0OdAIOqS7<(QkR7EXOAp^ARC@m&CduJAz({7N7Xd&Tfs zC<8@?kP~B9!^3NlcTP$1U#-k#`H1a}rE8-kDg`>P(_XzI=pF9sqfxU1jQ;=z1fI`7 z@gQIE0Li@rJI2#eTV6PtsGD9l`hu*0_fdsdPCHi^SJ^ zL-x^L@sN-l=AiHC?oOVVFc&!*{M?56=+RDp5;|1y0#!i1opJZu0k7@F8jtChk!UXh zl;4h4Pds?qs03wF=_f76FnxySzUb&Qve0Rt}o{-j7dMJ z;f%Dj?fv;Spyy*30^wUs%tA8Q4MN(B>{(kvJlfz8$Y-S)JUqn$8LXJmPNsi#x z$X9IbDbx9L=Um{UWl4$&g4(#{S2-Sp~H3-R()K*}GKwtw0Vj z$%9}}G66IOD=_+0`&LEv+fW^w+QHd*TX*J<{#VR=c0i;vj~} z!2A0WKpl}|{n|UbdWwy0$)V{E6E4Cd@lA*qk*mD7(7W&q&~U`Gu2D@@RaG(QLM)Wm zIppc->7lB&wRo@Pwo)DdR@Wbbn59y9JC!4VtQHjz+%zT$#pb_$1+raJ?tL&8N~8Op z=lJ>kwM?Kp6!*i!5_Euy)HMiG?K!W%NCR~z;vXAPZ?<5zTkhSVSGaQV;sanaR$67r z?v|f{Iq)Hq^YMr4hu_6N@4{9YBs+|Km12+=-;#Kw*z8QYrQ5OTXTg# zI;8+#_44IQyh1Gy1dX7l=Tnc6vpInzg5PtG3S{TqY50MfUenmnj zh~g3&8k(>qudTJzpV{G2T_7~>@uQnw^^bbcT7$vv6`$SZ_^y8zm;ZzgJ0>^RzP9yL z?7GUM>NyCOWjq=OAsRpOuBjr3Mb1CXO)$m(;EK_J`~{r&I6VBt=H{laS6Fy>M0ogN z9zl4nJ9qYDOzdwEL5!fY2f^jP@+#NZH&s_xR$e71p9AnPy7)UgyG^4P(8(@iwG`T&(U?lj_81tjt4A=tu+>uWHuG#j6~^@I$h%)!Ay-#I!V`%W^S@3K1s6+5xz+vD6e zE-ot^d_eI}2Sb6tzPQj~B=ch+)d5=+E~*3B2|!X^Lu2LvdnUo&bpdTxYAedMI_c>2 zi`;$^!XS}$BHokNFdkkBol6;ggr4#>ft{w2ZKc{8SQu4Q&~9dKmu?7arpZJ1X379^qeljCRqzCSPR_H9QKo$X&V)8S=j7 z1R-+SYR^SC+FuhFDv)%U>}vO7O`jC|JvI2Km|==(Ew2bij$8fgDT>Yog_wzhss! zaPHhgyIZIB!Q=p9sqZU(q3Yx!ekj;X^$^JSM4^SZC#WRdJ!#_o^vypvH!};1bTG7# z2FQXX2(+v#*48s3lN_9!U7&`tPQy*BL7krmf%4vKGPnnngiEad!?n`;dJMDRPdiDd zzDL!{{Y2F!fD5=?*ayDMD=CF!* z!p-@j^Dv_jd0mDwqk)Y<@;ur2qa{nOIim^n|KeqTDPH>YV`&v*6JL5bZLT-*ax|Eqvw#q!YQop8}$A!mp>^to6K|VKCQp zIK4*@q#E!MQ<|2BKIiiLBmZ)@D1-r3^G}qCYrl6{S(#3bsk~MV$V<6o=ti4xXX{`YC>a_uH`EE$}8V)7O9tPfZ6P!5CfPW z)d#C27xWV&CVSAh90>na5RR3p^lu~#d#&qv0h}Vk_Mhu$PZ0Pu{}qM4bvCmEH4TAW zsel>?j)jOHLh~MLg6{Ns*#g>4QKCLvIV^gi+gM6rWp~0`Q8| zRL~5(Wrr#HBDvZUUdU3!@?nJ2iyo9cGGZ=^NS1$YAiz7Y7Cr4b=K%W-@>BLBtxSXW=)UL8c2@3nQkXvn^7 zd#Qn$5gIJhA>g=}zOb?I{FL%X-t5qgeD_D?RQdMtNP|qF;Ty*i(bU5FS}BAm{OW$m zbfH!Rshtj~X^=70G&G(JL#(5m+#er^=HOBDN1}sGGdOka=MqLmZFwTSkBkY-i}p)1V@ z{lYL2kkVz_TCqfmc(<=7@K077tB=3zImyQ6Rr(BcQ`S@H@)gGU9=Wq;%Jj!NeR_uE0Z1z-;-UMKd zbWlh)R&o^nnEu)l_Wx$H67H~J;7;1(cUMm6d2fs}Gg86r6ps>8^ECVwE<_auOZ90b z)PYMA5L1eo7i3T)E59LJ{O=SN80f;KHpUJ^&!6!-z|h+E;`}NqL7}(;y29ebhg-+MSmaZ!38xLfK_my9Bx24AJM{y9wNm%_ zMX}?@5&V1uR@v|n1tq0%$`!c#>Mv|Z5mx$=LlX)Ok1gikr*grY;kWQi2mb(`-d}|G z{9X5ZJq6hvU<;7L_f@V|vQlHs(H0*jUB@%q-itWbc50= z8bA3$u)t*T!(m{kBqrkykREN_Ss%#?4W&Ti6qUh=tL}BS!>6Fnz;uz*iL7Dsa*EI%9MJsa68;Q^zZmZq z{WDTi<-r{XGU1BDELfc3GzQ3`V9`|9)=mYdDP}E*PN<$=$z7a*UfA&rIASTZA;c>c ztCfU(e+P!{*V5i!4{rQ@LtmL$GwxKhZ>?zj$<;iw21;!XO7MkSf!7mTe+&yCB@-ej;!3>!@{#@uxoGUz{aMyubwn4k8WhhpqJn zZulNydV%Zr-+>7Jfib=D3v(@MLrvg>NJNaFda>2k`PJ}$W+w;gR|* z1{y#+)u{EWssVESTxL@E$+ zI^Ot;T|@>gM+lF!WhFVqKOxk80e@<~=SA8EW%ow*A$}sg+Qb zu%8tAHqt>)Le27J^P>AMmvt+9WO@^3zQ0rBNVzT)ZRSeGV&9&jBqv;)nQ;NUq*x0lNZo7RQMKo*+P zt+8;G89+ZTcgGEO&pMQEB!jNBGXP8^D&514TfqqtI5tAs>(=s2qWEi01FO8dyF2&^ zNz6pxMi8EpGS-#NG^KQjU%nUv=XX*{YD7vyPw#bD*dgH1PM$b%9<22^Tg0TKr+_F3 z<98Sqrx$Tz9UDcTqf(A&n*H8kiqe~Zmr4nHpFMi?{Mh;6?-;k;?F|YE0MNkfT)9Bf zE4P1v)}Oh9AGaC~-27+}^m8*W1zRoPE{Exv^ehcfUauZ~Ztn|#{QyD-kLe8+< zJ<|W%#c!E^JH7`qq{Y()`@(o3bujpCrG00l*oD_rlDP}he zV)x9z$Zo;zA|vKX-~$t zoS77i#?aqcrKydRM(MR>m|g^xI`|oVwy!OxNbRI9dE|)F{FlT^(`P;%{7UgH7T%L$Bd0M-krj%=EH5fe%SbV+1{gC+Dymqxa>dS^ zLlcw+4<{;7C8ZA=LP{N;t6iE+FgG{5h(6uThO@QHsFAoSfYJMg6D1YiEfEa5gN?v^ z*YYcMY&W}=n|MQ$HwS#zH!|V?$>Ag50GP*Dq-9O=!v-0@_GEc_dV?-BF{_y5jZRgS z=nBvl+1wI3I!$-`Ciz;Y*_O9s+2Z}0&2#hv9HnrZUa=br4Y`Cv?>>&66Ks)Kk1Jox z&#L1ghI77_pa4ReT>+4Vf}-#1boBIHUp@v3STrAn207iDAiHbF==sgBeB~uK3|Qyb zH8NVuy|(y4{D4!6L*83+SVjHYr+4xOvo3IZn75h+Ug`#0{XL*E@wx{-+!wwo>iPY1 zKz&nF1S^!o)E6&I{#c;Mq>bgtSuh5YQ7b4Ybf9^1&_I>{;Ka5jbV5$fCd|?Ft~AU> zJf;m?I$7{ylo^53t7|Rp1?$YsKF{k!*FjWD%glVjio$0&UKn1{Yh{_!3{lf;%R6$D zRTB4U6YSGxZ~U0cBw8{ux1hwMyhnav;VddMz);635AQ>bbx^KwC08!A$B8(j2V5|7 z15FA}R@60%Svq~}I)}`p)7$siv?ZS1&$&s|e~0G6>jACw2TWm)1kd72%gH%veD2=8 zqu)5VUpkh6_RU%HD6@NybED+L+T8coY+at*{OVbTMZWF&MiB|k_y+lM*)Y!@CP{l}AW-V{>DU8EAL-NRmm(O$R6Vu3mH@hRl zEGZ==A|=)0fx&2>TslBaPyf-9-&{gSQZiWIKz-mw8)4muaW?YYiWV0aH>%0JecHu5 z$X~eRIpC#zap?aSz#sq6eYuHiQIy zHR&3}DyQ(-Bz0JUCd(78sHmir&@)RzM>o2=tFP@fu6%YE;pXO^TJ=E9Zog?5sja*- z&ppk{`~K@!jy6j*kHspVr#}3&>Km)<`pg?PG3S2&&DhH7;P=_{s{=JP2eP%kMs7X& zej=i8VQwzFyqs(O)6R1ipJ=}&RoCqX;*|xpm4sfJS82+X3=9n4Hax#BEOfNB`Bi=X zG&4i!>nQxN>T~TzQA2|QDH)me)vK~89c?{50m)XDG1aZDrSG4-DpWRJ#ygOD=R;FZQ!|v?tjC}W$q@<+$c0(N2M4UmT zJ7!~zIaEn~4V*{&_u-hEn}d Tuple[None, BytesIO]: + """ + Make a plot of group titles history over time + :param start: Start timestamp (e.g. 2019, 2019-01, 2019-01-01, "2019-01-01 14:21") + :param end: End timestamp (e.g. 2019, 2019-01, 2019-01-01, "2019-01-01 14:21") + """ + query_conditions = [] + sql_dict = {} + + if start: + sql_dict['start_dt'] = pd.to_datetime(start) + query_conditions.append("date >= %(start_dt)s") + + if end: + sql_dict['end_dt'] = pd.to_datetime(end) + query_conditions.append("date < %(end_dt)s") + + query_where = "" + if query_conditions: + query_where = f"AND {' AND '.join(query_conditions)}" + + query = f""" + SELECT date, new_chat_title + FROM messages_utc + WHERE type = 'new_chat_title' {query_where} + ORDER BY date; + """ + + with self.engine.connect() as con: + df = pd.read_sql_query(query, con, params=sql_dict) + + df['idx'] = np.arange(len(df)) + df['diff'] = df['date'].diff(-1) + df['end'] = df['date'] - df['diff'] + + if end: + last = pd.Timestamp(sql_dict['end_dt'], tz=self.tz).tz_convert('utc') + else: + last = pd.Timestamp(datetime.now(), tz='utc') + + df_end = df['end'] + df_end.iloc[-1] = last + df.loc[:, 'end'] = df_end + + fig = Figure(constrained_layout=True, figsize=(12, 0.15 * len(df))) + ax = fig.subplots() + + x = df.iloc[:-1].end + y = df.iloc[:-1].idx + .5 + + ax.scatter(x, y, zorder=4, color=sns.color_palette()[1]) + + titles = list(zip(df.date.apply(date2num), + df.end.apply(date2num) - df.date.apply(date2num))) + + for n, i in enumerate(titles): + ax.broken_barh([i], (n, 1)) + ax.annotate(df.new_chat_title[n], xy=(i[0] + i[1], n), xycoords='data', + xytext=(10, 0), textcoords='offset points', + horizontalalignment='left', verticalalignment='bottom') + + ax.margins(0.2) + ax.set_ylabel("") + ax.set_ylim(-1, (df.idx.max() + 1)) + ax.set_xlim(titles[0][0] - 1, None) + ax.set_xlabel("") + ax.set_title("Chat Title History") + ax.grid(False, which='both', axis='y') + ax.tick_params(axis='y', which='both', labelleft=False, left=False) + sns.despine(fig=fig, left=True) + + bio = BytesIO() + bio.name = 'plot.png' + fig.savefig(bio, dpi=200) + bio.seek(0) + + return None, bio + def get_user_correlation(self, start: str = None, end: str = None, agg: bool = True, c_type: str = None, n: int = 5, thresh: float = 0.05, autouser=None, **kwargs) -> Tuple[str, None]: """