From fff882894faabf548f3aa450c4c1992b81b8dc8e Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Wed, 29 Jun 2022 22:41:57 +0200 Subject: [PATCH 01/10] add sphinx project --- docs/.gitignore | 3 + docs/Makefile | 20 ++++ docs/_latex/hsastyle.sty | 108 +++++++++++++++++++ docs/_latex/logos/hsa_informatik_logo_lq.pdf | Bin 0 -> 46230 bytes docs/_latex/logos/hsa_logo_horizontal.pdf | Bin 0 -> 14235 bytes docs/_latex/logos/hsa_logo_only.pdf | Bin 0 -> 4452 bytes docs/conf.py | 92 ++++++++++++++++ docs/index.rst | 9 ++ docs/requirements.txt | 4 + docs/src/0_intro.rst | 4 + docs/tox.ini | 20 ++++ 11 files changed, 260 insertions(+) create mode 100644 docs/.gitignore create mode 100644 docs/Makefile create mode 100644 docs/_latex/hsastyle.sty create mode 100755 docs/_latex/logos/hsa_informatik_logo_lq.pdf create mode 100755 docs/_latex/logos/hsa_logo_horizontal.pdf create mode 100755 docs/_latex/logos/hsa_logo_only.pdf create mode 100644 docs/conf.py create mode 100644 docs/index.rst create mode 100644 docs/requirements.txt create mode 100644 docs/src/0_intro.rst create mode 100644 docs/tox.ini diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..4da8e6b --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,3 @@ +/.tox +/build +/venv diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..ed88099 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/_latex/hsastyle.sty b/docs/_latex/hsastyle.sty new file mode 100644 index 0000000..b8adc0e --- /dev/null +++ b/docs/_latex/hsastyle.sty @@ -0,0 +1,108 @@ +\usepackage[absolute]{textpos} +\usepackage{setspace} + +\newcommand{\hsamaketitle}{% + \let\sphinxrestorepageanchorsetting\relax + \ifHy@pageanchor\def\sphinxrestorepageanchorsetting{\Hy@pageanchortrue}\fi + \hypersetup{pdfauthor={\@author}, + pdftitle={\@title}, + pdfsubject={\subtitle}, + pdfkeywords={Forschung, Entwicklung, Informatik}, + } + \hypersetup{pageanchor=false}% avoid duplicate destination warnings + \begin{titlepage} + % Deckblatt - Hochschule Augsburg + \thispagestyle{empty}\null + % Logo - Hochschule Augsburg - Informatik + \begin{textblock}{10}(8.0,1.1) + \begin{figure}[h] + \centering + \includegraphics[width=0.45\textwidth]{hsa_informatik_logo_lq.pdf} + \end{figure} + + \end{textblock} + + % Text unter Logo + \begin{textblock}{15}(12.43,2.4) + \LARGE + \textsf{ + \textbf{\textcolor[rgb]{1,0.41,0.13}{\\ + \begin{flushleft} + Fakultät für\\ + Informatik\\ + \end{flushleft} + } + } + } + \end{textblock} + + % Textbox links - Informationen + \begin{textblock}{15}(2,2) + %\LARGE + \begin{flushleft} + \begin{spacing} {1.2} + \huge + \textbf{\@title} + \vspace{30pt} + \textcolor[rgb]{1,0.41,0.13}{\\ + \textbf{\subtitle}}\\ + \vspace{60pt} + \LARGE + Studienrichtung\\ + \hscourse\\ + \vspace{30pt} + \@author\\ + \vspace{60pt} + \LARGE + Prüfer: \examiner\\ + \vspace{10pt} + Abgabedatum: \deadline\\ + \end{spacing} + \end{flushleft} + + \end{textblock} + + + + % Textbox rechts - Hochschule + \begin{textblock}{5}(12.45,8.0) + \textcolor[rgb]{1,0,0}{\\ + \footnotesize + \begin{flushleft} + \begin{spacing} {1.3} + Hochschule f\"ur angewandte\\ + Wissenschaften Augsburg\\ + \vspace{4pt} + An der Hochschule 1\\ + D-86161 Augsburg\\ + \vspace{4pt} + Telefon +49 821 55 86-0\\ + Fax +49 821 55 86-3222\\ + www.hs-augsburg.de\\ + info(at)hs-augsburg-de + \end{spacing} + \end{flushleft} + } + \end{textblock} + + + % Textbox rechts mitte - Fakultät + \begin{textblock}{5}(12.45,11.4) + \footnotesize + \begin{flushleft} + \begin{spacing} {1.3} + Fakult\"at f\"ur Informatik\\ + Telefon +49 821 55 86-3450\\ + Fax \hspace{10pt} +49 821 55 86-3499\\ + \end{spacing} + \end{flushleft} + \end{textblock} + \end{titlepage}% + \setcounter{footnote}{0}% + \let\thanks\relax\let\maketitle\relax + %\gdef\@thanks{}\gdef\@author{}\gdef\@title{} + \clearpage + \ifdefined\sphinxbackoftitlepage\sphinxbackoftitlepage\fi + \if@openright\cleardoublepage\else\clearpage\fi + \sphinxrestorepageanchorsetting +} diff --git a/docs/_latex/logos/hsa_informatik_logo_lq.pdf b/docs/_latex/logos/hsa_informatik_logo_lq.pdf new file mode 100755 index 0000000000000000000000000000000000000000..9e8d2814745d39d240b9bf547b4ec89b6b209f4a GIT binary patch literal 46230 zcmcG!WmH^E)HT?_oe&@dCm~pn#@z|-?hxGFJp>4Z;2PZB-DwE!-nd(Ecbl6$^RD^6 znKf(8pSgdUrf=P@2n}9_O zoDHn)%)kl;W+qN#%)rk|U>O5jGinoCdU0VIGO)6ofT@b_8&+f@Ii0E^hU*gBIjfu${sowUhV{yt8Z z?0+5i_h0{yalrZm$ixYlUqjx|(!|Ia_)F3T*aI6G+uuj>^Me%} z?TnO7oVCG#4ZtcU?#}<+ApGBl$bTP_f9D3vniyLc2-~@9149|fxY!xV*jO2L$$+)m zIs>yhk+J@LCRp6j&c*(J4EOH~SQ)J1XkhDP|95pp9$*n=@MjZO3nLRHabe)ODh7s5 zz%Boo@V^~6kum5mIGuvGyzi`F@&d|4g1^a)eyCH%ZF>>Iibpv<8G>yQ znVPF2^sKb0+T&TO{a`K;>Qt)u1`F09qn2Bx(VXHJ1U+`VFXNAnMcpjQVil~~*V3=E zQW+HOMTer#3PCH=81iUYA;|Xgxo9V7uyQ}uTs0yta3=K6m`I)7J}Lh@?*CcW|D62a z6ZoG^{d2Pa^NhgCE{4v3o$lXBfz>UHfxWS_bAcsHEX>TE$ynG~0FztWIV#&57@7QE zmIMo1I6EnrIEvWW*xT9ubpuYYBycj0_I7`5MP_PX?PLP}e>Wd13kN6r|8Bs;Wn^!a znPraCb|2M*%2>fS%ft)l}Fqf)Zc* z<)YZ=s{1Lck*iOHO^*);WSFf?SIv&wJVs@4uy($8Eb(x_LQZzQZ^yj{Q(uxcsb0KB z`J}Z8LI1bwtMQ-8U<~fPsGoV{N_`*jDG#^X12ZqQp5Dx9gg7(N9H!_4T*7t`teObvNBJ?f_17huP5Z3~e2La%R>FRX|aj;p?5lT_On>RzT*vL{6foTu)%{(hsBXBDcp_1$k35!YjNHI?y;}-}JpBFQMI*hM>2+i> zWA3bE_T*0_k8Kf@NAc(`8F~yZ&L9vO8s(v40%i+!ffIfioixo*tshM+cZYEZcWpQ- zDOJua=W2kp`N1hJ4_{I8&~?SjC~ss&x=rWPN0w7hPQBlz$t~%rYCZDeD)YEn^K7^7~J4(P^gwU zI`kqhlPWTT1A$%z(woIAZ$?7nO_B!B4MuY=aw8OV6y<9S_8|Jr&1>EknlIu-Mlx|8 z2Op2i1}RuhS0kV&`2iUJjjpVUGKKPa`vkdLQ>gg#vr!=ik|Mvb4;>m*_+dFnxomD)jy{umm z$1PUX4O7-TQ!$8of7<%JpS{#wX#X9y$zuE%Uu|5^!A3RRNSK3SgW`X)%gp7J6A<3? zSUvE1lMY2-0z0SkT_!m?d?<`@PRGBM>04ij^F{3J{qQ{=d_LNdXu?77tMqT|7y68L z5cR4*kJu)b35h>S;CI)3-hi?oTeikS+Ka zWi@@JAB0#PzV8?B<%sMkEA=6PKrlb==mv|pcrQ-p&mZ;59%zAMcYi-68Piy_A;dez zBBFJpUg<2e&xkFYu8kAqAUAeE-Ryx`BV)<&8U$hx?ad9BPG8sNETERKy1Trxva_mr z7?u)sXpSkEQBi!!T#uS&qWriq&JN|1#KjC-6jbe@hZ2)Y5t9S)6NxrYgjno;W1ENu z^?m%3x%YM20OiMz+hJ|Wvyl!b>29mzP8bw{Lo=go{ z7JE*ihV9~YsR{D>iT}o2;>l-xEXJdiG(`BRF zVUr{_5pF%dN=`oW2CKzwH@J^NrT^|dgxZ{U(9c$qQu6i6cX`0*?-U~^Gz6mUesFr! zGub?{U<0|w^n=E+!jkZchy$?sUs2NgWPr1OX39`i=1afPNp4Mt>NeS+(YySDIkj>v z{Pg{-%|QX@$}LSJW|9YL#9!ku^Yc-Au{z~|D*tlN0|c_yT-rD-i@m#cpbbT2WAOf9 z%|!+HhS5AUUCW20K4NJk8FlKbqo+l2U~-Zz&QI= zRm5w9MVRL0&~LT3%2P{{CiDC=u8PI{q%g!3@_5-1aey0JJRO|>Zuc%h3bXPRM@;)L zBX=KhNwz1hSW~N!Up zmQ9Re)@KQ|^o$)&-W2ckZ?n?(KQ9UPcqRjKNhR&X(mdHIy+uEkB(t{;Kqv&X1zxb2 zNK*Sn%(}DAl(Y}^6Ey1~C;Ti#QE_jS{&Z;etI&;Cp}*Tz z&c00LLq6+z8XSCp1ZqPeoo)QrQwa&w`D}nS=pvSX_rMO4&FfFiv#lJZnPGVgU**ows=0KQIDO7#-p+OUC)N-{D&tYMS0=}t0i5>$6oLU@L<%$#Ws$ohVEQ_qr)=O`6Ar*qK1@@^Sr=}^ zm?6i&sZNPC$%C;g8Myzj+W4lNM7@pqp1hy_#@kA}JAZum9?R`=1Al5?727_vu3=7~&%gc;Zd(G^I3YG+QoeN|%6I#h+IbNcpkmRL6Aes;t zqEg$JCsMx=_JQxc_dl#<`n$$|Lu;1cTpn|yoQ}I*wt2bLJ3MYHx5JwEU7w%M_ZAi& zy3{(MdqHLB3z|2lV;wh^%jyh=H!NK+IrO{SHERty1e*o zsxL_A5w&JX7s>HT$+d>JBGF<~pOFv~^xDPp@~3Y(^`9XYqv7!RffJ<+%aX70y)f51 zGm!0+;6%J@E6tl1L*EpInIz~-)zgAPdXH|dzlr7!{RxU{ntYvZx)=GXu1jdPuYd28 z@XVD>xOV(@*R6WRHZ{s*asn^*g*IGK1aAW?gYWrdQKTJdEOV*8cQ?|#Uci>s(J+sP zSLM^XGR@HW;4G>J4M_0QxwmdbIl&Oe_(A{Y;&X$YvRL@ixV)TEa?+s-&(m-QHa54I zrS~$rRbQyob9|MJCIp{;XT-h~fM!Gk>X+eL@k$d-|Li~^p-i2jPk$j9~Kqq|~Z*PFJ+I+Rfy~|(sS=Ym= zz#@$Ye!BKd*5Cl0)n~@{NcvIcvslYVHzXy+VXH~7ci1P%6S}g*+}LSw|HE;iazVyR zNH*(pAfz=j5`blJ0y+_w7<)OR1k{AZ~=x+-=3lij}4JYy~=@`02Z5{gdvT=Rk!%^B;0Z=w?CI zq_fQtELJf4S?I5j3@_g`53EO77g5+NRFdro4#`SI=iI9==&M8UCVL83mrU>1p*v}2 z3y<~Z)v>26z0vJ*tqc&`$ZEsD7&HGoUI>R%U0_>d@topO8bOAygdIN=KMjQ zW48~b-Q%`Z@7hNho{O5&+D2h^X?`H6GC9c&H74u>6rq?k&24i9;=9IQrxK>DtU+m6 z>KC*tDuS`6ISI*4#IB&;X{axKfL%@So{ayFJ2oYxzJaSd=;9syt%T#b2H#`S{Q1&_ z`y)5BV7y!BA#MMt3;BbmD8B(K z6A`&kT1r$zy?^u6+F`??thTbB$4;dOFWt99b>MEcW+I}B+Z8Y(4y>WPP(<1@^b&8c z?j&zv!#~$d@+C%3t~DX^EX1@|V}zO4xs(OfaVb6%snzC=~ZH20f@cQ|CMcbFnz**cpP#Pcq{()$6iANk@HPtGJVYpWo>bo&Mo( z+CS*NMquAs{(K*INw=pjRD7DMJMyr^%$5S6b>_obkb+R^wpHO z?~%R|1K)qK%cGDNz=8nqIc{*kHI@_~A;Ln8Sfbmvix?h^k5%s3q)@mG*I<=?BUrxz zKqpIZ~g1lDx7HJIm42PzDGOUPW#4CgEB{CRb2NlHKTxHw8y z-cb{uhiL!Ja7IbgiITC74r0S*wt5d9q-x(*v~fHr58~8l&WtDcen2>j#+4X(p%(+jv6e?R-7gr>rS+yXQ%2}z)KGXoS%uOvU8E8DuyACkkgjCt+-DoxVc?=?4>YuX7TdkO% zPg6!9cHG-}4zxpWZ6zD2J(K@HJQ+h|O*eh7N^yb=n}@%k>4xfVzy~b6c4&Du&Gz|_ zo>Eh~v_iPwIrOIcyxQ8sKwqd_E>>ZBYN_^eUe0t)Hf1GSloJOJ1X6l4q~*3fc;VSQ z7FI0-a4F}?lyuZVW~RRA$UEDR94Ul@9eyHKl4$PXK!6XbDm&fgD-$?+HOf~+{RPc` z#Fh#Y9i&Iy^_D+{BEp3m61OCiu@kV;c}1LVPuaHj&+~*Zk z@92fP42p8#KwoV?PCE(lF`uyz$Xkd}4cs#m73Dn)E0{3kQV zW7*2PLZVT`;ee_)kf#(A1S)?e(`~kJ`SvA>v8L$Qf_?HyucD^(VCzkL7Po3lRuY#` zA?0c6mJR|&t#{KwP_1=aG z3YKzDuD>YX6h@+Q`#ZedUbM}0HCJC;2p8KTQjC7< zsopWJ;NM;wP3A=~y$2Tdd`Jv@j}UQiXe0t~_BV_sEod9%nEcNSilJ(B+H|v6$5*nm zcPfjw33rNlBC1p31^4TYOcg&`R)TivMY`e$ZCX(6w^0C>GFeon+iij?Yug(4^|y19 zj0(NEDV3PXM<{@t-FytI&Pn zDD@Tscq^5P8cQP_>^8lk z-${C?pknHM;J!{CWw$x(0(gyIa#W+@PoA1in7k%@kws zPZP~ZZ@!ZW!MwfXWMtnXhN3RO{c&Df^XF&WD7U9(m%d}Tdvu*HQdf`M)I`XTjW_<) z@GQH4gx$@|Wc2izVvOr_t0{YaV z_-e3o#9AM|z++UT#P0@!mJoR{{Cc#N16s0qb`dAjJR3VEhFAiii@{OddcB1hD;e&Os zOKK0>dwX%3WK1WIm=*(Py231}$wc@3^J)@pc_|~%#!(UmTMEz{Vs?ADJ!}*s;q;0FwwcXMedNJ5J;;d5e(aWb&!pn=W5$`Tid1|)p*my%I$|5yrUV7&cSEYf zQ~XIw^-taVou&Tf3bLN@_v)M3`lr@TLuv`TwbqYL=Q$|&k>;i=#D4NVnv@=M_C!gs zkA;DG`nPbaXsy|q@5GjAkfE&*6SPIlAXq@x#lJT$>*$tYp_Z2U^Fin8f}o-?KJbne~&m2Xc0P_7m=*eyCkI$f&e*pAfFMI2ZFP4&T~o zWIwt7GnYzl{T|+Ps#}Kpz?ZJ`)!M27&a+_`@2qA^x-n=yoy*LT-re_)f$vEu38qyd zcbn?yQ@m$r{QlN^XW05QWk7}77(+`m{sWY|DrHHeuG%}@%Vit17esmr{BHH_!#YaFDFghvM0hH*^2;AV8Bo8X#`-z zhJ9r07dw(mCZ%WT+WiW;0xwm+W_% zG8^R@pe#r`#*}@X)6n3!q2dMeR2RiuTCM%{t!Cs4Ge1?e(`7q;3CQV>Ut=FEL4XVw zl`7Yh<_{iHQ4N>8inboN7gT2PKT*(`sa5=+gf)u-JW2840|#@UdjauT0^9 zkn0`!=fgHf`pLw13*d@tGX3^2PjIiJ5}%4ObJt_Cw^*(`)U=fc%F$QBWvn7R5B!iFRHl8CZ2z6Q7mD2!e{f4v)v+YgzAR;*zvXeuHqT(i^)rCs|3$E- zMlbE^m%B%wsU0^!hy0-uc7+{}+vVKRw zEm==#641U;{j4=(SX&<8u>I2;@x+PhNQQK(`WgMq6Iy#`a}a^~v`@Uj2I!{E)H`h2 z_3Z`a1SQn_RAVO;UQIDk2wZDhKk7Z}ti16D-%i3m+*Kjk(!EZ@x_$0yt!hIT zUPGv!v?fW-caiS6DR6eW+I?A#7rujTP#UCUysIoE9#gN%1JKx!z@ zd}2Si_M;BHSEdNy8EBHE{s>x54Th0LgtN=>xM&Ie#{Y)BjIYY{6UqaSr*LuB^$2g0 zw)gSfoX?kH;(nKT0i28r1Iifvb?x8tPK)?=U7apQRw+5oXbN_ae3x{lZOpaqi9Bqh z+x?a8D9PObZOD0!+?o(b$@x;jQV%LnMG4bcl}Pzf#SY+nuo8aEUE^?UT}AN{d&gd( z-2XLUeYoD8r|cD{)LXw@^%zuDUO~v8AC=pwU(t=f$=O;Fa?F45fo+l-K3dPKN177^ zs>6o_3{8QT0$xbsR#RpUHOd2fg-84kq&r8blWCIYf<*hnW{ghZB-%*WB5ZRT413gd z5+NSnMEInq9vC1pblBLH;Q$t3EA`P2@*WJ2+5Kk6A}oIa9k8Jz|AIQuugG#yZhMyC zpOQl|u5zO?_vw#?9o=%{mU^0wLG0G#=>+D}f-dJh0!Z+U?-j;Xt)h29EJcmNUwkIk zB2SN7@9&&B)3~1}7ZEON8ohg6>HEwtjmjHScbxkBh$zhOo4zAY)yK3&ayxaD#s4-G zG3UAyqiFo7-5;wCL~rNFfgZLiLVLi&r6W*!V+5L`Ue)=o$Onw{!P$`!SMKc!2*;n> z*-Oi<*H2vSk_^M8*}VdNrTyLg?V7J=@LanwZ+e^S4bJiBd2N}LXPID~?AoZjwsZNq zI!t@JISPv}9ue6eMIdX@U)R47(heRv=c<}$JQJGSF%}U>#G90S3g(F%wJ^#yWCgso z9FEXoU#AbRo}|!`s94gHi?hqa*tXwW?69Fqrh8Y_+OndSy9xc{jOxR*KG4xAME|J& zrNh1-P$8-b-3#-tI-GBcwprnsO9!yal2-JB=UD%|S z)d0|fP$d&6ZS27ZPm+*eYF^wIoE#~&+)gWkFp)ri0uZeqiO`~rPN0PptQ8^sZ^YZG zFrNyUbg!Io3qD<*i{m(HJsqvp`}9VOG~UzUM)J%>S{LnCptXf9{x)H~@sv+PZy7wc zf!1O&&`MbHy#1JWwPysgu&mT@MQG3hpuKSYL zO+tmKa`9+t2__!6DGM56`@OpOE46yQsH)5o>8lT+q1lzBcfoi*ICu6>-^4|Brj#1$ z=#BYJbgn{8cb1d)d05%p_VM^_?;c?xu5Pn8v*LVWee3hGLw;pxPdV3^P0}}K0YD>+ zX7&W=guXj}n6G_~49$KH&Hl{M$hLJg4qZ8kxBIdeGCk64cyt1#(oKeL-|>~ToM+1| z0_RLs1QFc3OsP*-Yn28-SLL za!^1dCpS6`Nei8eH_#3!FerN%cHFJ<0GfIE`ls&(cJ}vjAa@O`-V)ptgc|^p{W**Q zBBP<)z^o^_U@yH;Oet@thCZ&I|z@gIJ_J;4i0$>Y8e*h^C*^8d%*<-H*VlWs!n&Z^- z6GAJTKh?~I=_pOst@##cTx|2+GYx&tv!Mim1c%Kmbk5OKlb@gF_hgElLw1Kzm=R9) zcN@{~xiB5TX^;jq-w@Bsv`tNPsHBV|tvL(atdb9W0(A-eOI0}y@Q@YSl%t=Im7Q~tSZxlT+K z1Fa@8rqH(iy@u%FmGliBwR$%Xq?e;Xk7G#cInhhG$d16NZkK&*a&iLa;jiM@k}o#oIrno2Y*Cs? z5IO;BbY0EK6xe;Zb`R{IAE4BL09tGAt1d$<9`(6}H8^>%8ixiQy>sY)teYNbk&+oV zSvfCnUE82IBNkEdu*K9p3W(^c`9|MIj^Q$0gs$CwovLf2@l1ODZN(TwxQj|dQkZg~ zP)WGzgN-`pJ#AL@FsKE6%CZ=EnE<=12)vj9?`_!kjr(W=I5IXPYO?VZc~S$w0Hd3z zT?sWxeL&xH^~+wA$-_e;$@hdW>j~cK;pq67(#!27c+43S!|w{H30|N0Qw6gsq-Riq z|Ky~(MEV{_4vfcp2Ya)S5ZiHlT%C0lHHXme*hF~9@^7t?3$ zSb7aqjYuB*Lut)`@tZQIp{(6ULi{cuhX=ZE6ZX%w8r3Hi7hJ08p&&ZFrnrkPFn=P@^jQ)+%!Elh}e1Fb-QRV*kQIx zcijl{j(LEyt;u%-mslQPj8SCVYn3OoRywzh&6cH}3)F0GeSI@Hs@q6MrCuqs&kW{= z?N(jo-!5)p&PVJKTb;BgT4I)Ja7AGYtLbb}Atj3Yr$Bk}oc6ugDM+s=;oF7knA~~h z>0gL`(i`y9tYcrdwvBv6yZxJl8h_9T0=zKBf z9kT><$AMP>Bz^55S5?+7yo<;_FW)ernOH{;Ilhg0z4}o<4_xCfo^t%v> z$=ZpWUYX>}^l1l*#afH0hZ{n718@N*Nwr~*RC0bE#?iSUYn$~v%A3=>HM;?P{^tlD z4(mB;7jqEkTXeh}1%BwGFCo9Ru{gf#P>4fABxG{TV|)7t{+`H~pG4p85|iz>cT7~P z#j02T&Bq!uzv^KY15BqaDr%y2(vEk1{`EN^0jwYW$--xEa{J@jMW>nB_7eYf#MJ?Z z1n`#D*Dq1f78r{**hy}XAV+ZR3a-QfaTN3wsF^GGs$5X(-nH&71Ct|J( zAb4R|w9!UEdC1COLC#JR2fF^XE3bf_VP=Ym)(J}P6^6tC2(+xjA#;G%#hE(V+bfnP zx9i%{wSKDVjdT)R6SjIXYgy;%lQUzQW06n$QhZ>syyqON(F{OzxrYjvc-^pr9ge?*d#fO5YV}Mf%?XNBT(u9O(ZsgtZZuEnKG8^?av=L zjGzwHKl~QU*7b*TXQH~xF&o)2kmswkME&&J->6`@^vjhv8jp*ek=45%hLRc2JjFD; zh|hAVoSG0z7YoU~hZDckM>{?Dy*%|5?+ba+pdMmU+lED+yWK?D1GBMo?H1GJOAFPL z)~DkkaGNmyV_E~%fbmP$ipy732WK0IKnDCCaTVU7Gir};jiC^h3LKn}q5@W>Avh#C zgtC_*IkQTv$WVxm75)c24&3KB%5R04WIcf|+qRB1$15#5@%gK*W4yeHEi7hZsYzZd zPNr^V4Mgai$x%_KMGFb>Z9ki_Tpk-X7weza*4IsVx-d}WGfZpT&nD3c*%9D~+I*kH zY;BLt=GJvJHLYc=1v{$334PuQs-{Qd(VuIyS&md0L3;Z76650?SnwkT5)lzu>R3B0R(vXy!`yo z55Zr*e$5n`ATodI`T1Kv;?a_)ORr44qTVp(&4$ux+qq*Xilfw|QgzImNt>RJo>zwl zYmBHksaGEllwDdpuNKZtXuqSgebYcnjEPf>Qvc?yiSH4G)9!zo|6fm(LJ>ah(i>!u!2Jbh)ksdMj%V5L?8KM|5`c@@0h(ILpuaFrh{*2;?~{#gf$GEnxw+-qm}gcHY)cEzhlDrdd7vN$dWouli&wA2o4gwAR{gJwiA~)7;Z(;*;#W#O(bDeC@JB-JsFqxvbjS7T zuz%zJ(#>3EJSJXn`(FRW8ymX@yH8$e2oDap!ZF#)ayn+)ywnl;7!2<&#vrBn8eMsQ zZ^~Y-W;1|TfT~o;O0Qqfr&32vtm!H`1+R{tJ9Z|qk=~pvH`LXM^TX#CDl;1^>2SG* zc^H0(^~0}?fC*(~eOH{5CtZLX@r@sYn3OjRl`{3}qS7>;tLAn9ugm@xWw zZLXE9w}jYMtV?igLVvPDf|_u)_D zM|T2VjW&ddR)}(&W4R9bDi-#LUDVv^OrKC^MVX;O!6L zaXl<8Egka`Mgp$Sfr47WRxb9x*rry5x;L23((}KwcU{d$0+|ir8-zOf?S$F62O`>b zjRi~JvQ!aGB&DW?l4R|ln5>$>#_2zbM%C5nlX+DZX&V?gSn=X)G?GbsQ)WnEVtQ?! zY(B~1wYhXT$b~3enQ_KP3p{8+$CY>RE-I?rrCLn{!gDb>IXQ@!lZc7PL*qeb;O2Vo zCXUT!_7rH=M@R1oO-#0l98$OEkM`5axMi!&xRI6NSfxt33Q_9$446U$Mpv*1LfF(! zryW`Q`=9({kbw;mV8B=q+oDJ^#Nc5446EhkS>DONT5PbhDzwU?Z^2#SZ_II_Wy109 zfS_HC2TJi`lJb90;4E~izaW}6V9lM>u43Pav(N2CIhR6f?}FS;nv5>}#tZWHhp|X| zk3UKzM^a8w@YLwHb+~2yzM45{%Zf(OIsbUrSGI!XSUMGXQZcI1LjM zQfYV6o^*}z1?AdA)?IEZi^FckaOmb@@khzl1uJw4Y7t4$;2T7$)by8Utg zl^1p|D$A3ORP<0xI#jVr*+>L8#Z!@ykrnE*B9|e;!?QTrHwxYQ(aRFMKRiBqdzw5F zz9ldyPuv(pMJYp=Jy@i_?*llk2Duf4G?eDNg!0 zYBNa!CE(GlI&gyfB)PhH+nBb}#?*A@V75Yt0w|SkCrfEZtm2|c9*cy(V1BGDHjwJp zh>2(fbQXwp$=WW5;+gZM!V~Y!)L>rv3%;XgWew9k6265Wf9tahdJ?8KF<|1_7jt%S zU=l$TfDng`!<)II_6b&n?#mzdI*psAtp=MU%4&RNbL&I@FT%iEdf z#|!zbA)tm_TJ}GfF7UL|ZZ7mwFfzVFF)y@2HhuxTp5E~$>UCoF1&uHsIXU(&%* zR-Ve7;Pac^d=jl<@AJxWJawQkZ& z_2=7F|9-J>BBzb+fz(5ydlo5ct-c~fAi=i3ZBJR+9!hj^L7a@`AKaZ{F-hIN+++E} zFJf?db$7ALuRvC z!iolv?wPT+2node`Vb51g?*4fbqoN4oJuySs$UIpfswA z9v^P8rbOSYPs`P$uC{uJ%rpTY6hurJD;$nj`>+c4fs(R!X69(4=jT|4fSG{vaK1|* z1pz^ST$5`Q?Wa%GwY5sOzpA6*A&SN~U_rHgE1@FH&(J{NdwdJdnWXz-)w+lr@ zMco~C@UO_3wVrA|0vKVV@)ZHe-sjJsC43%ner12FzMFHvB+XZFxjtM$)yo9KcPx&% z>2|b-4GFrq{H;1cdmZ^M-s~*Iooxq5xg(DDhR$zMSj_o&cnAl`9-g`P*S|eKu{ygT zM3At#Lg{vOTYULRN%VHVyJSAhl*}q&Dolm9n%$&xhXXzn#+Di)JtZWlRSgC<@(xR`A8tr*f8RJDE%8D} zY=qL#@fe)V{s8#z{N{wicB#7&WlR7|PHOoR$n=%R)zOr^h_1A>a^K3zE1EkVA?-$T z*W{x^VLXYlJe^kRODH_ndwY5J!p8a1&BPn8i1 zTEkfWh>LC7XF)+h1%2}^zI9T5Z%+G;FU`SyW>?QzRZLYdJog@&ru1B{s5w3Ec4S7f@^UeVD7EK z{1@=Sy#+2}8`qMxdP++B$Hzhf(bTmhB)(ZmQ`}MRJc{C8ASL06hJYLm5?)T5V)UmG zD~rfU1dMSbf~Gz5w#>{g2|3t4S8GI;w3$9bdunPD5tI4W)cmRYN9>Xo8%&u9?et^V zWLwI@uZbP-&;EQ?V5Q-KV)<8badDjim-r=rd>#t>KKF$mWgy?mlPR%C9eCcf*gj58q)lHl=i-;GmgB0 zp&^myQ6%5{>tny8pEt}l##-W#=?5#l3R(g#`?c3Q_C6E$*QAegwHTJ|>OUVcw2oKW z5|fkfgBo1_CXtW`U|o1%ynEi;5Dv{hmENmXMbpd;M#cgR)Hd_F@bZ85#NE`dGioaE9~ZjGG&_menN_ zcE*RjNu&XJlb)LJEiP`;u!8}<=3%0~Z`o8onYm>PufKRoAe5ZE!tp@oK_jVKJTl$~ zx$NYA&+M}@n%1ns?1yO?LBUhi%xH_JqeV9>XsHSBA}uZb3HO+6+(G2}I^Mg1#&4}L zO?QFQ)8Z;YM&gn0JqoC76>{|Tuhf5YglC=ZUmYZ|5WBb_r1E*yuX(%*cqYhz;ujVd ze_lakOJLAsckZ{p-r#NYUHjTOU1NcZi|f1SCLtx^XKak`ftTnJ#%DC&KQ?xO4O`XTsj=xhfE*-*r3(JaUs6dU+vUv#fD1z>*-X9v^bs9%f;Go{rD9W*z?R##USqR`OL z+a`%v@bDf@L(iCOUt3zDG@azC<{Ey8@{klK8PkQxU4)556kq%M+1Iv6ZDf&<}i4oJqp^@ z1qOf^Gju%*xm!5);U;!2d3S3|uhrcmaGtu!Z)G8etRnD>OV4>c(*#pC-S2;Z0u=}i z|Hj6Yr+Z6kn&R;!oE5^A6$QUPov^{jj}C}Qj<&W8)I0!xKodPW6HSb?1MsR4E84m! zSYPg)T~=Y{Z~H3=-I)igqlGIcYipty&5vql4I58Sn1tvYuRNGw5Ta)H<4f*})B+}f z;JI7xf;b-(BLrkB7cveQo&!#t0i>OFSz0P8v%ZM5cg$i--tYWke1J;g;ifZ?{XX=G9RadkXuo=w)NQBI?-e(14k|r4# z4b>Ck1n}>6@q2D+dwASI%NC=aYhXdC7{rJ6Jkst_vkOb>4%1BI=z&U=@thz z$3e?NOusp*G+Rv5s$)K-6mwt1D6G&M)X5A=^iivq=4Ltqu+iB9{qsQ`SX+RUfr4g8 zqp`y*6;>!Ufdv7w=cGy^bI37P#Et25~< zG?~tN#=L^>&CvJ|T4#SCI6COW&BmK6W!(!~Xy)wt%iOdOuaB1dQs`mAl+B9JF}CAR z-ENNgw)nt*3-gcsYyg_nDe^2PePR7ngf(FxtjanuL1KTbLl%4*6Eg`EUl9t|QHCYl z*>X@Jby2xK#NYS9O;&{AH=xkkT%QHmTS#hRFksggSyQcOPs@glFlQK}sF2apS{1t- zEq}e70UiIA4p;4P3!BT&S2TYD$UYL){t`(>`KLM!#gkf$$I~v?8CT+YJm&pr6tzj{ zB%kwmMifD6NVd8a1Y^i(j& zM9OpA@?tfBCp=(LFqt*_9T)dRK7%_v?2R`f+nm+r^amD4CHu}y|N9j7yN^^cBc3jeqz?Q3OA>OBK48*G<* z&pHT5DeP8mA4mam0ADwu**oJg`1=3sjY_-Hs zO>Nk&1nApy8iWbvqXaT?i(zY-=fQ>agW%v(W-xFYfZR3%3*lV5cH!vJ%f?b6e~hl z+sJ6@$d@M*w?PI52Id>W@1CED&{DmFHp7|0_>vcfm6E7E?_#1Ck>ErI&FhNS>8a=k z9HDc(0^pP3Jr-ap5%=+m3T`BvX|d%G|9 zL|Pi@?rvCgH~aqn{?GFg_Q_rcdcudf)|&Gk;~G~C+Np*)4925qc*j_Np$0V z|Bm7DeXKb!aB(R)`m?NT)Eg4L7Pt59i6J2xhKAqpcGbUHSy}Zb#O~y^KRsAk15(k@ zZg2lBMfO5HbQd~nucV0F-P2Q{*KF70Xy5i|HmD8|(=KARsh8JlZ=NKU8~p}5*ryd~ zBYGBJUz&}9CKo83T=m{^T~+>{kDS769}S)A$yz@}lQmn$(!ER1&(G&8zybyEBgxwR zhZxrOD#JC^?Jw%;H9=mb={F~Xo0S#u1qcDJ2Amosxdx7jxEYiID)o7((L2qeZ(iNq-hMgj%joa75%m)- zdSUAUIz;6seen;GdGD@MBje(@Wp3hQ{4xbSD`)zPM&S_P`?|Z&8*0}@T&@t*zpu>R z5s_XJ{Lba>w$S{9Ynvs^BI0Y3Yhr9-tjx-7M@QS{cIL0Y+l8=0(z|-Uvj-CmP0*o$_1S)L%3-032mF1cU1-$|W`~ZaSzPQw!cG^o(B0Hp{-Y#6D*m1w%tag)>lJ#DW5Q z6O&Cb@h&kjvCU1Kfq?;Gov9FvY2T$r9BgcCd{-fM_FC|`kX=zzSgPM1&7JK}nnw`v z5}8p~Y0B3K5uNI&LM4?D9Gxzvra4_8E-ny+vCmm6-WGFnX89H$>-`P5pYNendwZ5> zE=+Ak^&ji6-ayH(g(s#;pD-w?sJdK(^-lD?J+BToH`pgYUMg3D- ztF_c8Wp(S>8u8t~f3pi`&Y*8Bp9T`8A3xp(t0}7=EfhRdX8G7zPd|smq^9z@Ml?o1 z(jf`u^;ZzUUwZ#8{(drG&fhHk^K(a!m9-_^vSO)}VB^`&FfloKmXUZQ>Sf5+#cS`p zjGMHMR8D9x`dcBdlrxM~d*7SmjB4vDgZ7nbqr9As7(kc7!N1`y3?4=xVAkE6)gXN? zbtSPd4aysb$xm7T_r?X;&p#}8 z0$oW3I&O0_>Y1ut|3WF?af!&REvhf0ui$Wh`F4JOK8pz%A~f5BhxPg~t#ah=R(@}@ zlA5lrfJIbzLZBQF1PF!<<}7!g%nj{ND8|)^P`BH@DO*{UR9goH1t}{Vwv`y5w4JwC0Tl`G`C>hYf6mssLh_`1Re_fG2}+S2MaqYO z5c09U(0~oGf*S!-o35A=^8B9lBjIc9lc}1)12vmeZ32JAR~wc8X%BCWAW`oqnd^Z@ z{HLTO@kv|MvXyr&Eyo3@u!c10pih*Ik30luT zQ9C<34Fv&Dj)kT1;lqa@H7ba{xaAWRZf|GS0Co?uQX>vHr&Q38)?r^hqcRlUoLG#+ z1wLJf{P*q_vt9gqVREjB#GnRrfSn!%YAPY8(DGmTx5R13iw&#YZg5Zj%@GOdeeXtr zsPeIXz<}oe_hn#`2F}$b;@jg8t`b}Sd1pc%>|Ko`RcWK#iM z!(jGY+RO~^E8wV9^q<>C2C8?#cxw1*Af=kAFU+#_#~7dA9>xEC+V1r(slDWJHZOXH zR*m(sn!LX5MOh!O&2(o&L!}If0Az4Vd`{Pl4uqv;WPpC9zWXNa^x|7f$qUzK?}U3q z^!5?`?DhB|I#JP%l@$giS_O6@yD(#GcH{jCGoZ?HaB#do_kMZy{^ao{VLfYI^c)tG z{(JOFt7q~Z4~M{`e{}RoI*H+%6$E}<# zobjMK{v5<2=Kh-c)ri-*{}h~XT7{IY{e3)K-1Dt}@qAe{eqJ$DP4Tj@e|Bv5b&l03 zCc)$~p`*-Yq~UYTn5N9Zd4*-5;G_QxCZC%V;cBnDutuj{csLRq*9o9W{ZOpZ4ZXZt zHny zYV4g_Obd(SO@0eALaDG9kK0(gWH>&sJ$$j6u8qv~9{^qW5AjNi`)Bn}nX9tpk#Ih$ zgUJkedIX^67np9F;w2_7oJE%87yGZP$7rOV{AT62kTFt@oyN6kvSZSI zTt%#l-8ZO?cG#TctABhAo)qMn9bbblm)Lb@$IG7IkC$3KcaO<^mqa0o_uX@puzo<=Hqff4L z&>X44{&&>RdP@<>5{0RISpp6a_YRw2Q;$B&03A{tfrX1_8d|3IiZ|XB{0* zv}ZNB>Bw{k+Ac~%9xGjDnU`&Cj}$X`er3I+KTMsrBA}Bve)|Tgs|%SdBzkfFqzii?(?PM*=4AcASz+{7+E3N5B=9 zT5oS}VgjPKend2=!7Q59V?Aa-szAvUC?Or*9nC^Ofam8MBH|Ijp!`_-DgsMP%XJaV zZewFg+!_r)Ct+1K5=kd5P$x%vi(@hwNz4t5T25b)P!3mG`-}>y=!toG1S3RIPuMM( z*`0AE_M@T{0^S^Kaxd0@#(2D6S{5u82lFY`jk&2n<+?l4DQTPEFyQ?qEq0S7S=wKG z_=ki{f|u?4qLPz+pLIfRMNC~bdn54}T7WB~h!}yK^)pt|$?4*+xVQnV6C*w&73F0K z2ZKL|LSgrMX{ixgz8DORjUz8lH+2S;9HOn8W1_yNw96&N==^*<%2J}PIt_Mt9Pqsa z9MnAYfu7S%4wj@fXF1}}8SZIo4&Rs!aFLf-T3|BrfF>Ji>VkI0tO^@r-eW^jShkQ0?YT!)HH4qxsxc3@#k@Kz?Vl@Eio>Lbw z@EQemy3B%H6^Engshv+dzld^ z{+XyRgD<~7NmCg!pywA9u;?`DYRM#OL%zgl1Zx?R;PS4l@YjD%R&mr$;`&eaSmxkOvL9M5t2a(fHEcd2Vy0**9vDg!k_Rf)wPtKa)pzqOs#5&8Fjx0(L}|J$5L zt<@7Kv#>4*T~{>-D1rqm^xY{|w{ec82AmaCtcAVKKi8{oZ{g;YRCI~VC8{EW)8u{` z+nRCWnOd9kVG9J(+#q0(94-{_U#&351Oc`b$ZdcSjIEWg&onpZ%hecNnF`NcJH?7XO3(Fr zJRhvO-Oeqt7W9Be2tg&c4veB75O>NL2BVlr@a+oLvIoHbwKqcIa+Fn(Aw5xB2D<>ym{ zL`QIBiL_>8a>0xj6(OO0zJ)|7br>7lVooSD3Z~khEqiRsZkeo@-2*eZV z@hm8eJ4cWP-{o6dY`=ML!C4lfjJ zYz{w;MGkKE_8U`P1k0U)S-MEE@%Wn368rY{_MD1M$cge*;jC!(@lk7-gRsET^Gn@# zQbRRe9d6$h&rtZ74?p#)f2c@^NGL1ANMgYqz8m)c#MUMe)_S9W<;goC~}G%TgN*;cv}^K}02$768ub#3Dq+e5!pZx$XBT8+jp4&P0Gtmr~UKgIZ> z^2I0#IRU070E@>QvUq<*oST=+cJ+=bT4XmwKJfjJ41PMK&HlvaCutHlnRwSov+J>O z#i5zSF2z}O4po0XZQ5Zqf1#oUIpbE53oeESV&D+?YP&Eb4b_?TTTDfKJ^N*>V9B%Q z+FvNj(M&T3JA zP{y90YCA20ShxERZf+)@8HQQbwCMHnx2k8aj}zTH*3a^!Ru$8tjDFmAn%{i8iK|Ct z&T+||&1u7-yM1(g5mMxhkBc+x@0ySZP(1%N(i_MWAyR#<6={Ndo_?CUqxYR2U6=%5@$M$y`La=Lglhx<5V`Oa3`apK_m~xO+t!Av0;o(2wl`bKkJ(@f?O9Io@$v?> zyHOaEXZ_pq>IpokLx3f3vVKti(dFo8zdHxuWyp z51?sA)cqT|09=!axqgX-s6Vb(+R?{?zevIofTAagUdvu(rET#0D{pvvf7@M@Ex+kD z>Xi_yA?+nj5?a3ultP~N<((5D=G1WLz4~poJw)i>DDq?LlV8X39 z55o&xAlTHt8}N69zsjJjQ+mxZPSqSm2}#5qXyQ%3Tu~f4Y>HU}yz9|Oe;iD{0Vt)fPiEn7UF0&9x6*o_ozqRwk#tUQ(itQHYJyUMQeFT; zDQ+zZRYzA>nUS|-1atgI;iD80qL2^cDlXBCv@!&xDsR&DrS0i)|9yq8C}2L{$BQ6o zEiPOp>udXhg19BK`u_a~jvjW24nJ4~Q(nGeW$nI?={y|>VgXuiW8G8lC&O0GNyUc; zhwBe#0?c3?Cz{lv^~+6**-fXsS6n*FG%CrWcpjexZ$^mdD&ixjrpsndO&`v;8TvX# z82!cF1(pPV{j+wkZ%vcDfzDPA-gnm)3=(rG8MnPVS6FJsusMl_*DP7l-&9MSe&K?k z&+~ZANmKGZ+`-3OdY9Ysj1~?QTxE@BaC6s<*-hZ~@RJj;*fiXnZT5LTEQpxQPJC_p z*70t}K0GY!6Do0N@Vhp~e3>j9LS?|`QqdI?+gSE|lXowyKjxW}k^T(|2Bs)|X+Qwg zDAsqs;?Te4pOYA=q!JmKnl22SblQCaa&N`_Dk7I#o7oj95IaidG`(9D_9%uf)fhC8 zT6lb4o?&a{1I{)%9O4+ONZ}G@+9~EP>rI%C!luoa$$e8gez|o8M-nc|nRi5-UK7y` zvdDui1i;I{+tO1i5Y;!hSDrEl*yx@%tR!9xXNq zdljcVAS!4})f^$9#(ieS!ir64DKEe)rkC4S)`3JlheZkw$G=3peYP~+VL(Pp{B6HV zd1E?$cj1tIrTE>q?Tfb5s?nqULbt<+F4168rAXOE1y_X&@2oVqByjE?9U zV_s9Q(hr#bAT+$FzUJNQShE{wHCfn&D`p~A|A%Q&Rg|~jiUr~AuU|^-TFQ%;SA3Z< z4*svbrsn4Y!J-FUSPL>Wv)oTsr00D@5QaL|ev;ov7q8kGf!Y>ZNAn0F!^U1vzlo=E z3Y_n89-GUrD~XKESWKx=ExKjahHS0*1thcRB@x4f#LrMBwF=?3-VsHH!Ch}6~sC;Xz$`x(Aem65Z0`V6DxXR#of(z49RXfXI~IN^bHblQbbm8aox)!j|O zw(gUa;Puo#`Vl|-9ai2#m-tSN4lRWz8d~J96UPa@?!p{DwjwH`k3`)(-6#$TAKIkt z01q?T5s=|UE7!S{yv-z=Iup9^DpJp`#_!qndgvJ&ew33H&=3*Sq7`EvP<7kuqwU4C zW~bc|3bsggsn^mZQH;|LIB;79mSdm4*`@%M9H$lP~ z86F<5PyBCWgmM@Aj7j19>hm*9{@M6G2do8xE$T|OPu`NnW^i^QgZli!HQg4x_d_q* z@BM+62IlXvk=cL#%zZ!jI0bK?BT&u$36;Fjv4DQ5<(q{E_7rACl|h4Fzgl=@QhGQs zCc4wkP?A+qRdw6N$p}wkubizVpP(8 zQ85%Y#0;;~ZkYIWmPbCy0Mt~&iY}7{4-Yp7qSu_VPz!~u=~)iLbE@9mg!igh!oJK6 z8*dvp4EIqS$UJv0f6;0WZ#AV*(KYpCu5)ru)nD>Cldu}DVKHZg2?(uk;}gFM$c|1~ zJu0^UcDiP;Yik`k<8n(Na}1DJP>9U1rB{lcSn=Jzcsl*em7!YiaR|EdsC&K=(X<%U z5Yxg!W4QMn1~n*qjJ9=opV&gauGgyRr6qU5FI`$mj17jAk*A|KK&3NZS%L?oQ~$1D zHKi!pxQBuQ`qyuc=$NGm&i;_8smdK+{mI1^_wbn9a|$8mj{Lf}L~n6iJNzYSXbL)4 z!P0W_Fe&9KYo}#bF ziW1D5&A|zuX>INO*IJ^?TnND2Ywu1V&AlFe-O)dKI3(3_QxwWBZeDwgqQSOu?_2aj zFAv4S3ZX#)DEN*WLGt6lT7SMvv52~$2f)+)73`Lz%lF@NuSix51+l-NRKS+0SK^0Q zTN_y#4lU^W0x`2}khP+BVGlhkG@i#Gi|fdfJxCe*@rQCwem3JxN8r1*jnKiRs#`S}9{E-`trIY{xTl&SaEHU9>; z+lD#^$ltO2RqK;Mx)H&b5J|7#yZz-9z|s0ATKVN++8vRSmPn>&HBl#}{RU zROuK#D1VV@TXeKN=%?AVrL`B{8oWJJgddXpSzy9Sn z66LxWZuU}aB)>@|vkBS)fIvTU^Gm|C5yis;g1TTzx#=?YQbFV3UK=>PY{nY6`k^OI>SDk@ss)%C=5HK=U4`_U7S zz84;PC*-4z;KTCxv@@J0J-Iv)cKgk|F?H7~X2_v>5*QAdD5NL(9Qe87Z|;A?Ei*RN zMe%gP@sDcmm4OAyprdEuF%%J5k+M4t;2P{mQ{0^Ze;ee>NUD*xHqjfxx{NXfD3JS# z;dzHS&4)B8`xwn&lJYF&HA#|9yHAzVwWgUX@@!ZU|HWNJkUvqQ0g=DAhCOkAIIsZ_o+az+_?cR@h^ z(R5X(q5kdPlP_CW&{;y%a{WraiU5>Cg)^F{dCHkBKDbSo;MUeB3he$N?{b7)&c}rU z7sIPk&Th0?Q93Fa^|7vhTxrD`?_xCw0eeNFBHzRyyU2Yrzj zyPJH(-#et$zs^~L_ol;952^>xs10fT?p?!n z4uU(g@q0xJ-;IBFAf;2?qgg~-8av}B*nE?lTCVtGzC%htw8m%z^0;c|XAOQ!N>-L| zJ_8Y^ya)I+vKH`ESlEh(407IaqoxW>1v6Hp9-j$tI2^l}1q5CPU`q0RKenjd2&C-Z z{K-kplfc8=s~azLt&aDFzv8o!wzkLFhFO3@t_@?#50m93UV zDe(Tk#}n1T(dd`CninhUz2=SQ(|tTvj|@~cY=Fc3_Kb(J(FMwd`*jALz35^tWiO9( z0qWE%qSfq5N|@eQ7?>s6;o}37o2}64)yc8CZLdiE%Hd?bjsULD*cDRO?)$^E^4~do z2z!+-r~){}3RRh{1<^bn9$v;fP7{1P4k`8{Dwf|4?)`fR-MO-96RUaP8h)#e|!ee6r8eLOe44A*Mi zK!KFt35WU^%Fnw96(@_|e@H^5%_ru+B%L9iI}&cuS8#j-YuNNxK+?KE-oA68c=J%p z37t$JA?6#*b@M8!?ns3=`a#HM z=4(=&!N19py!EN~Z6IhVX#wmPB;Jv)2PY`Yf@UzJBz^5-d1CY*`-Ry zBqrh!d)}XI`p12zQCroKLMJrG#ClZFqLG$S@Z0%xtgG8LR70Uksohr`AhU5oK(RHs zy`exZZ1*~J0==hRm*gbT&7~`*ivWIy3Qi)vZ%@pVmPQZvc4kv5S_+js=wP#^ft;Gu zE)+=?>Ow;Cr%*n%4p9Nuno>yA5dF;I3}3Ig1{c~tJ)M0REf0)C^?yN{T#=DkLaBz-b z&3D<{l!Nl5qKSwI>r&yl6im0UWa>`g%!3|bl1YU~WKx6jLr4N-t6hir`c3gKHnMii z^$b2s?u7m1(LGswQ$8g5Z1sTA0yOO`+vj!I=iop&Ma72WiRTzJkf-4o|wx?~t%^LM9JZo(^6Srz*-rOD}hziKa*U%kqNLG|;b_+&1r-^eD?g|2<9Wod0+^WR} zwYlj~YM~1SHrk)u(t#u1ku-55LqecFvd8X?cKU!op;nPk`RBJS_xMDvEHo$V8FYnVmLA ztY;Q&j$4sI0vZ}Bvty2*B42z`ozu0=%$fJfw5RzX{FKmYxmhQ+WVjt>__c#-sL$*y z6qf{-=r}_#m24D~ zeIrC);n>f^J>0I;deFkv7z0#+!KOMEc_>)@!5DJK)I)c7mIK;O4&-F11`2laSdL~# zibe&5#PBSXkBY+i@fkdxB|Ay`Xj^chtkBHv@o*;X3~SE=W-V$L-PC+#-`--hse-no zEr0mmzBgI(A6m;+-7Qul<+3Ec$E+lQ{A0%Dye3OQCMGmA$v1T8&V(NckyBz?O`JCX z*dD9PCuPNQc3He&^qIlZUTw9(u=-cHz$E=KWTaOwPE{ok_f2_D$+*Ol5)ldka~$4s z=&PpV`m$M&&68f@{*r!i{#lY>eRtGAWT}^{xT@M?n&=sY1=ulMe?PJ5j0=gU>+wXh zgB>@(P$m;kOI1KWH(aDW=E-K-s;RDhy&28HI?pCr?s?PGO&K76`=<5VUrfvST(tQw zo&8%F5Di^j68zs#N3iQG+`gbBy@h%9n{bYBCm<%)$&u{u!U~a562`Zwe#hoV zFD@qb&lJ}#yXI#^7U)j1xld29IoKxnPAfEYQgx}8oL#E`+Wq3|Nyc+dl!T^~QUym# zh&!m12D&P<2w2J1O7S=~4^M){{S=lqunUNt{>kqc9}!R24NQRh zs>~^r8%6apxu$;c)<$Tavs*h5_ zK=Lg4@5+b?9 zi~D9LR-h50fJsWadBBJ3k1{RV(SMJ9=eLx6va*bvCrHInm!18}tK&ofKNk=y5LeqP zo|2Fk%9}$G*Xr$UzG#{wmN@%iZKQcwiiOUd>R|zS2RaTXpfb&4;7#lln-oO_mv?hY zK}GH>bTTtn^oE%h8YZdig#YC*KK|&0OdtI)Xhd}o^xUCi-6t$jV%aFZ5u;K&Gr6)J z&#?1K*z>_$_Bi4f8wm*s0h4ZL?&!ch4JRk(o%#8AULQV-{zP*!r`Az7rli4IPf$31 zyZ0bLB_wK$Z%t?>eu(i4e*H?TO+!orVs4a#$qZ(k828oQ3I{zs;gQoz@&oTY?^rE6 zJG)|*kRWhMTvDaNC-xi?^LkAIZJn2+yj$iL*kN>2x_>Xbdgep?zz zymxu1Xb}Jre5@? zLKe`{PM)e1_w-J{RLT9tqaRV89_sYrr|OiX9Y5H&fCML@siJO`W*trfFJAJ^h4f8D zXt!gW0NMe=P$s7o-!4{{l$bfYYVOy>3qK^@IwSG1J!QMSa=+_J2x$)b08Gt}sx9i3on7gTW_# z!>cbBC-dJnvOj+aVdHc|sCQ9AnZwS;Y63bE2Q}Pe!@oa0z3vA_YF5qLlUOw@5aR?~ z2>45}OFRSAF(gC?82R+PUn%&uO2+ex)a;-ChRZ2|)BHnJHeELMR(4C&0Q4o*wRIU< zt`J+lT4WW&o#4Jz79~EmAu{_ahc~2X|2jF5W`BkdT1F;(S%l2&FZP)~w*=XTtt^f7 z|G208huMkt`+9#nSUrm3<1z>zEZ_){Ln!Pi+4>@3>1@$*LxSmDla~ z1D7l^6u~L*3tTYSv(bJfYE4m-MJ0I)QzO~x(c!0;cuJ)Ez@z{5C25$Wk54UD4s zg<~;Go6-FD64R#^x-)FrFn(;wH}2zyoHxuVVOyD7P8;@d)_1Kmu}oC1rlu&(lFRIx zs>!P3HM*L0c^W@*uN=~Q4VT%OTD!MP|601VwShN31L(Qr5jZGnQXbm(2`7cA;iOh^ z&opVBaa1^g3IFWJ+1IEnEM|Xx6D3#?g@WGbAAyJE*Ov45C}6&BCvI}~EeI9oq9Gt{$KVnm7fonNI0~}?m-|5=lUV<3AO#<3>FeYu z`fq{uK90FKOAFjLzrOU34+jOpp^BN9-~cMd{H>u<{68_~M7g_>WZ^f*Ke6(jpRTx9 zAB$Fi%;wOWo$%_us6g_2O}Jrfl^#9z?OQ#Q<+76_9WVWS)>RyAW=!qARq^0Ir{tfD z`7#CE+3i>S?eLSfbYaLG28(e@-mUO`jp+RaVhBO$3`B2m5O%l z3f#b83#|ePTR23-|N$@A*B9k zSOg6D^IrmA_fCaoo|L}gPWSfO{ftN1xr!p?_kB1TrKkITvZ4p#Np<8JRoYJLo$&ht z%AHqPg{Wv~@t!5*6O5FUlze~$j>Y(%(zcvZadCBP+4cwL*1qr2PY{tnRXbu=ck(PKe@?;1!G6O(7EbON)=n<+pX~$lyxn;rjG6|giR*y!?xyHR?;V=6BvTe^2e?*rUsEWkS&GUI&kg^@^> z0_*hEwVR`CX>m_{9O$?}K=+j@@qnp^A?ndE@SZL;OJk-r'$mV^nO9e8mS)-7p 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 b|H)`MI_Wz&{gvI1{n$C-$jQYN#Nqx22FkLx literal 0 HcmV?d00001 diff --git a/docs/_latex/logos/hsa_logo_only.pdf b/docs/_latex/logos/hsa_logo_only.pdf new file mode 100755 index 0000000000000000000000000000000000000000..8d50990de103a71cf68b76e12a0a786e90cb136c GIT binary patch literal 4452 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 Date: Mon, 4 Jul 2022 12:10:40 +0200 Subject: [PATCH 02/10] longer sqlite timeout --- ucast_project/settings.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ucast_project/settings.py b/ucast_project/settings.py index b98373b..c5d6f28 100644 --- a/ucast_project/settings.py +++ b/ucast_project/settings.py @@ -146,6 +146,9 @@ def _get_db_config() -> dict: return { "ENGINE": "django.db.backends.sqlite3", "NAME": DB_DIR / f"{db_name}.sqlite", + "OPTIONS": { + "timeout": 20, + }, } db_port = get_env("DB_PORT") From 83e1d9a406bfc1c872b852e31a129143d602676c Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Tue, 5 Jul 2022 13:17:10 +0200 Subject: [PATCH 03/10] add deletion of jobs handle unavailable videos --- ucast/tasks/download.py | 49 +++++++++++++++++++----- ucast/tasks/library.py | 11 ++++-- ucast/templates/ucast/downloads.html | 14 ++++++- ucast/templates/ucast/error_details.html | 7 +++- ucast/tests/tasks/test_download.py | 36 ++++++++++++++++- ucast/tests/tasks/test_library.py | 4 +- ucast/urls.py | 10 +++++ ucast/views.py | 24 +++++++++++- 8 files changed, 133 insertions(+), 22 deletions(-) diff --git a/ucast/tasks/download.py b/ucast/tasks/download.py index be14ddb..3122e90 100644 --- a/ucast/tasks/download.py +++ b/ucast/tasks/download.py @@ -3,6 +3,7 @@ import os from django.db.models import ObjectDoesNotExist from django.utils import timezone +from yt_dlp.utils import DownloadError from ucast import queue from ucast.models import Channel, Video @@ -21,7 +22,25 @@ def _load_scraped_video(vid: youtube.VideoScraped, channel: Channel): try: video = Video.objects.get(video_id=vid.id) except ObjectDoesNotExist: - details = youtube.get_video_details(vid.id) + try: + details = youtube.get_video_details(vid.id) + except DownloadError as e: + if "available" in e.msg: + # Create dummy video to prevent further download attempts + # of unavailable videos + video = Video( + video_id=vid.id, + title="", + slug="", + channel=channel, + published=timezone.datetime(2000, 1, 1, tzinfo=timezone.utc), + description="", + duration=0, + is_deleted=True, + ) + video.save() + return + raise e # Dont load active livestreams if details.is_currently_live: @@ -50,20 +69,20 @@ def _load_scraped_video(vid: youtube.VideoScraped, channel: Channel): and video.is_deleted is False and channel.should_download(video) ): - queue.enqueue(download_video, video) + queue.enqueue(download_video, video.id) redis.delete(lock_key) -def download_video(video: Video): +def download_video(v_id: int): """ Download a video including its thumbnail, create a cover image and store everything in the channel folder. - :param video: Video object + :param v_id: Video ID """ # Return if the video was already downloaded by a previous task - video.refresh_from_db() + video = Video.objects.get(id=v_id) if video.downloaded: return @@ -71,7 +90,14 @@ def download_video(video: Video): channel_folder = store.get_or_create_channel_folder(video.channel.slug) audio_file = channel_folder.get_audio(video.slug) - details = youtube.download_audio(video.video_id, audio_file) + try: + details = youtube.download_audio(video.video_id, audio_file) + except DownloadError as e: + if "available" in e.msg: + video.is_deleted = True + video.save() + return + raise e # Download/convert thumbnails tn_path = channel_folder.get_thumbnail(video.slug) @@ -106,8 +132,9 @@ def download_video(video: Video): video.save() -def update_channel(channel: Channel): +def update_channel(c_id: int): """Update a single channel from its RSS feed""" + channel = Channel.objects.get(id=c_id) videos = youtube.get_channel_videos_from_feed(channel.channel_id) for vid in videos: @@ -123,18 +150,20 @@ def update_channels(): This task is scheduled a regular intervals. """ for channel in Channel.objects.filter(active=True): - queue.enqueue(update_channel, channel) + queue.enqueue(update_channel, channel.id) -def download_channel(channel: Channel, limit: int): +def download_channel(c_id: int, limit: int): """ Download maximum number of videos from a channel. - :param channel: Channel object + :param c_id: Channel ID (Database) :param limit: Max number of videos """ if limit < 1: return + channel = Channel.objects.get(id=c_id) + for vid in youtube.get_channel_videos_from_scraper(channel.channel_id, limit): _load_scraped_video(vid, channel) diff --git a/ucast/tasks/library.py b/ucast/tasks/library.py index b6b3481..3b0241e 100644 --- a/ucast/tasks/library.py +++ b/ucast/tasks/library.py @@ -7,7 +7,9 @@ from ucast.models import Channel, Video from ucast.service import cover, storage, util, videoutil, youtube -def recreate_cover(video: Video): +def recreate_cover(v_id: int): + video = Video.objects.get(id=v_id) + store = storage.Storage() cf = store.get_channel_folder(video.channel.slug) @@ -42,7 +44,7 @@ def recreate_cover(video: Video): def recreate_covers(): for video in Video.objects.filter(downloaded__isnull=False): - queue.enqueue(recreate_cover, video) + queue.enqueue(recreate_cover, video.id) def update_file_storage(): @@ -81,7 +83,8 @@ def update_file_storage(): video.save() -def update_channel_info(channel: Channel): +def update_channel_info(ch_id: int): + channel = Channel.objects.get(id=ch_id) channel_data = youtube.get_channel_metadata( youtube.channel_url_from_id(channel.channel_id) ) @@ -104,4 +107,4 @@ def update_channel_info(channel: Channel): def update_channel_infos(): for channel in Channel.objects.filter(active=True): - queue.enqueue(update_channel_info, channel) + queue.enqueue(update_channel_info, channel.id) diff --git a/ucast/templates/ucast/downloads.html b/ucast/templates/ucast/downloads.html index 9cbe830..9f51790 100644 --- a/ucast/templates/ucast/downloads.html +++ b/ucast/templates/ucast/downloads.html @@ -27,11 +27,15 @@
{% if failed_jobs %} -
+
{% csrf_token %}
+
+ {% csrf_token %} + +
@@ -41,6 +45,7 @@ + @@ -56,6 +61,13 @@ + {% endfor %} diff --git a/ucast/templates/ucast/error_details.html b/ucast/templates/ucast/error_details.html index 04f89fa..4928008 100644 --- a/ucast/templates/ucast/error_details.html +++ b/ucast/templates/ucast/error_details.html @@ -16,12 +16,17 @@ {{ job.exc_info }} -
+
{% csrf_token %} +
+ {% csrf_token %} + + +
{% endblock content %} diff --git a/ucast/tests/tasks/test_download.py b/ucast/tests/tasks/test_download.py index dc6fd6c..8d12f27 100644 --- a/ucast/tests/tasks/test_download.py +++ b/ucast/tests/tasks/test_download.py @@ -1,21 +1,24 @@ import os import pytest +from django.utils import timezone from ucast import queue, tests from ucast.models import Channel, Video from ucast.service import storage +from ucast.service.youtube import VideoScraped from ucast.tasks import download CHANNEL_ID_THETADEV = "UCGiJh0NZ52wRhYKYnuZI08Q" VIDEO_ID_INTRO = "I0RRENheeTo" VIDEO_SLUG_INTRO = "20211010_No_copyright_intro_free_fire_intro_no_text_free_copy_right_free_templates_free_download" +VIDEO_ID_UNAVAILABLE = "K6CBuTy09CE" @pytest.mark.django_db def test_download_video(download_dir, rq_queue): video = Video.objects.get(video_id=VIDEO_ID_INTRO) - job = queue.enqueue(download.download_video, video) + job = queue.enqueue(download.download_video, video.id) store = storage.Storage() cf = store.get_or_create_channel_folder(video.channel.slug) @@ -28,6 +31,35 @@ def test_download_video(download_dir, rq_queue): assert os.path.isfile(cf.get_thumbnail(VIDEO_SLUG_INTRO, True)) +@pytest.mark.django_db +def test_load_unavailable_video(download_dir, rq_queue, mock_redis): + channel = Channel.objects.get(channel_id=CHANNEL_ID_THETADEV) + download._load_scraped_video(VideoScraped(VIDEO_ID_UNAVAILABLE, None), channel) + + video = Video.objects.get(video_id=VIDEO_ID_UNAVAILABLE) + assert video.is_deleted is True + + +@pytest.mark.django_db +def test_download_unavailable_video(download_dir, rq_queue): + channel = Channel.objects.get(channel_id=CHANNEL_ID_THETADEV) + video = Video( + video_id=VIDEO_ID_UNAVAILABLE, + title="", + slug="", + channel=channel, + published=timezone.datetime(2000, 1, 1, tzinfo=timezone.utc), + description="", + duration=0, + ) + video.save() + job = queue.enqueue(download.download_video, video.id) + video.refresh_from_db() + + assert job.is_finished + assert video.is_deleted + + @pytest.mark.django_db def test_update_channel( download_dir, rq_queue, mock_redis, mock_get_video_details, mock_download_audio @@ -37,7 +69,7 @@ def test_update_channel( Video.objects.get(video_id="_I5IFObm_-k").delete() channel = Channel.objects.get(channel_id=CHANNEL_ID_THETADEV) - job = rq_queue.enqueue(download.update_channel, channel) + job = rq_queue.enqueue(download.update_channel, channel.id) assert job.is_finished mock_download_audio.assert_any_call( diff --git a/ucast/tests/tasks/test_library.py b/ucast/tests/tasks/test_library.py index ddbc605..19b213b 100644 --- a/ucast/tests/tasks/test_library.py +++ b/ucast/tests/tasks/test_library.py @@ -19,7 +19,7 @@ def test_recreate_cover(download_dir_content_mut, rq_queue, mocker): store = storage.Storage() cf = store.get_or_create_channel_folder(video.channel.slug) - job = rq_queue.enqueue(library.recreate_cover, video) + job = rq_queue.enqueue(library.recreate_cover, video.id) assert job.is_finished create_cover_mock.assert_called_once_with( @@ -53,7 +53,7 @@ def test_update_channel_info(rq_queue, mock_get_channel_metadata): channel.avatar_url = "Old avatar url" channel.save() - job = rq_queue.enqueue(library.update_channel_info, channel) + job = rq_queue.enqueue(library.update_channel_info, channel.id) assert job.is_finished channel.refresh_from_db() diff --git a/ucast/urls.py b/ucast/urls.py index 327f61d..35fbc2d 100644 --- a/ucast/urls.py +++ b/ucast/urls.py @@ -28,6 +28,16 @@ urlpatterns = [ views.download_errors_requeue_all, name="download_errors_requeue_all", ), + path( + "downloads/delete", + views.download_errors_delete, + name="download_errors_delete", + ), + path( + "downloads/delete_all", + views.download_errors_delete_all, + name="download_errors_delete_all", + ), path("downloads/error/", views.error_details, name="error_details"), path("feed/", views.podcast_feed, name="feed"), path("opml", views.channels_opml, name="channels_opml"), diff --git a/ucast/views.py b/ucast/views.py index 415dd9f..c4d9d76 100644 --- a/ucast/views.py +++ b/ucast/views.py @@ -33,7 +33,7 @@ def home(request: http.HttpRequest): channel_str = form.cleaned_data["channel_str"] try: channel = controller.create_channel(channel_str) - queue.enqueue(download.update_channel, channel) + queue.enqueue(download.update_channel, channel.id) except ValueError: form.add_error("channel_str", "Channel URL invalid") except controller.ChannelAlreadyExistsException: @@ -139,7 +139,7 @@ def channel_download(request: http.HttpRequest, channel: str): form = forms.DownloadChannelForm(request.POST) if form.is_valid(): queue.enqueue( - download.download_channel, chan, form.cleaned_data["n_videos"] + download.download_channel, chan.id, form.cleaned_data["n_videos"] ) return http.HttpResponseRedirect(reverse(videos, args=[channel])) @@ -204,6 +204,26 @@ def download_errors_requeue_all(request: http.HttpRequest): return http.HttpResponseRedirect(reverse(downloads)) +@login_required +def download_errors_delete(request: http.HttpRequest): + form = forms.RequeueForm(request.POST) + + if form.is_valid(): + freg = queue.get_failed_job_registry() + freg.remove(str(form.cleaned_data["id"]), delete_job=True) + + return http.HttpResponseRedirect(reverse(downloads)) + + +@login_required +def download_errors_delete_all(request: http.HttpRequest): + freg = queue.get_failed_job_registry() + for job_id in freg.get_job_ids(): + freg.remove(job_id, delete_job=True) + + return http.HttpResponseRedirect(reverse(downloads)) + + @login_required def channels_opml(request: http.HttpRequest): response = http.HttpResponse( From 9d53d79f9591f85ebf0ee90ee0764ce277198820 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Tue, 5 Jul 2022 13:33:20 +0200 Subject: [PATCH 04/10] show number of pending videos --- ucast/tasks/download.py | 15 ++++++-- ucast/tasks/library.py | 12 +++++- ucast/templates/ucast/videos.html | 61 +++++++++++++++++++------------ ucast/views.py | 5 +++ 4 files changed, 65 insertions(+), 28 deletions(-) diff --git a/ucast/tasks/download.py b/ucast/tasks/download.py index 3122e90..d3bbe81 100644 --- a/ucast/tasks/download.py +++ b/ucast/tasks/download.py @@ -82,7 +82,10 @@ def download_video(v_id: int): :param v_id: Video ID """ # Return if the video was already downloaded by a previous task - video = Video.objects.get(id=v_id) + try: + video = Video.objects.get(id=v_id) + except ObjectDoesNotExist: + return if video.downloaded: return @@ -134,7 +137,10 @@ def download_video(v_id: int): def update_channel(c_id: int): """Update a single channel from its RSS feed""" - channel = Channel.objects.get(id=c_id) + try: + channel = Channel.objects.get(id=c_id) + except ObjectDoesNotExist: + return videos = youtube.get_channel_videos_from_feed(channel.channel_id) for vid in videos: @@ -163,7 +169,10 @@ def download_channel(c_id: int, limit: int): if limit < 1: return - channel = Channel.objects.get(id=c_id) + try: + channel = Channel.objects.get(id=c_id) + except ObjectDoesNotExist: + return for vid in youtube.get_channel_videos_from_scraper(channel.channel_id, limit): _load_scraped_video(vid, channel) diff --git a/ucast/tasks/library.py b/ucast/tasks/library.py index 3b0241e..797ea49 100644 --- a/ucast/tasks/library.py +++ b/ucast/tasks/library.py @@ -1,5 +1,6 @@ import os +from django.db.models import ObjectDoesNotExist from django.utils import timezone from ucast import queue @@ -8,7 +9,10 @@ from ucast.service import cover, storage, util, videoutil, youtube def recreate_cover(v_id: int): - video = Video.objects.get(id=v_id) + try: + video = Video.objects.get(id=v_id) + except ObjectDoesNotExist: + return store = storage.Storage() cf = store.get_channel_folder(video.channel.slug) @@ -84,7 +88,11 @@ def update_file_storage(): def update_channel_info(ch_id: int): - channel = Channel.objects.get(id=ch_id) + try: + channel = Channel.objects.get(id=ch_id) + except ObjectDoesNotExist: + return + channel_data = youtube.get_channel_metadata( youtube.channel_url_from_id(channel.channel_id) ) diff --git a/ucast/templates/ucast/videos.html b/ucast/templates/ucast/videos.html index d43569c..a491a8b 100644 --- a/ucast/templates/ucast/videos.html +++ b/ucast/templates/ucast/videos.html @@ -13,7 +13,11 @@   {{ channel.subscribers }}   {{ videos.paginator.count }} + class="fas fa-video">  {{ videos.paginator.count }} + {% if n_pending %} + ({{ n_pending }}) + {% endif %} +   {{ channel.download_size|filesizeformat }}
-
+
- @@ -60,28 +65,38 @@
-
- {% if not videos %} -

No videos

+ {% if not videos %} + {% if n_pending %} +

There are {{ n_pending }} videos waiting to be downloaded. + Please wait a few minutes and refesh this page. + You can see the current status in the Downloads tab. +

+ {% else %} +

No videos. If you have just added this channel, + you have to wait a minute for ucast to start looking for videos.

{% endif %} - {% include "ucast/videos_items.html" %} -
+ {% else %} +
+ {% include "ucast/videos_items.html" %} +
+ {% endif %} {% if videos.has_previous or videos.has_next %} - + {% endif %} {% endblock content %} diff --git a/ucast/views.py b/ucast/views.py index c4d9d76..0850a17 100644 --- a/ucast/views.py +++ b/ucast/views.py @@ -91,6 +91,10 @@ def videos(request: http.HttpRequest, channel: str): if request.htmx: template_name = "ucast/videos_items.html" + n_pending = Video.objects.filter( + channel=chan, downloaded__isnull=True, is_deleted=False + ).count() + return render( request, template_name, @@ -98,6 +102,7 @@ def videos(request: http.HttpRequest, channel: str): "videos": videos_p.get_page(page_number), "channel": chan, "site_url": site_url, + "n_pending": n_pending, }, ) From 3479365c525502cb9b0a73c9b83f99a07e1d5d56 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Tue, 5 Jul 2022 13:56:07 +0200 Subject: [PATCH 05/10] publish docker images with ci --- .drone.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.drone.yml b/.drone.yml index ebe4a65..297b7c6 100644 --- a/.drone.yml +++ b/.drone.yml @@ -36,6 +36,27 @@ steps: depends_on: - install dependencies + - name: build container + image: quay.io/buildah/stable + when: + event: + - tag + commands: + - buildah login -u $DOCKER_USER -p $DOCKER_PASS -- $DOCKER_REGISTRY + - buildah manifest create ucast + - buildah bud --tag code.thetadev.de/hsa/ucast:latest --manifest ucast --arch amd64 -f deploy/Dockerfile . + - buildah bud --tag code.thetadev.de/hsa/ucast:latest --manifest ucast --arch arm64 -f deploy/Dockerfile . + - buildah manifest push --all ucast docker://code.thetadev.de/hsa/ucast:latest + environment: + DOCKER_REGISTRY: + from_secret: docker_registry + DOCKER_USER: + from_secret: docker_username + DOCKER_PASS: + from_secret: docker_password + depends_on: + - test + volumes: - name: cache temp: { } From 86cbe478a65cef68527fc4944e92da7e952c2a98 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Tue, 5 Jul 2022 13:57:07 +0200 Subject: [PATCH 06/10] =?UTF-8?q?Bump=20version:=200.3.1=20=E2=86=92=200.4?= =?UTF-8?q?.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- pyproject.toml | 2 +- ucast/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 02482c5..e592fa8 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.3.1 +current_version = 0.4.0 commit = True tag = True diff --git a/pyproject.toml b/pyproject.toml index 96ab12a..7ead845 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "ucast" -version = "0.3.1" +version = "0.4.0" description = "YouTube to Podcast converter" authors = ["Theta-Dev "] packages = [ diff --git a/ucast/__init__.py b/ucast/__init__.py index 521568f..7907732 100644 --- a/ucast/__init__.py +++ b/ucast/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.3.1" +__version__ = "0.4.0" def template_context(request): From e4e3c890b1cc3947039c2b1496beb1dab8c44bda Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Tue, 5 Jul 2022 14:10:45 +0200 Subject: [PATCH 07/10] remove docker build step --- .drone.yml | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/.drone.yml b/.drone.yml index 297b7c6..5c94ab7 100644 --- a/.drone.yml +++ b/.drone.yml @@ -36,26 +36,26 @@ steps: depends_on: - install dependencies - - name: build container - image: quay.io/buildah/stable - when: - event: - - tag - commands: - - buildah login -u $DOCKER_USER -p $DOCKER_PASS -- $DOCKER_REGISTRY - - buildah manifest create ucast - - buildah bud --tag code.thetadev.de/hsa/ucast:latest --manifest ucast --arch amd64 -f deploy/Dockerfile . - - buildah bud --tag code.thetadev.de/hsa/ucast:latest --manifest ucast --arch arm64 -f deploy/Dockerfile . - - buildah manifest push --all ucast docker://code.thetadev.de/hsa/ucast:latest - environment: - DOCKER_REGISTRY: - from_secret: docker_registry - DOCKER_USER: - from_secret: docker_username - DOCKER_PASS: - from_secret: docker_password - depends_on: - - test +# - name: build container +# image: quay.io/buildah/stable +# when: +# event: +# - tag +# commands: +# - buildah login -u $DOCKER_USER -p $DOCKER_PASS -- $DOCKER_REGISTRY +# - buildah manifest create ucast +# - buildah bud --tag code.thetadev.de/hsa/ucast:latest --manifest ucast --arch amd64 -f deploy/Dockerfile . +# - buildah bud --tag code.thetadev.de/hsa/ucast:latest --manifest ucast --arch arm64 -f deploy/Dockerfile . +# - buildah manifest push --all ucast docker://code.thetadev.de/hsa/ucast:latest +# environment: +# DOCKER_REGISTRY: +# from_secret: docker_registry +# DOCKER_USER: +# from_secret: docker_username +# DOCKER_PASS: +# from_secret: docker_password +# depends_on: +# - test volumes: - name: cache From 1e59cd70ae4caf29ed4e18448215859ef462b2a6 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Tue, 5 Jul 2022 14:19:14 +0200 Subject: [PATCH 08/10] add global docker urls --- deploy/Devcontainer.Dockerfile | 2 +- deploy/Dockerfile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/Devcontainer.Dockerfile b/deploy/Devcontainer.Dockerfile index 571102f..8b84e2c 100644 --- a/deploy/Devcontainer.Dockerfile +++ b/deploy/Devcontainer.Dockerfile @@ -1,5 +1,5 @@ # This has to be built with docker buildx to set the TARGETPLATFORM argument -FROM python:3.10 +FROM registry.hub.docker.com/library/python:3.10 ARG TARGETPLATFORM diff --git a/deploy/Dockerfile b/deploy/Dockerfile index b22b23d..167dec3 100644 --- a/deploy/Dockerfile +++ b/deploy/Dockerfile @@ -1,11 +1,11 @@ -FROM thetadev256/ucast-dev +FROM registry.hub.docker.com/thetadev256/ucast-dev COPY . /build WORKDIR /build RUN poetry build -f wheel -FROM python:3.10 +FROM registry.hub.docker.com/library/python:3.10 ARG TARGETPLATFORM COPY --from=0 /build/dist /install From 0e93d361915f2a92ebdef552106d93f745614d51 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Tue, 5 Jul 2022 14:54:53 +0200 Subject: [PATCH 09/10] update dependencies --- poetry.lock | 379 +++++++++++++++++++++++++++---------------------- pyproject.toml | 6 +- 2 files changed, 212 insertions(+), 173 deletions(-) diff --git a/poetry.lock b/poetry.lock index dedcf83..aa2c218 100644 --- a/poetry.lock +++ b/poetry.lock @@ -68,7 +68,7 @@ python-versions = ">=3.5" [[package]] name = "certifi" -version = "2022.5.18.1" +version = "2022.6.15" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false @@ -76,7 +76,7 @@ python-versions = ">=3.6" [[package]] name = "cffi" -version = "1.15.0" +version = "1.15.1" description = "Foreign Function Interface for Python calling C code." category = "main" optional = false @@ -95,11 +95,11 @@ python-versions = ">=3.6.1" [[package]] name = "charset-normalizer" -version = "2.0.12" +version = "2.1.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false -python-versions = ">=3.5.0" +python-versions = ">=3.6.0" [package.extras] unicode_backport = ["unicodedata2"] @@ -117,7 +117,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "colorama" -version = "0.4.4" +version = "0.4.5" description = "Cross-platform colored terminal text." category = "main" optional = false @@ -183,7 +183,7 @@ python-versions = "*" [[package]] name = "django" -version = "4.0.4" +version = "4.0.6" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." category = "main" optional = false @@ -222,14 +222,14 @@ Django = ">=3.2" [[package]] name = "fakeredis" -version = "1.8" +version = "1.8.1" description = "Fake implementation of redis API for testing purposes." category = "dev" optional = false python-versions = ">=3.7,<4.0" [package.dependencies] -redis = "<=4.3.1" +redis = "<4.4" six = ">=1.16.0,<2.0.0" sortedcontainers = ">=2.4.0,<3.0.0" @@ -250,7 +250,7 @@ sgmllib3k = "*" [[package]] name = "filelock" -version = "3.7.0" +version = "3.7.1" description = "A platform independent file lock." category = "dev" optional = false @@ -349,7 +349,7 @@ python-versions = ">=3.5, <4" [[package]] name = "mysqlclient" -version = "2.1.0" +version = "2.1.1" description = "Python interface to MySQL" category = "main" optional = false @@ -357,11 +357,11 @@ python-versions = ">=3.5" [[package]] name = "nodeenv" -version = "1.6.0" +version = "1.7.0" description = "Node.js virtual environment builder" category = "dev" optional = false -python-versions = "*" +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" [[package]] name = "packaging" @@ -376,14 +376,14 @@ pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" [[package]] name = "pillow" -version = "9.1.1" +version = "9.2.0" description = "Python Imaging Library (Fork)" category = "main" optional = false python-versions = ">=3.7" [package.extras] -docs = ["olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinx-rtd-theme (>=1.0)", "sphinxext-opengraph"] +docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinxext-opengraph"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] [[package]] @@ -452,7 +452,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pycryptodomex" -version = "3.14.1" +version = "3.15.0" description = "Cryptographic library for Python" category = "main" optional = false @@ -522,7 +522,7 @@ testing = ["django", "django-configurations (>=2.0)"] [[package]] name = "pytest-mock" -version = "3.7.0" +version = "3.8.2" description = "Thin-wrapper around the mock package for easier use with pytest" category = "dev" optional = false @@ -580,7 +580,7 @@ python-versions = ">=3.6" [[package]] name = "redis" -version = "4.3.1" +version = "4.3.4" description = "Python client for Redis database and key-value store" category = "main" optional = false @@ -597,21 +597,21 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" [[package]] name = "requests" -version = "2.27.1" +version = "2.28.1" description = "Python HTTP for Humans." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=3.7, <4" [package.dependencies] certifi = ">=2017.4.17" -charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} -idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} +charset-normalizer = ">=2,<3" +idna = ">=2.5,<4" urllib3 = ">=1.21.1,<1.27" [package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rq" @@ -717,7 +717,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "virtualenv" -version = "20.14.1" +version = "20.15.1" description = "Virtual Python Environment builder" category = "dev" optional = false @@ -759,7 +759,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [[package]] name = "yt-dlp" -version = "2022.5.18" +version = "2022.6.29" description = "A youtube-dl fork with additional features and patches" category = "main" optional = false @@ -776,7 +776,7 @@ websockets = "*" [metadata] lock-version = "1.1" python-versions = "^3.10" -content-hash = "41be11c588a5d47c4ddc2e06b5699ee9db0c3888e3576c0134d55e065f53cc0d" +content-hash = "f582f6abb81e647dd6874bb00768645e574c3c4c85ee366d9cd74b675717e216" [metadata.files] asgiref = [ @@ -896,76 +896,90 @@ bump2version = [ {file = "bump2version-1.0.1.tar.gz", hash = "sha256:762cb2bfad61f4ec8e2bdf452c7c267416f8c70dd9ecb1653fd0bbb01fa936e6"}, ] certifi = [ - {file = "certifi-2022.5.18.1-py3-none-any.whl", hash = "sha256:f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a"}, - {file = "certifi-2022.5.18.1.tar.gz", hash = "sha256:9c5705e395cd70084351dd8ad5c41e65655e08ce46f2ec9cf6c2c08390f71eb7"}, + {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"}, + {file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"}, ] cffi = [ - {file = "cffi-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962"}, - {file = "cffi-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0"}, - {file = "cffi-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14"}, - {file = "cffi-1.15.0-cp27-cp27m-win32.whl", hash = "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474"}, - {file = "cffi-1.15.0-cp27-cp27m-win_amd64.whl", hash = "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6"}, - {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27"}, - {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023"}, - {file = "cffi-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2"}, - {file = "cffi-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e"}, - {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7"}, - {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3"}, - {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c"}, - {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962"}, - {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382"}, - {file = "cffi-1.15.0-cp310-cp310-win32.whl", hash = "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55"}, - {file = "cffi-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0"}, - {file = "cffi-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e"}, - {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39"}, - {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc"}, - {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032"}, - {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8"}, - {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605"}, - {file = "cffi-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e"}, - {file = "cffi-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc"}, - {file = "cffi-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636"}, - {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4"}, - {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997"}, - {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b"}, - {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2"}, - {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7"}, - {file = "cffi-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66"}, - {file = "cffi-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029"}, - {file = "cffi-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880"}, - {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20"}, - {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024"}, - {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e"}, - {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728"}, - {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6"}, - {file = "cffi-1.15.0-cp38-cp38-win32.whl", hash = "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c"}, - {file = "cffi-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443"}, - {file = "cffi-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a"}, - {file = "cffi-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37"}, - {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a"}, - {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e"}, - {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796"}, - {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df"}, - {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8"}, - {file = "cffi-1.15.0-cp39-cp39-win32.whl", hash = "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a"}, - {file = "cffi-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139"}, - {file = "cffi-1.15.0.tar.gz", hash = "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954"}, + {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, ] cfgv = [ {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, ] charset-normalizer = [ - {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, - {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, + {file = "charset-normalizer-2.1.0.tar.gz", hash = "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"}, + {file = "charset_normalizer-2.1.0-py3-none-any.whl", hash = "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5"}, ] click = [ {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, ] colorama = [ - {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, - {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, + {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, + {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, ] colorthief = [ {file = "colorthief-0.2.1-py2.py3-none-any.whl", hash = "sha256:b04fc8ce5cf9c888768745e29cb19b7b688d5711af6fba26e8057debabec56b9"}, @@ -1027,8 +1041,8 @@ distlib = [ {file = "distlib-0.3.4.zip", hash = "sha256:e4b58818180336dc9c529bfb9a0b58728ffc09ad92027a3f30b7cd91e3458579"}, ] django = [ - {file = "Django-4.0.4-py3-none-any.whl", hash = "sha256:07c8638e7a7f548dc0acaaa7825d84b7bd42b10e8d22268b3d572946f1e9b687"}, - {file = "Django-4.0.4.tar.gz", hash = "sha256:4e8177858524417563cc0430f29ea249946d831eacb0068a1455686587df40b5"}, + {file = "Django-4.0.6-py3-none-any.whl", hash = "sha256:ca54ebedfcbc60d191391efbf02ba68fb52165b8bf6ccd6fe71f098cac1fe59e"}, + {file = "Django-4.0.6.tar.gz", hash = "sha256:a67a793ff6827fd373555537dca0da293a63a316fe34cb7f367f898ccca3c3ae"}, ] django-bulma = [ {file = "django-bulma-0.8.3.tar.gz", hash = "sha256:b794b4e64f482de77f376451f7cd8b3c8448eb68e5a24c51b9190625a08b0b30"}, @@ -1039,16 +1053,16 @@ django-htmx = [ {file = "django_htmx-1.12.0-py3-none-any.whl", hash = "sha256:e8351b9251642a5a550a18c6958727ea9b33574bb412b1900fa5ab0d5dd9db40"}, ] fakeredis = [ - {file = "fakeredis-1.8-py3-none-any.whl", hash = "sha256:65dcd78c0cd29d17daccce9f58698f6ab61ad7a404eab373fcad2b76fe8db03d"}, - {file = "fakeredis-1.8.tar.gz", hash = "sha256:cbf8d74ae06672d40b2fa88b9ee4f1d6efd56b06b2e7f0be2c639647f00643f1"}, + {file = "fakeredis-1.8.1-py3-none-any.whl", hash = "sha256:4a0f8fe0d5c18147864db50ae2e86f667420ea06653bec08b3a5fccfd3fbde6f"}, + {file = "fakeredis-1.8.1.tar.gz", hash = "sha256:ca516f86181f85615cd8210854b43acbe7b1f37ed8a082c5557749c73f2f0dd3"}, ] feedparser = [ {file = "feedparser-6.0.10-py3-none-any.whl", hash = "sha256:79c257d526d13b944e965f6095700587f27388e50ea16fd245babe4dfae7024f"}, {file = "feedparser-6.0.10.tar.gz", hash = "sha256:27da485f4637ce7163cdeab13a80312b93b7d0c1b775bef4a47629a3110bca51"}, ] filelock = [ - {file = "filelock-3.7.0-py3-none-any.whl", hash = "sha256:c7b5fdb219b398a5b28c8e4c1893ef5f98ece6a38c6ab2c22e26ec161556fed6"}, - {file = "filelock-3.7.0.tar.gz", hash = "sha256:b795f1b42a61bbf8ec7113c341dad679d772567b936fbd1bf43c9a238e673e20"}, + {file = "filelock-3.7.1-py3-none-any.whl", hash = "sha256:37def7b658813cda163b56fc564cdc75e86d338246458c4c28ae84cabefa2404"}, + {file = "filelock-3.7.1.tar.gz", hash = "sha256:3a0fd85166ad9dbab54c9aec96737b744106dc5f15c0b09a6744a445299fcf04"}, ] font-source-sans-pro = [ {file = "font-source-sans-pro-0.0.1.tar.gz", hash = "sha256:3f81d8e52b0d7e930e2c867c0d3ee549312d03f97b71b664a8361006311f72e5"}, @@ -1089,59 +1103,81 @@ mutagen = [ {file = "mutagen-1.45.1.tar.gz", hash = "sha256:6397602efb3c2d7baebd2166ed85731ae1c1d475abca22090b7141ff5034b3e1"}, ] mysqlclient = [ - {file = "mysqlclient-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:02c8826e6add9b20f4cb12dcf016485f7b1d6e30356a1204d05431867a1b3947"}, - {file = "mysqlclient-2.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:b62d23c11c516cedb887377c8807628c1c65d57593b57853186a6ee18b0c6a5b"}, - {file = "mysqlclient-2.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:2c8410f54492a3d2488a6a53e2d85b7e016751a1e7d116e7aea9c763f59f5e8c"}, - {file = "mysqlclient-2.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:e6279263d5a9feca3e0edbc2b2a52c057375bf301d47da2089c075ff76331d14"}, - {file = "mysqlclient-2.1.0.tar.gz", hash = "sha256:973235686f1b720536d417bf0a0d39b4ab3d5086b2b6ad5e6752393428c02b12"}, + {file = "mysqlclient-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:c1ed71bd6244993b526113cca3df66428609f90e4652f37eb51c33496d478b37"}, + {file = "mysqlclient-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:c812b67e90082a840efb82a8978369e6e69fc62ce1bda4ca8f3084a9d862308b"}, + {file = "mysqlclient-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:0d1cd3a5a4d28c222fa199002810e8146cffd821410b67851af4cc80aeccd97c"}, + {file = "mysqlclient-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:b355c8b5a7d58f2e909acdbb050858390ee1b0e13672ae759e5e784110022994"}, + {file = "mysqlclient-2.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:996924f3483fd36a34a5812210c69e71dea5a3d5978d01199b78b7f6d485c855"}, + {file = "mysqlclient-2.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:dea88c8d3f5a5d9293dfe7f087c16dd350ceb175f2f6631c9cf4caf3e19b7a96"}, + {file = "mysqlclient-2.1.1.tar.gz", hash = "sha256:828757e419fb11dd6c5ed2576ec92c3efaa93a0f7c39e263586d1ee779c3d782"}, ] nodeenv = [ - {file = "nodeenv-1.6.0-py2.py3-none-any.whl", hash = "sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"}, - {file = "nodeenv-1.6.0.tar.gz", hash = "sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b"}, + {file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"}, + {file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"}, ] packaging = [ {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, ] pillow = [ - {file = "Pillow-9.1.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:42dfefbef90eb67c10c45a73a9bc1599d4dac920f7dfcbf4ec6b80cb620757fe"}, - {file = "Pillow-9.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ffde4c6fabb52891d81606411cbfaf77756e3b561b566efd270b3ed3791fde4e"}, - {file = "Pillow-9.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c857532c719fb30fafabd2371ce9b7031812ff3889d75273827633bca0c4602"}, - {file = "Pillow-9.1.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:59789a7d06c742e9d13b883d5e3569188c16acb02eeed2510fd3bfdbc1bd1530"}, - {file = "Pillow-9.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d45dbe4b21a9679c3e8b3f7f4f42a45a7d3ddff8a4a16109dff0e1da30a35b2"}, - {file = "Pillow-9.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e9ed59d1b6ee837f4515b9584f3d26cf0388b742a11ecdae0d9237a94505d03a"}, - {file = "Pillow-9.1.1-cp310-cp310-win32.whl", hash = "sha256:b3fe2ff1e1715d4475d7e2c3e8dabd7c025f4410f79513b4ff2de3d51ce0fa9c"}, - {file = "Pillow-9.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:5b650dbbc0969a4e226d98a0b440c2f07a850896aed9266b6fedc0f7e7834108"}, - {file = "Pillow-9.1.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:0b4d5ad2cd3a1f0d1df882d926b37dbb2ab6c823ae21d041b46910c8f8cd844b"}, - {file = "Pillow-9.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9370d6744d379f2de5d7fa95cdbd3a4d92f0b0ef29609b4b1687f16bc197063d"}, - {file = "Pillow-9.1.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b761727ed7d593e49671d1827044b942dd2f4caae6e51bab144d4accf8244a84"}, - {file = "Pillow-9.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a66fe50386162df2da701b3722781cbe90ce043e7d53c1fd6bd801bca6b48d4"}, - {file = "Pillow-9.1.1-cp37-cp37m-win32.whl", hash = "sha256:2b291cab8a888658d72b575a03e340509b6b050b62db1f5539dd5cd18fd50578"}, - {file = "Pillow-9.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:1d4331aeb12f6b3791911a6da82de72257a99ad99726ed6b63f481c0184b6fb9"}, - {file = "Pillow-9.1.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8844217cdf66eabe39567118f229e275f0727e9195635a15e0e4b9227458daaf"}, - {file = "Pillow-9.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b6617221ff08fbd3b7a811950b5c3f9367f6e941b86259843eab77c8e3d2b56b"}, - {file = "Pillow-9.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20d514c989fa28e73a5adbddd7a171afa5824710d0ab06d4e1234195d2a2e546"}, - {file = "Pillow-9.1.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:088df396b047477dd1bbc7de6e22f58400dae2f21310d9e2ec2933b2ef7dfa4f"}, - {file = "Pillow-9.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53c27bd452e0f1bc4bfed07ceb235663a1df7c74df08e37fd6b03eb89454946a"}, - {file = "Pillow-9.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3f6c1716c473ebd1649663bf3b42702d0d53e27af8b64642be0dd3598c761fb1"}, - {file = "Pillow-9.1.1-cp38-cp38-win32.whl", hash = "sha256:c67db410508b9de9c4694c57ed754b65a460e4812126e87f5052ecf23a011a54"}, - {file = "Pillow-9.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:f054b020c4d7e9786ae0404278ea318768eb123403b18453e28e47cdb7a0a4bf"}, - {file = "Pillow-9.1.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:c17770a62a71718a74b7548098a74cd6880be16bcfff5f937f900ead90ca8e92"}, - {file = "Pillow-9.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f3f6a6034140e9e17e9abc175fc7a266a6e63652028e157750bd98e804a8ed9a"}, - {file = "Pillow-9.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f372d0f08eff1475ef426344efe42493f71f377ec52237bf153c5713de987251"}, - {file = "Pillow-9.1.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09e67ef6e430f90caa093528bd758b0616f8165e57ed8d8ce014ae32df6a831d"}, - {file = "Pillow-9.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66daa16952d5bf0c9d5389c5e9df562922a59bd16d77e2a276e575d32e38afd1"}, - {file = "Pillow-9.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d78ca526a559fb84faaaf84da2dd4addef5edb109db8b81677c0bb1aad342601"}, - {file = "Pillow-9.1.1-cp39-cp39-win32.whl", hash = "sha256:55e74faf8359ddda43fee01bffbc5bd99d96ea508d8a08c527099e84eb708f45"}, - {file = "Pillow-9.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:7c150dbbb4a94ea4825d1e5f2c5501af7141ea95825fadd7829f9b11c97aaf6c"}, - {file = "Pillow-9.1.1-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:769a7f131a2f43752455cc72f9f7a093c3ff3856bf976c5fb53a59d0ccc704f6"}, - {file = "Pillow-9.1.1-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:488f3383cf5159907d48d32957ac6f9ea85ccdcc296c14eca1a4e396ecc32098"}, - {file = "Pillow-9.1.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b525a356680022b0af53385944026d3486fc8c013638cf9900eb87c866afb4c"}, - {file = "Pillow-9.1.1-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6e760cf01259a1c0a50f3c845f9cad1af30577fd8b670339b1659c6d0e7a41dd"}, - {file = "Pillow-9.1.1-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4165205a13b16a29e1ac57efeee6be2dfd5b5408122d59ef2145bc3239fa340"}, - {file = "Pillow-9.1.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:937a54e5694684f74dcbf6e24cc453bfc5b33940216ddd8f4cd8f0f79167f765"}, - {file = "Pillow-9.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:baf3be0b9446a4083cc0c5bb9f9c964034be5374b5bc09757be89f5d2fa247b8"}, - {file = "Pillow-9.1.1.tar.gz", hash = "sha256:7502539939b53d7565f3d11d87c78e7ec900d3c72945d4ee0e2f250d598309a0"}, + {file = "Pillow-9.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:a9c9bc489f8ab30906d7a85afac4b4944a572a7432e00698a7239f44a44e6efb"}, + {file = "Pillow-9.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:510cef4a3f401c246cfd8227b300828715dd055463cdca6176c2e4036df8bd4f"}, + {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7888310f6214f19ab2b6df90f3f06afa3df7ef7355fc025e78a3044737fab1f5"}, + {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831e648102c82f152e14c1a0938689dbb22480c548c8d4b8b248b3e50967b88c"}, + {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cc1d2451e8a3b4bfdb9caf745b58e6c7a77d2e469159b0d527a4554d73694d1"}, + {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:136659638f61a251e8ed3b331fc6ccd124590eeff539de57c5f80ef3a9594e58"}, + {file = "Pillow-9.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:6e8c66f70fb539301e064f6478d7453e820d8a2c631da948a23384865cd95544"}, + {file = "Pillow-9.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:37ff6b522a26d0538b753f0b4e8e164fdada12db6c6f00f62145d732d8a3152e"}, + {file = "Pillow-9.2.0-cp310-cp310-win32.whl", hash = "sha256:c79698d4cd9318d9481d89a77e2d3fcaeff5486be641e60a4b49f3d2ecca4e28"}, + {file = "Pillow-9.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:254164c57bab4b459f14c64e93df11eff5ded575192c294a0c49270f22c5d93d"}, + {file = "Pillow-9.2.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:408673ed75594933714482501fe97e055a42996087eeca7e5d06e33218d05aa8"}, + {file = "Pillow-9.2.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:727dd1389bc5cb9827cbd1f9d40d2c2a1a0c9b32dd2261db522d22a604a6eec9"}, + {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50dff9cc21826d2977ef2d2a205504034e3a4563ca6f5db739b0d1026658e004"}, + {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb6259196a589123d755380b65127ddc60f4c64b21fc3bb46ce3a6ea663659b0"}, + {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b0554af24df2bf96618dac71ddada02420f946be943b181108cac55a7a2dcd4"}, + {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:15928f824870535c85dbf949c09d6ae7d3d6ac2d6efec80f3227f73eefba741c"}, + {file = "Pillow-9.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:bdd0de2d64688ecae88dd8935012c4a72681e5df632af903a1dca8c5e7aa871a"}, + {file = "Pillow-9.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5b87da55a08acb586bad5c3aa3b86505f559b84f39035b233d5bf844b0834b1"}, + {file = "Pillow-9.2.0-cp311-cp311-win32.whl", hash = "sha256:b6d5e92df2b77665e07ddb2e4dbd6d644b78e4c0d2e9272a852627cdba0d75cf"}, + {file = "Pillow-9.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6bf088c1ce160f50ea40764f825ec9b72ed9da25346216b91361eef8ad1b8f8c"}, + {file = "Pillow-9.2.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:2c58b24e3a63efd22554c676d81b0e57f80e0a7d3a5874a7e14ce90ec40d3069"}, + {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eef7592281f7c174d3d6cbfbb7ee5984a671fcd77e3fc78e973d492e9bf0eb3f"}, + {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dcd7b9c7139dc8258d164b55696ecd16c04607f1cc33ba7af86613881ffe4ac8"}, + {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a138441e95562b3c078746a22f8fca8ff1c22c014f856278bdbdd89ca36cff1b"}, + {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:93689632949aff41199090eff5474f3990b6823404e45d66a5d44304e9cdc467"}, + {file = "Pillow-9.2.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:f3fac744f9b540148fa7715a435d2283b71f68bfb6d4aae24482a890aed18b59"}, + {file = "Pillow-9.2.0-cp37-cp37m-win32.whl", hash = "sha256:fa768eff5f9f958270b081bb33581b4b569faabf8774726b283edb06617101dc"}, + {file = "Pillow-9.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:69bd1a15d7ba3694631e00df8de65a8cb031911ca11f44929c97fe05eb9b6c1d"}, + {file = "Pillow-9.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:030e3460861488e249731c3e7ab59b07c7853838ff3b8e16aac9561bb345da14"}, + {file = "Pillow-9.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:74a04183e6e64930b667d321524e3c5361094bb4af9083db5c301db64cd341f3"}, + {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d33a11f601213dcd5718109c09a52c2a1c893e7461f0be2d6febc2879ec2402"}, + {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fd6f5e3c0e4697fa7eb45b6e93996299f3feee73a3175fa451f49a74d092b9f"}, + {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a647c0d4478b995c5e54615a2e5360ccedd2f85e70ab57fbe817ca613d5e63b8"}, + {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:4134d3f1ba5f15027ff5c04296f13328fecd46921424084516bdb1b2548e66ff"}, + {file = "Pillow-9.2.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:bc431b065722a5ad1dfb4df354fb9333b7a582a5ee39a90e6ffff688d72f27a1"}, + {file = "Pillow-9.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1536ad017a9f789430fb6b8be8bf99d2f214c76502becc196c6f2d9a75b01b76"}, + {file = "Pillow-9.2.0-cp38-cp38-win32.whl", hash = "sha256:2ad0d4df0f5ef2247e27fc790d5c9b5a0af8ade9ba340db4a73bb1a4a3e5fb4f"}, + {file = "Pillow-9.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:ec52c351b35ca269cb1f8069d610fc45c5bd38c3e91f9ab4cbbf0aebc136d9c8"}, + {file = "Pillow-9.2.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ed2c4ef2451de908c90436d6e8092e13a43992f1860275b4d8082667fbb2ffc"}, + {file = "Pillow-9.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ad2f835e0ad81d1689f1b7e3fbac7b01bb8777d5a985c8962bedee0cc6d43da"}, + {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea98f633d45f7e815db648fd7ff0f19e328302ac36427343e4432c84432e7ff4"}, + {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7761afe0126d046974a01e030ae7529ed0ca6a196de3ec6937c11df0df1bc91c"}, + {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a54614049a18a2d6fe156e68e188da02a046a4a93cf24f373bffd977e943421"}, + {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:5aed7dde98403cd91d86a1115c78d8145c83078e864c1de1064f52e6feb61b20"}, + {file = "Pillow-9.2.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:13b725463f32df1bfeacbf3dd197fb358ae8ebcd8c5548faa75126ea425ccb60"}, + {file = "Pillow-9.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:808add66ea764ed97d44dda1ac4f2cfec4c1867d9efb16a33d158be79f32b8a4"}, + {file = "Pillow-9.2.0-cp39-cp39-win32.whl", hash = "sha256:337a74fd2f291c607d220c793a8135273c4c2ab001b03e601c36766005f36885"}, + {file = "Pillow-9.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:fac2d65901fb0fdf20363fbd345c01958a742f2dc62a8dd4495af66e3ff502a4"}, + {file = "Pillow-9.2.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:ad2277b185ebce47a63f4dc6302e30f05762b688f8dc3de55dbae4651872cdf3"}, + {file = "Pillow-9.2.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c7b502bc34f6e32ba022b4a209638f9e097d7a9098104ae420eb8186217ebbb"}, + {file = "Pillow-9.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d1f14f5f691f55e1b47f824ca4fdcb4b19b4323fe43cc7bb105988cad7496be"}, + {file = "Pillow-9.2.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:dfe4c1fedfde4e2fbc009d5ad420647f7730d719786388b7de0999bf32c0d9fd"}, + {file = "Pillow-9.2.0-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:f07f1f00e22b231dd3d9b9208692042e29792d6bd4f6639415d2f23158a80013"}, + {file = "Pillow-9.2.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1802f34298f5ba11d55e5bb09c31997dc0c6aed919658dfdf0198a2fe75d5490"}, + {file = "Pillow-9.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17d4cafe22f050b46d983b71c707162d63d796a1235cdf8b9d7a112e97b15bac"}, + {file = "Pillow-9.2.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:96b5e6874431df16aee0c1ba237574cb6dff1dcb173798faa6a9d8b399a05d0e"}, + {file = "Pillow-9.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:0030fdbd926fb85844b8b92e2f9449ba89607231d3dd597a21ae72dc7fe26927"}, + {file = "Pillow-9.2.0.tar.gz", hash = "sha256:75e636fd3e0fb872693f23ccb8a5ff2cd578801251f3a4f6854c6a5d437d3c04"}, ] platformdirs = [ {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, @@ -1177,33 +1213,36 @@ pycparser = [ {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, ] pycryptodomex = [ - {file = "pycryptodomex-3.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca88f2f7020002638276439a01ffbb0355634907d1aa5ca91f3dc0c2e44e8f3b"}, - {file = "pycryptodomex-3.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:8536bc08d130cae6dcba1ea689f2913dfd332d06113904d171f2f56da6228e89"}, - {file = "pycryptodomex-3.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:406ec8cfe0c098fadb18d597dc2ee6de4428d640c0ccafa453f3d9b2e58d29e2"}, - {file = "pycryptodomex-3.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:da8db8374295fb532b4b0c467e66800ef17d100e4d5faa2bbbd6df35502da125"}, - {file = "pycryptodomex-3.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:d709572d64825d8d59ea112e11cc7faf6007f294e9951324b7574af4251e4de8"}, - {file = "pycryptodomex-3.14.1-cp27-cp27m-win32.whl", hash = "sha256:3da13c2535b7aea94cc2a6d1b1b37746814c74b6e80790daddd55ca5c120a489"}, - {file = "pycryptodomex-3.14.1-cp27-cp27m-win_amd64.whl", hash = "sha256:298c00ea41a81a491d5b244d295d18369e5aac4b61b77b2de5b249ca61cd6659"}, - {file = "pycryptodomex-3.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:77931df40bb5ce5e13f4de2bfc982b2ddc0198971fbd947776c8bb5050896eb2"}, - {file = "pycryptodomex-3.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:c5dd3ffa663c982d7f1be9eb494a8924f6d40e2e2f7d1d27384cfab1b2ac0662"}, - {file = "pycryptodomex-3.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:2aa887683eee493e015545bd69d3d21ac8d5ad582674ec98f4af84511e353e45"}, - {file = "pycryptodomex-3.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:8085bd0ad2034352eee4d4f3e2da985c2749cb7344b939f4d95ead38c2520859"}, - {file = "pycryptodomex-3.14.1-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:e95a4a6c54d27a84a4624d2af8bb9ee178111604653194ca6880c98dcad92f48"}, - {file = "pycryptodomex-3.14.1-cp35-abi3-manylinux1_i686.whl", hash = "sha256:a4d412eba5679ede84b41dbe48b1bed8f33131ab9db06c238a235334733acc5e"}, - {file = "pycryptodomex-3.14.1-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:d2cce1c82a7845d7e2e8a0956c6b7ed3f1661c9acf18eb120fc71e098ab5c6fe"}, - {file = "pycryptodomex-3.14.1-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:f75009715dcf4a3d680c2338ab19dac5498f8121173a929872950f4fb3a48fbf"}, - {file = "pycryptodomex-3.14.1-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:1ca8e1b4c62038bb2da55451385246f51f412c5f5eabd64812c01766a5989b4a"}, - {file = "pycryptodomex-3.14.1-cp35-abi3-win32.whl", hash = "sha256:ee835def05622e0c8b1435a906491760a43d0c462f065ec9143ec4b8d79f8bff"}, - {file = "pycryptodomex-3.14.1-cp35-abi3-win_amd64.whl", hash = "sha256:b5a185ae79f899b01ca49f365bdf15a45d78d9856f09b0de1a41b92afce1a07f"}, - {file = "pycryptodomex-3.14.1-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:797a36bd1f69df9e2798e33edb4bd04e5a30478efc08f9428c087f17f65a7045"}, - {file = "pycryptodomex-3.14.1-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:aebecde2adc4a6847094d3bd6a8a9538ef3438a5ea84ac1983fcb167db614461"}, - {file = "pycryptodomex-3.14.1-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:f8524b8bc89470cec7ac51734907818d3620fb1637f8f8b542d650ebec42a126"}, - {file = "pycryptodomex-3.14.1-pp27-pypy_73-win32.whl", hash = "sha256:4d0db8df9ffae36f416897ad184608d9d7a8c2b46c4612c6bc759b26c073f750"}, - {file = "pycryptodomex-3.14.1-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b276cc4deb4a80f9dfd47a41ebb464b1fe91efd8b1b8620cf5ccf8b824b850d6"}, - {file = "pycryptodomex-3.14.1-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:e36c7e3b5382cd5669cf199c4a04a0279a43b2a3bdd77627e9b89778ac9ec08c"}, - {file = "pycryptodomex-3.14.1-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:c4d8977ccda886d88dc3ca789de2f1adc714df912ff3934b3d0a3f3d777deafb"}, - {file = "pycryptodomex-3.14.1-pp36-pypy36_pp73-win32.whl", hash = "sha256:530756d2faa40af4c1f74123e1d889bd07feae45bac2fd32f259a35f7aa74151"}, - {file = "pycryptodomex-3.14.1.tar.gz", hash = "sha256:2ce76ed0081fd6ac8c74edc75b9d14eca2064173af79843c24fa62573263c1f2"}, + {file = "pycryptodomex-3.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:6f5b6ba8aefd624834bc177a2ac292734996bb030f9d1b388e7504103b6fcddf"}, + {file = "pycryptodomex-3.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:4540904c09704b6f831059c0dfb38584acb82cb97b0125cd52688c1f1e3fffa6"}, + {file = "pycryptodomex-3.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:0fadb9f7fa3150577800eef35f62a8a24b9ddf1563ff060d9bd3af22d3952c8c"}, + {file = "pycryptodomex-3.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:fc9bc7a9b79fe5c750fc81a307052f8daabb709bdaabb0fb18fb136b66b653b5"}, + {file = "pycryptodomex-3.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:f8be976cec59b11f011f790b88aca67b4ea2bd286578d0bd3e31bcd19afcd3e4"}, + {file = "pycryptodomex-3.15.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:78d9621cf0ea35abf2d38fa2ca6d0634eab6c991a78373498ab149953787e5e5"}, + {file = "pycryptodomex-3.15.0-cp27-cp27m-win32.whl", hash = "sha256:b6306403228edde6e289f626a3908a2f7f67c344e712cf7c0a508bab3ad9e381"}, + {file = "pycryptodomex-3.15.0-cp27-cp27m-win_amd64.whl", hash = "sha256:48697790203909fab02a33226fda546604f4e2653f9d47bc5d3eb40879fa7c64"}, + {file = "pycryptodomex-3.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:18e2ab4813883ae63396c0ffe50b13554b32bb69ec56f0afaf052e7a7ae0d55b"}, + {file = "pycryptodomex-3.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:3709f13ca3852b0b07fc04a2c03b379189232b24007c466be0f605dd4723e9d4"}, + {file = "pycryptodomex-3.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:191e73bc84a8064ad1874dba0ebadedd7cce4dedee998549518f2c74a003b2e1"}, + {file = "pycryptodomex-3.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:e3164a18348bd53c69b4435ebfb4ac8a4076291ffa2a70b54f0c4b80c7834b1d"}, + {file = "pycryptodomex-3.15.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:5676a132169a1c1a3712edf25250722ebc8c9102aa9abd814df063ca8362454f"}, + {file = "pycryptodomex-3.15.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:e2b12968522a0358b8917fc7b28865acac002f02f4c4c6020fcb264d76bfd06d"}, + {file = "pycryptodomex-3.15.0-cp35-abi3-manylinux1_i686.whl", hash = "sha256:e47bf8776a7e15576887f04314f5228c6527b99946e6638cf2f16da56d260cab"}, + {file = "pycryptodomex-3.15.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:996e1ba717077ce1e6d4849af7a1426f38b07b3d173b879e27d5e26d2e958beb"}, + {file = "pycryptodomex-3.15.0-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:65204412d0c6a8e3c41e21e93a5e6054a74fea501afa03046a388cf042e3377a"}, + {file = "pycryptodomex-3.15.0-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:dd452a5af7014e866206d41751886c9b4bf379a339fdf2dbfc7dd16c0fb4f8e0"}, + {file = "pycryptodomex-3.15.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:b9279adc16e4b0f590ceff581f53a80179b02cba9056010d733eb4196134a870"}, + {file = "pycryptodomex-3.15.0-cp35-abi3-win32.whl", hash = "sha256:46b3f05f2f7ac7841053da4e0f69616929ca3c42f238c405f6c3df7759ad2780"}, + {file = "pycryptodomex-3.15.0-cp35-abi3-win_amd64.whl", hash = "sha256:8eecdf9cdc7343001d047f951b9cc805cd68cb6cd77b20ea46af5bffc5bd3dfb"}, + {file = "pycryptodomex-3.15.0-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:67e1e6a92151023ccdfcfbc0afb3314ad30080793b4c27956ea06ab1fb9bcd8a"}, + {file = "pycryptodomex-3.15.0-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:c4cb9cb492ea7dcdf222a8d19a1d09002798ea516aeae8877245206d27326d86"}, + {file = "pycryptodomex-3.15.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:94c7b60e1f52e1a87715571327baea0733708ab4723346598beca4a3b6879794"}, + {file = "pycryptodomex-3.15.0-pp27-pypy_73-win32.whl", hash = "sha256:04cc393045a8f19dd110c975e30f38ed7ab3faf21ede415ea67afebd95a22380"}, + {file = "pycryptodomex-3.15.0-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0776bfaf2c48154ab54ea45392847c1283d2fcf64e232e85565f858baedfc1fa"}, + {file = "pycryptodomex-3.15.0-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:463119d7d22d0fc04a0f9122e9d3e6121c6648bcb12a052b51bd1eed1b996aa2"}, + {file = "pycryptodomex-3.15.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:a07a64709e366c2041cd5cfbca592b43998bf4df88f7b0ca73dca37071ccf1bd"}, + {file = "pycryptodomex-3.15.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:35a8f7afe1867118330e2e0e0bf759c409e28557fb1fc2fbb1c6c937297dbe9a"}, + {file = "pycryptodomex-3.15.0.tar.gz", hash = "sha256:7341f1bb2dadb0d1a0047f34c3a58208a92423cdbd3244d998e4b28df5eac0ed"}, ] pyparsing = [ {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, @@ -1222,8 +1261,8 @@ pytest-django = [ {file = "pytest_django-4.5.2-py3-none-any.whl", hash = "sha256:c60834861933773109334fe5a53e83d1ef4828f2203a1d6a0fa9972f4f75ab3e"}, ] pytest-mock = [ - {file = "pytest-mock-3.7.0.tar.gz", hash = "sha256:5112bd92cc9f186ee96e1a92efc84969ea494939c3aead39c50f421c4cc69534"}, - {file = "pytest_mock-3.7.0-py3-none-any.whl", hash = "sha256:6cff27cec936bf81dc5ee87f07132b807bcda51106b5ec4b90a04331cba76231"}, + {file = "pytest-mock-3.8.2.tar.gz", hash = "sha256:77f03f4554392558700295e05aed0b1096a20d4a60a4f3ddcde58b0c31c8fca2"}, + {file = "pytest_mock-3.8.2-py3-none-any.whl", hash = "sha256:8a9e226d6c0ef09fcf20c94eb3405c388af438a90f3e39687f84166da82d5948"}, ] python-dateutil = [ {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, @@ -1273,12 +1312,12 @@ pyyaml = [ {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] redis = [ - {file = "redis-4.3.1-py3-none-any.whl", hash = "sha256:84316970995a7adb907a56754d2b92d88fc2d252963dc5ac34c88f0f1a22c25d"}, - {file = "redis-4.3.1.tar.gz", hash = "sha256:94b617b4cd296e94991146f66fc5559756fbefe9493604f0312e4d3298ac63e9"}, + {file = "redis-4.3.4-py3-none-any.whl", hash = "sha256:a52d5694c9eb4292770084fa8c863f79367ca19884b329ab574d5cb2036b3e54"}, + {file = "redis-4.3.4.tar.gz", hash = "sha256:ddf27071df4adf3821c4f2ca59d67525c3a82e5f268bed97b813cb4fabf87880"}, ] requests = [ - {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, - {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, + {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, + {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, ] rq = [ {file = "rq-1.10.1-py2.py3-none-any.whl", hash = "sha256:92f4cf38b2364c1697b541e77c0fe62b7e5242fa864324f262be126ee2a07e3a"}, @@ -1324,8 +1363,8 @@ urllib3 = [ {file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, ] virtualenv = [ - {file = "virtualenv-20.14.1-py2.py3-none-any.whl", hash = "sha256:e617f16e25b42eb4f6e74096b9c9e37713cf10bf30168fb4a739f3fa8f898a3a"}, - {file = "virtualenv-20.14.1.tar.gz", hash = "sha256:ef589a79795589aada0c1c5b319486797c03b67ac3984c48c669c0e4f50df3a5"}, + {file = "virtualenv-20.15.1-py2.py3-none-any.whl", hash = "sha256:b30aefac647e86af6d82bfc944c556f8f1a9c90427b2fb4e3bfbf338cb82becf"}, + {file = "virtualenv-20.15.1.tar.gz", hash = "sha256:288171134a2ff3bfb1a2f54f119e77cd1b81c29fc1265a2356f3e8d14c7d58c4"}, ] wcag-contrast-ratio = [ {file = "wcag-contrast-ratio-0.9.tar.gz", hash = "sha256:69192b8e5c0a7d0dc5ff1187eeb3e398141633a4bde51c69c87f58fe87ed361c"}, @@ -1447,6 +1486,6 @@ wrapt = [ {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, ] yt-dlp = [ - {file = "yt-dlp-2022.5.18.tar.gz", hash = "sha256:3a7b59d2fb4b39ce8ba8e0b9c5a37fe20e5624f46a2346b4ae66ab1320e35134"}, - {file = "yt_dlp-2022.5.18-py2.py3-none-any.whl", hash = "sha256:deec1009442312c1e2ee5298966842194d0e950b433f0d4fc844ef464b9c32a7"}, + {file = "yt-dlp-2022.6.29.tar.gz", hash = "sha256:5fbfac72fd035d11bc2693e5d1cd6933b1bc0712f742f5082a261703810bb5c9"}, + {file = "yt_dlp-2022.6.29-py2.py3-none-any.whl", hash = "sha256:a688f5cbc4a824456983774ccdd4a12befd379f6c92e25074fa85e7b8ce31704"}, ] diff --git a/pyproject.toml b/pyproject.toml index 7ead845..f5d3ea6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,8 +11,8 @@ packages = [ [tool.poetry.dependencies] python = "^3.10" Django = "^4.0.4" -yt-dlp = "^2022.3.8" -requests = "^2.27.1" +yt-dlp = "^2022.6.29" +requests = "^2.28.1" feedparser = "^6.0.8" Pillow = "^9.1.0" colorthief = "^0.2.1" @@ -22,7 +22,7 @@ fonts = "^0.0.3" django-bulma = "^0.8.3" python-dotenv = "^0.20.0" psycopg2 = "^2.9.3" -mysqlclient = "^2.1.0" +mysqlclient = "^2.1.1" python-slugify = "^6.1.2" mutagen = "^1.45.1" rq = "^1.10.1" From fb6d8308975d789b3fe2c7a54bc52cc921249a9c Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Tue, 5 Jul 2022 14:55:08 +0200 Subject: [PATCH 10/10] =?UTF-8?q?Bump=20version:=200.4.0=20=E2=86=92=200.4?= =?UTF-8?q?.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- pyproject.toml | 2 +- ucast/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index e592fa8..60b03ad 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.4.0 +current_version = 0.4.1 commit = True tag = True diff --git a/pyproject.toml b/pyproject.toml index f5d3ea6..99ae662 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "ucast" -version = "0.4.0" +version = "0.4.1" description = "YouTube to Podcast converter" authors = ["Theta-Dev "] packages = [ diff --git a/ucast/__init__.py b/ucast/__init__.py index 7907732..c1f2c55 100644 --- a/ucast/__init__.py +++ b/ucast/__init__.py @@ -1,4 +1,4 @@ -__version__ = "0.4.0" +__version__ = "0.4.1" def template_context(request):
Function Details RequeueDelete
+
+ {% csrf_token %} + + +
+