From 215a6ac3318ac3fc0b6b52cc0bd57b8a0d918114 Mon Sep 17 00:00:00 2001 From: bkfox Date: Mon, 9 Sep 2019 02:47:57 +0200 Subject: [PATCH] work on pages, filters, lists --- aircox/admin/article.py | 7 +- aircox/admin/episode.py | 10 +- aircox/admin/page.py | 4 +- aircox/converters.py | 10 +- .../__pycache__/__init__.cpython-37.pyc | Bin 577 -> 577 bytes .../models/__pycache__/episode.cpython-37.pyc | Bin 10052 -> 10253 bytes aircox/models/__pycache__/log.cpython-37.pyc | Bin 8961 -> 8961 bytes aircox/models/__pycache__/page.cpython-37.pyc | Bin 6177 -> 6545 bytes .../models/__pycache__/program.cpython-37.pyc | Bin 16813 -> 17012 bytes .../models/__pycache__/sound.cpython-37.pyc | Bin 8981 -> 8981 bytes .../models/__pycache__/station.cpython-37.pyc | Bin 4691 -> 4691 bytes aircox/models/article.py | 14 +-- aircox/models/episode.py | 26 +++--- aircox/models/page.py | 19 +++- aircox/models/program.py | 32 +++---- aircox/models/signals.py | 2 +- aircox/static/aircox/admin.css | 31 +++++++ aircox/static/aircox/admin.js | 2 +- aircox/static/aircox/main.css | 28 ++++++ aircox/templates/admin/aircox/statistics.html | 13 ++- aircox/templates/admin/base.html | 4 +- aircox/templates/aircox/article_detail.html | 6 +- aircox/templates/aircox/base.html | 38 +++++++- aircox/templates/aircox/diffusion_item.html | 11 +++ aircox/templates/aircox/diffusion_list.html | 23 +++-- aircox/templates/aircox/log_item.html | 4 +- aircox/templates/aircox/log_list.html | 19 ++-- aircox/templates/aircox/page_list.html | 86 +++++++++--------- aircox/templates/aircox/program_base.html | 36 +++----- aircox/templates/aircox/track_item.html | 6 +- .../templates/aircox/widgets/dates_menu.html | 59 ++++++------ aircox/urls.py | 31 ++++--- aircox/views/__init__.py | 2 +- aircox/views/admin.py | 3 + aircox/views/article.py | 6 +- aircox/views/base.py | 29 +++--- aircox/views/episode.py | 22 +---- aircox/views/log.py | 6 +- aircox/views/mixins.py | 20 ++-- aircox/views/page.py | 8 +- aircox/views/program.py | 25 ++--- assets/admin/admin.scss | 6 ++ assets/admin/statistics.vue | 1 - assets/public/styles.scss | 47 +++++++++- requirements.txt | 3 +- 45 files changed, 424 insertions(+), 275 deletions(-) create mode 100644 aircox/templates/aircox/diffusion_item.html diff --git a/aircox/admin/article.py b/aircox/admin/article.py index b8248d2..4a08dc9 100644 --- a/aircox/admin/article.py +++ b/aircox/admin/article.py @@ -11,11 +11,8 @@ __all__ = ['ArticleAdmin'] @admin.register(Article) class ArticleAdmin(PageAdmin): - list_display = PageAdmin.list_display + ('program',) - list_filter = PageAdmin.list_filter + ('program',) - search_fields = PageAdmin.search_fields + ['program__title'] + list_filter = PageAdmin.list_filter + search_fields = PageAdmin.search_fields + ['parent__title'] # TODO: readonly field - fieldsets = copy.deepcopy(PageAdmin.fieldsets) - fieldsets[1][1]['fields'].insert(0, 'program') diff --git a/aircox/admin/episode.py b/aircox/admin/episode.py index b41ce2f..9e91d44 100644 --- a/aircox/admin/episode.py +++ b/aircox/admin/episode.py @@ -48,13 +48,11 @@ class DiffusionInline(DiffusionBaseAdmin, admin.TabularInline): @admin.register(Episode) class EpisodeAdmin(PageAdmin): - list_display = PageAdmin.list_display + ('program',) - list_filter = PageAdmin.list_filter + ('program',) - search_fields = PageAdmin.search_fields + ['program__title'] - readonly_fields = ('program',) + list_display = PageAdmin.list_display + list_filter = PageAdmin.list_filter + search_fields = PageAdmin.search_fields + ['parent__title'] + # readonly_fields = ('parent',) - fieldsets = copy.deepcopy(PageAdmin.fieldsets) - fieldsets[1][1]['fields'].insert(0, 'program') inlines = [TracksInline, SoundInline, DiffusionInline] diff --git a/aircox/admin/page.py b/aircox/admin/page.py index 6cb5bc1..a139f5c 100644 --- a/aircox/admin/page.py +++ b/aircox/admin/page.py @@ -21,7 +21,7 @@ class CategoryAdmin(admin.ModelAdmin): # limit category choice class PageAdmin(admin.ModelAdmin): - list_display = ('cover_thumb', 'title', 'status', 'category') + list_display = ('cover_thumb', 'title', 'status', 'category', 'parent') list_display_links = ('cover_thumb', 'title') list_editable = ('status', 'category') list_filter = ('status', 'category') @@ -33,7 +33,7 @@ class PageAdmin(admin.ModelAdmin): 'fields': ['title', 'slug', 'category', 'cover', 'content'], }), (_('Publication Settings'), { - 'fields': ['featured', 'allow_comments', 'status'], + 'fields': ['featured', 'allow_comments', 'status', 'parent'], 'classes': ('collapse',), }), ] diff --git a/aircox/converters.py b/aircox/converters.py index 6b3d422..f4030dd 100644 --- a/aircox/converters.py +++ b/aircox/converters.py @@ -33,7 +33,8 @@ class WeekConverter: return datetime.datetime.strptime(value + '/1', '%G/%V/%u').date() def to_url(self, value): - return '{:04d}/{:02d}'.format(*value.isocalendar()) + return value if isinstance(value, str) else \ + '{:04d}/{:02d}'.format(*value.isocalendar()) class DateConverter: @@ -41,8 +42,9 @@ class DateConverter: regex = r'[0-9]{4}/[0-9]{2}/[0-9]{2}' def to_python(self, value): - return str_to_date(value) + value = value.split('/')[:3] + return datetime.date(int(value[0]), int(value[1]), int(value[2])) def to_url(self, value): - return '{:04d}/{:02d}/{:02d}'.format(value.year, value.month, - value.day) + return value if isinstance(value, str) else \ + '{:04d}/{:02d}/{:02d}'.format(value.year, value.month, value.day) diff --git a/aircox/models/__pycache__/__init__.cpython-37.pyc b/aircox/models/__pycache__/__init__.cpython-37.pyc index f6e2bd5eea87e8f353d1dfdf16ebfa4f4bdbf863..cfebf4589f8fe46688fe920d8efcc3e05df60534 100644 GIT binary patch delta 20 acmX@ea*&1FiIe*muXnxn+T$jU`=CwZkkodZ#DqEyHi0f}hw|{&L}~i=#8iWK4l?;+tEqJU^l+AL6F z2{mYR->4+yI!5ELPO>)IF84{=wjTv4u+x-E3M@+T6e!+l+hq;Mt5bH8GT(OGos8}9 zYW>csL$u}iY;$7W-*l@4=<&lDqcID^YXjgbca;r7!GpaJNLCjDz0vg4R0Dkt`>~i(XLd6vN(G>(JMD8#gC-7TR3#pd4u{l>7j>81RV;-n zppz_^gm(kZRCy0fLHL&KZZWB%2~Y*^1dxMqsH+M~{KR}{QN+~YbU>^iaf|Vly2q@V zy~)H+LZ2oD@#oML(kaep`LL8OUez*WNZi(Dc25I4cn?!YwWVR$mdNlg9>aXNgz8>13v)b<(NSJ-!a zm+?;V`|#&UNjw=D9T`VSPar@6pA#~B&RJI%tm*mB zfv-KHnCUbk^_m5RF)hwT-z_3-U{J^Nom$loj5?=`TPxe9CU1hzik?_LjA=S2o{#ZtMtg`oPsu)f;QPp)3jq>sbpv;?Si?F zcGDi1v#g)?(u{1gIav46tXvPUJng4BxgG@k0L{yFfez9F@D*v14#7M`OLQ3K5}lxB zI=W9P!*q;}nt&Ri80cD<857RUi)lnMp~?;hzc z!2WwMya)iS9z*2?@uTiHt{v5k%!HkAVeGYgW)S9#Z`Dklp9FeYQnD!oakpNzUCZ-r z?(+#a3v{RE_>S#zREZr~?DrJO1M&TyyB%LVV#dmC6<8wX*|(S_HM}d9df&>+fT&G1 zk}|?8k66XOdP@XLvp^n-napw$10qAyk{C1S7Pozf$}hxwnb!+4ccGk-?pQftIsWS4 z)xH=>V^IWA>5#0{X|bKn_5ClVF979l4t|_XlU`X#D=1i6QH52@ig;6&#cK4o;-mg| z;&`|GJc23ltz1$1&?(-}8RUb5-{o@TQ%DeK4clK|#;0->8m6fSVXwYbquh~)E_9wC z2JfmRu^vAw#`DD_S_xfcy8%h!Kxn#zn@^BG9&G35NE|t3V(|^}>%j|WIJV3{TLx+~ z6sQxEfrjrL?*lX#FUe(?u+e@TJBvE2_07h)e~K3ivnO2?CyC^JGTdSZ3Bs6yU=gfa zy{sXAUdXgdV%fE8aQ0X6hr;_g88}(hM@fD7e)DncKH|e-n*3Y*t@s17Aih16onAn( zBv2bS%&6?v{29PJ)xg4B;aD7;B3MUo69Ha3zl{K+&hH_>=y3F%pFtoK z4nZqGGGFjj_HbZn7-k+&ge2Y?X;=PgToRDLRlDhxG24u7E($*8GNER-5co&GOoM5-$Q delta 2914 zcmb7GU2Ggz6`ngYyR-k^AOGyG*FWpO^`zJhE#MG0PVBYQx@nUXyFY9Llj+`TXPxn` zb7$6#Q-cvUiV$toa$l;d;!m_y-zr&xzCff3As#BIctB;ODpEo4f_Onls1Lw7cjH|M zePLJo%{h0@x##DebMC%$@fYVy3-NeFfzNC2xnJ?d6y*=d9DM>noPnSF{wt+h<*oyT zcCkK|-q$O+hZUNnQCNwx-hHi-2R=pPz{goP@cqE2X$<%n%K%@XWJNJEul%VNNiEke z^2R#1H^n8gbw4?>5d(rL6+)GYDy3DwYiX=N zuHiDPZf~+13D$~ZiZaixIpRg_nLgePI=ly=7qyAS^Y9co{S+AxPwVIAa=4saXP#w0 z=Qf#Jhna z8^BwNr|v5o+Ai5uZxI4-AqaBb)cruU0giLD%!dKMhP};9jTa?j^L5t`UVR>)CgCF} z)-egyqnPk>g8&MNkchYwxYZ-W(5dY)Q}qL0&2t#fiEjp-BSNhhr)GMtOdvJioZa`+;l4k`Zf$ImicaVF&?z z^`kOvo6Nh?pnOVvXbhP$B$+@wQjE>Ta|#ii1W8PTr<%}XfmlEchyFE!S>ZDPzFMQL zOmxzL>nFv0_*(u1iltC2y87jdOV)++*8K99Akv~J4rRohut83XKZk!xPKfVE@mI;7&r||W$|(3Cr_OM$_)A;%%fM^WE|55>1G2yNH11q}tsRmqz#kda0|ncj53iu`nU0#P8#UiL)r%QI#%8>#bsG zsg`Ac(}^HiJ^XwkMP_6e1`na~BMAS;HZOM>r#3dHO~PY`FTnNlY_(&4QO+foGO>(;j%{Sf2LMz5@kjL_g43nv-;a4bVL8m-Ha47wCYbhv*<30=;26OpEX= z(h)ie&k;IB$LYiYsf^MRorIOqF>2CdK#bF|%7h$F_tDS5a4N}BGzncieV9y7Xb;YS z<4|8XQ20rtHA(vhWovfR@qD9trBSOgm*au(#{k5)dS1`plRMc!a+89X?H%vI{`nsK zWQT_cd{sUmn!PulXm^4<_ZxxX$rrw6`T@>(vu+yv7+OK6WTX30r%|;X%k^yT@%v!e zH){2oSF;`2v!)82@pxa6ydfHWyXn=oGLDjV+a$A5awrPf7YAjuYHNQf668;Hbi^;S zqXavxTl_N{Bkzi6ZZ(b(%h=o7?d8Jc=i=MBuMf)_h2}&NSql>6P{5{p@354Qkh56& zepm(~`w_MLZk*QDCg-f~S-5oqGSV*#s3X6kEfW^2 z)8C4p6<&|xaq?M&89@h%GO|qAsJWI?+h!jf{%D{;$VqW~u#jaShcrfZ-d1+x&-rMXA6peL3W18$A=3;OC*X~vS|34`0nuH8Q%b1+w-`uuY$Cx`Rep> zU&o8h4{X~`69be=?L2)Fc?hjm8=G5me;3JOdFl#oDuv`}+Q`mJ4{9FU1fPIDnp=+e zMlstZg=Nz5HvfxwtN1}d=1I13yKJ#maI=z}G;fZi$S306k+;aB;__&I{!!eP`0CbG zGb|@Ce-MS`u#)q#y^n9O>s6;o8Q(^UGg9&Hfd2Jpf@tESQJY*Br^k9*1A0dqtdAv0 zTnqan+}0*4#AZIIW|&NFD|?!+9&g-^c&ci~lrK;z-yR7gVA z;X=BRUaYOHHQidHK5dD{c=VWg&jsllmPH#?FpHCnKY$<;Fe`pMKDvkP?Z@PmRDR^b za(QV*-l+UI%HjRTKZ}5o`Kgsn+i{lb9$RPpY>hco)`%ZpgbQgED!sMV32y*ZpG0^X z;aS`y1pkoWzl*oSF9EyPx+8-48k>P%MxY3r2zc(iiEtg^1q93&$87K~AjpbCfD-In z-FVergP)6IKa|p8Okuus75zL)NCKoY1Dv>BdSDQTV@QpWyI(CyvT9O`XlXq;l05Nm2@P)D diff --git a/aircox/models/__pycache__/log.cpython-37.pyc b/aircox/models/__pycache__/log.cpython-37.pyc index 55a125e82bfe5a96427b4ec166e79068deb2a4c6..0271250e3e0689b804c0c95dcbd4bb20cc18800b 100644 GIT binary patch delta 20 acmZp4Yjopw;^pOH0D|*Or5m}wDFFa5XayPo delta 20 acmZp4Yjopw;^pOH0D>jzB^$ZFDFFa56a^Ci diff --git a/aircox/models/__pycache__/page.cpython-37.pyc b/aircox/models/__pycache__/page.cpython-37.pyc index a02bef35810aa68f68b71cac33d7e55473016b24..1e1b87740006eb6433e214cb6545840cd3886c3a 100644 GIT binary patch delta 1954 zcmYjSO>7%Q6y8~{?e*H(IF6k(X@Z@kn>T-N-di6` zeRW2^)X||y@Z5U5ez)9vsQ;#D5il=8^Gf0`WwcYHDoyMXBSzzkQZe}~9sQncRnQ3^ zd}Et|<`n=oWlGjmp52sIrAxM{Ei%8m8cQ?Re-;I zumc~jA@cE=EtXhK(ggf8n%s*TDX=?eigxS~LkHf;;#A)up-1Ol#7KkI1zLKCFomhK z3$zSq8tVqkLQkgcouJ)&F(b!%+IqIF=k^q%mmLAm9#FP$>0X$m58V30WqS8y<0x1I z;Bo|9`e;8WgKgz#I1MVVu>5}EKr)8tfH6!5jS>0^&F@Oa=o4v~&;lLWRgEz^Oh-UF z#*WibI<_nA5aR^!WAu2)i|4>NL5rbrl8w`obUfq}Y?4mU$&ih~9Us+FGF0)*UBEapqV)qh`&jvcI<>@Q@ol@Z!D5 zW&SF>#GmS!1QLD*t)WDI3rW})#4B#ihjeTEhAx4+%q&PwM(1FQo3gBu#V@ zBQf!-wxC}D@n14hRQOxK#B0eJQWG1=2I1nLB#WZh5VupDG{r9|mz)yO@c%JBv zE-dwrs6CK3@chxAjQH@d5>Ji(e6)`U&!>cwN7n`5+v{Z=&b> z2v@{YeQ@w|psldWO+5_zGIy&c4lkY-&-LlvK$~+pvmey1vPVIDW_odE`tmG%Ci0zU z=Q-X*pf1iXndO`F^WheF5@!#0gx^|z9$h*vL#UP@RC6|SD8GnW>XPd^%&N7d3*yJl z(!F<~!^mKknb7K(@?pk@DZ(+j{3?!B>)fp~?my!5sA1svdk6^xj8%}VIF{#CnZM#v zj;H6h#8f&z{x;GALKgt$yoYnBL}~qGjc7!V=tL!=ksgZ^MOGszP3)%+$!T$;YXq*P z(N(x=yqJQ2h-?5M4D2W}1`ueoRm*l-=UYbg9;!;1K#3)`;kUZZ<0m(Ywe#gOk~v0V ztr8ZK-HWjr4trC4)_sXQ6+d@B?sIVp&GRkpdk<}Y1p&RL#FJE9 z{NeGbDmcAF{NrgSx5W$3%rW(ylANFUb^^>pwK}1Gcmt=dToAYraKSoZ3iHwsaADvg zED9I{Pq?Y})5xisYhm#wA8qonQze&RNl>;lnK;BqfvT0Y?X=SbWIpbIVJAqEAV~ow z=en9qt1}6iZr1ZCeJ01GJm=05`~nXqxt(NOh7M z2D^{;JN5;z2k4+6K%5EG zdpB9$s&Pi=4?=mvsO+Z;l~M`B=5m3603YlXXfx2vRsc#KNr%!7*^vQV)i|JXF2h3Q zm+OGKWVz6$$Vhb;ku0Sy?YIxgq5LHw5|tXO zlgGv~s#83!N}-qQaaVbB`8*W+(O@Q*Ny7eJC#5+D&V8hAIAh2aa*pHb{U(bTK8 z4WnpoGb+9a%n&Ai58Ne1(Hn}3Tfv*|S79=i9bVh zBY*|4?w3TMTw@(p&6WBF|F>fD;XyuP&LB;tOY@8rcR&8JWj zoXuNotyp67MP^W2whnApxw3C76nHx@U8xu>Uv`}Qnutcn7w2#;eoc-AGDK9oW_(gSjIXM@Xucu- zi%*kp#kIsyn}L%x6E1*d?ia0XxP^VFG4P{?gImnf;XvgJR`D+TPW+qbBMTy){8_Cu zL{F2;2kth3frUW@Q=`S8~!MzYSCc)hUjhEb^BxMG3|e> Crg7*1 diff --git a/aircox/models/__pycache__/program.cpython-37.pyc b/aircox/models/__pycache__/program.cpython-37.pyc index a9b7a105c6df9ff342cab301c74b2aaaffff72cb..07c00dd571dcd4a3720d0bb28d1346cb68e57c85 100644 GIT binary patch delta 4967 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 Sc&0p#veL56o<-B5$@4!D#4$kt delta 4935 zcmaJ^eQXrR6~DRL`?k#)8-ITsXB+!)Ap}GDHn#al_=x$iNx}uRtZ&Em!FkWjt_em_ zE{z=w38bZ?MnF=fRF!CwhR`^TXw(uyOVXwdNz_zThf1v!Rch6$YOA(?L`u~6X3uwr zb8x49JM(7d&3o_n-kaI~Op;e8NNZ1Valiq;^ViM&8+#m%Pq8!eQ=riWk9pus>z{WH zDX|6jIrMV9bkd=h()kmvSS$4B=^^NcXc+o!(67)dpuAEk4KB^q_(*O_AC^fJAC(if|u)!^9*IZ&fFNFS0|t?j#5ot#;x*Tc;EDTm^S zHS{^6jnn(wH^{F3SkWj;4KZy*9o2?t)G30a8l#4#CKJXXQN(Ccv#72b+6ZOnKA2H- zgtCE@NhMSGQ--S3B(PXvBSR$y2NSHiHOF5!$P87d*1ht0eI zK=2cbG zVygP&bYIB@LaOPj3$PRZFHQ?g>lw~1i=$UJ*iZZYKFZSgIy@* zxDjU<`y!y3D!&yzBKp1|qYf>vbm}23P z6a-gzSUZw1hQeAnXIgj=9T1LW!Z#AOQsD!|8HooLqa^;%GNW4-2A5qJWd5%K6=wk{ zopTON!_;?>a&oLXs~vx_e8)cF&Fm8;v0$dDstFw&l)r(7vI}j11K)v%yvRE$T6%k03rG%B&`;=3T-Qt2dJf8#eJPXe1s+8#doZ!;9b=* zLizL6-3w&#P&77VvgI&3lS$GFi5{l>JKR~bHHQ{UBY~OC9kEpUokaQwJhcon` z^bkW2u>D9F64YO+#&A!jBFTo&jA9amK^S@k9uo_jPf;L*JlxgL=w>)F9cj4a4CZOe zZ-o=H@`1rq38kR~Q$eR6UC-~RqA6=Z40H>*Q@e)Cf=G2q5_Orm+ zWWu!Ksgco6FK>-}K_2G|n*PM+HAi-`r$9J6j${f*)XCOk8;g9@#ZF=SG!Q|?X9;D` z0y{)9QR@kUBfbF~xK%~?`Q}x7^6W$*^3=eb5oP%YzB-y5V_Gs#wzNii6H#fz4Kg<< zNDSWAvY%-DcuRQU(XfQjEVjv=zFjH|Y3BJ;pjP$4*o#R5y-(M6ipXHvH zVGZS9Ec*L~oQcn)Fhr4IdJA6?1tyNc4foD&#+g&oi|)BWD$&xvdVv6rQZF=^UE=55;QfgI zVd?5-Ot9HlN-HE-hzpzGt2@Grq?oMLawCbQbQD|yFyw5&5U;6@$P%fUV*BI@3d(7M zN{AA~-&9kBs?`1K{P!K#iN#-7wm!d9+O-W;iW1>AwIfu|^9maB6YgKWZR0f*>4FQS zeNgKRcETmRTyA6SxN!SeuizSPz7&TUO}!*zqY)=Nv`pmD>h0+GPusT z74Ig%l6iEyM}Nh;R*tsVfaKJkm0JvfyvcvN@_0Hk69do&OUYY>+X%NTEnv7uUa~SD zFj)vc#CX8Vh=+i7@1PtF36`jS(D6FFXS8>-pFtICa+0bu!|=nD?*aRn&Gj+E+Dyx4ty|$FP5hbl%RLEPb&$Wiz9)j=)f+7-_??5kurGg0 zW!Qd#eSzc_5?q>>JUL%iz`*}_s;jl?Eog~gJe5q+xP?JrN9B2bsVhRx@{hZYlXLvx z?*3Bt5DLTZW>$)%ieK$+?-jn8j~#XZxdT9i`vLs;ls7@UFyeNF^bo$a@SQrAq@4t2 cm@D~;p6J{nSI8eq%`Fc3=dKH-9cf4C|A4kJkpKVy diff --git a/aircox/models/__pycache__/sound.cpython-37.pyc b/aircox/models/__pycache__/sound.cpython-37.pyc index 0675e48abfc61d58f505507160153f4de391278e..db47a404fd5af591d2d58cdcfec5ae50e1bb93b7 100644 GIT binary patch delta 20 acmbR0Hr0*WiIw delta 20 acmbR0Hr0*WiI this.update())\n this.update()\n }\n});\n\n\n//# sourceURL=webpack:///./assets/admin/statistics.vue?./node_modules/vue-loader/lib??vue-loader-options"); +eval("__webpack_require__.r(__webpack_exports__);\n//\n//\n//\n//\n//\n//\n\n\nconst splitReg = new RegExp(`,\\s*`, 'g');\n\n/* harmony default export */ __webpack_exports__[\"default\"] = ({\n data() {\n return {\n counts: {},\n }\n },\n\n methods: {\n update() {\n const items = this.$el.querySelectorAll('input[name=\"data\"]:checked')\n const counts = {};\n\n console.log(items)\n for(var item of items)\n if(item.value)\n for(var tag of item.value.split(splitReg))\n counts[tag.trim()] = (counts[tag.trim()] || 0) + 1;\n this.counts = counts;\n }\n },\n\n mounted() {\n this.$refs.form.addEventListener('change', () => this.update())\n this.update()\n }\n});\n\n\n//# sourceURL=webpack:///./assets/admin/statistics.vue?./node_modules/vue-loader/lib??vue-loader-options"); /***/ }), diff --git a/aircox/static/aircox/main.css b/aircox/static/aircox/main.css index a5530c6..5368918 100644 --- a/aircox/static/aircox/main.css +++ b/aircox/static/aircox/main.css @@ -7162,6 +7162,11 @@ label.panel-block { .has-background-transparent { background-color: transparent; } +.is-opacity-light { + opacity: 0.7; } + .is-opacity-light:hover { + opacity: 1; } + .navbar + .container { margin-top: 1em; } @@ -7174,6 +7179,29 @@ a.navbar-item.is-active { .navbar .navbar-dropdown { z-index: 2000; } +.navbar .navbar-split { + margin: 0.2em 0em; + margin-right: 1em; + padding-right: 1em; + border-right: 1px #b5b5b5 solid; + display: inline-block; } + +.navbar form { + margin: 0em; + padding: 0em; } + +.filters { + margin: 1em 0em; + background-color: transparent; + margin-bottom: 1em; } + .filters .title { + padding-right: 2em; + margin-right: 1em; + border-right: 1px #b5b5b5 solid; + font-size: 1.25rem; + color: #7a7a7a; + font-weight: 300; } + /* .navbar-brand img { min-height: 6em; diff --git a/aircox/templates/admin/aircox/statistics.html b/aircox/templates/admin/aircox/statistics.html index 572e64a..6dfa9b2 100644 --- a/aircox/templates/admin/aircox/statistics.html +++ b/aircox/templates/admin/aircox/statistics.html @@ -4,7 +4,9 @@ {% block content %}{{ block.super }} {# TODO: date subtitle #} - +
+ + + + + + +
{% endblock %} diff --git a/aircox/templates/admin/base.html b/aircox/templates/admin/base.html index 4382358..e66b147 100644 --- a/aircox/templates/admin/base.html +++ b/aircox/templates/admin/base.html @@ -46,7 +46,7 @@ {% trans "Articles" %} @@ -56,7 +56,7 @@ {% trans "Episodes" %} diff --git a/aircox/templates/aircox/article_detail.html b/aircox/templates/aircox/article_detail.html index b160431..dce7ec4 100644 --- a/aircox/templates/aircox/article_detail.html +++ b/aircox/templates/aircox/article_detail.html @@ -1,14 +1,14 @@ {% extends "aircox/page_detail.html" %} {% load i18n %} -{% block side_nav %} +{% block sidebar %} {{ block.super }} -{% if side_items %} +{% if sidebar_items %}

{% trans "Latest news" %}

- {% for object in side_items %} + {% for object in sidebar_items %} {% include "aircox/page_item.html" %} {% endfor %} diff --git a/aircox/templates/aircox/base.html b/aircox/templates/aircox/base.html index 90b8a3c..e06477f 100644 --- a/aircox/templates/aircox/base.html +++ b/aircox/templates/aircox/base.html @@ -3,6 +3,7 @@ Context: - cover: image cover - site: current website +- has_filters: display filter bar (using block "filters") {% endcomment %} @@ -71,19 +72,50 @@ Context: {% endblock %} + {% if has_filters %} + + {% endif %} + {% block main %}{% endblock main %} - {% if show_side_nav %} + {% if has_sidebar %} {% endif %} diff --git a/aircox/templates/aircox/diffusion_item.html b/aircox/templates/aircox/diffusion_item.html new file mode 100644 index 0000000..8b5d651 --- /dev/null +++ b/aircox/templates/aircox/diffusion_item.html @@ -0,0 +1,11 @@ +{% comment %} +Context: +- object: diffusion +- "episode_item"'s context (except object and diffusion) +{% endcomment %} +{% with object as diffusion %} +{% with object.episode as object %} +{% include "aircox/episode_item.html" %} +{% endwith %} +{% endwith %} + diff --git a/aircox/templates/aircox/diffusion_list.html b/aircox/templates/aircox/diffusion_list.html index eb76f57..78d60b4 100644 --- a/aircox/templates/aircox/diffusion_list.html +++ b/aircox/templates/aircox/diffusion_list.html @@ -1,5 +1,5 @@ {% extends "aircox/page.html" %} -{% load i18n aircox %} +{% load i18n aircox humanize %} {% block title %} {% with station.name as station %} @@ -9,17 +9,22 @@ {% block subtitle %}{{ date|date:"l d F Y" }}{% endblock %} -{% block main %}{{ block.super }} -
+{% block filters %} +{% with "diffusion-list" as url_name %} +{% include "aircox/widgets/dates_menu.html" %} +{% endwith %} +{% endblock %} +{% block main %}{{ block.super }} {% with True as hide_schedule %} -
+
{% for diffusion in object_list %} -
+ {# FIXME: opacity should work -- maybe hidden tz #} +
@@ -33,12 +38,10 @@
{% endwith %} +{% comment %} +{% endcomment %} -
{% endblock %} diff --git a/aircox/templates/aircox/log_item.html b/aircox/templates/aircox/log_item.html index 1694ee6..9cbae9b 100644 --- a/aircox/templates/aircox/log_item.html +++ b/aircox/templates/aircox/log_item.html @@ -11,9 +11,7 @@ for design review. {% if object|is_diffusion %} {% with object as diffusion %} - {% with diffusion.episode as object %} - {% include "aircox/episode_item.html" %} - {% endwith %} + {% include "aircox/diffusion_item.html" %} {% endwith %} {% else %} {% with object.track as object %} diff --git a/aircox/templates/aircox/log_list.html b/aircox/templates/aircox/log_list.html index 66dc1d2..be03e6a 100644 --- a/aircox/templates/aircox/log_list.html +++ b/aircox/templates/aircox/log_list.html @@ -10,14 +10,17 @@ {% block subtitle %}{{ date|date:"l d F Y" }}{% endblock %} +{% block filters %} +{% with "log-list" as url_name %} +{% include "aircox/widgets/dates_menu.html" %} +{% endwith %} +{% endblock %} {% block main %} -
- -
+
{#

{{ date }}

#} {% with True as hide_schedule %} - +
{% for object in object_list %}
@@ -37,13 +40,5 @@
{% endwith %}
- - - -
{% endblock %} diff --git a/aircox/templates/aircox/page_list.html b/aircox/templates/aircox/page_list.html index 2c63d1b..539a98c 100644 --- a/aircox/templates/aircox/page_list.html +++ b/aircox/templates/aircox/page_list.html @@ -2,63 +2,65 @@ {% load i18n aircox %} {% block title %} -{{ view.model|verbose_name:True|title }} +{% if not parent %}{{ view.model|verbose_name:True|title }} +{% else %} +{% with parent.title as title %} +{% blocktrans %}Publications of {{ title }}{% endblocktrans %} +{% endwith %} +{% endif %} {% endblock %} -{% block side_nav %} -{{ block.super }} - -{% if filter_categories|length != 1 %} -
-

{% trans "Filters" %}

-
- {% block list_filters %} -
-
- -
-
-
-
- {% for category in filter_categories %} - - {% endfor %} +{% block filters %} + + +
-{% endif %} + + {% endblock %} {% block main %} -
+
{% for object in object_list %} {% block list_object %} -{% include item_template_name %} +{% include object.item_template_name|default:item_template_name %} {% endblock %} {% endfor %}
diff --git a/aircox/templates/aircox/program_base.html b/aircox/templates/aircox/program_base.html index 14f6ad8..a3f5db2 100644 --- a/aircox/templates/aircox/program_base.html +++ b/aircox/templates/aircox/program_base.html @@ -1,30 +1,16 @@ {% extends "aircox/page_detail.html" %} {% load i18n %} -{% block side_nav %} -{{ block.super }} - -{% if side_items %} -
-

{% trans "Last shows" %}

- - {% for object in side_items %} - {% include "aircox/episode_item.html" %} - {% endfor %} - -
- -
-{% endif %} +{% block sidebar_title %} +{% with program.title as program %} +{% blocktrans %} Recently on {{ program }}{% endblocktrans %} +{% endwith %} {% endblock %} +{% block sidebar %} +{% with program as parent %} +{{ block.super }} +{% endwith %} +{% endblock %} + + diff --git a/aircox/templates/aircox/track_item.html b/aircox/templates/aircox/track_item.html index faf0972..ee1c3fe 100644 --- a/aircox/templates/aircox/track_item.html +++ b/aircox/templates/aircox/track_item.html @@ -4,9 +4,9 @@ Context: {% endcomment %} -{{ track.title }} +{{ object.title }} -— {{ track.artist }} -{% if track.info %}({{ track.info }}){% endif %} +— {{ object.artist }} +{% if object.info %}({{ object.info }}){% endif %} diff --git a/aircox/templates/aircox/widgets/dates_menu.html b/aircox/templates/aircox/widgets/dates_menu.html index f63e821..cbbb6c2 100644 --- a/aircox/templates/aircox/widgets/dates_menu.html +++ b/aircox/templates/aircox/widgets/dates_menu.html @@ -9,40 +9,35 @@ Context: An empty date results to a title or a separator {% endcomment %} -{% load i18n humanize %} +{% load i18n %} - + + + + diff --git a/aircox/urls.py b/aircox/urls.py index 805c4b9..6fbcf82 100755 --- a/aircox/urls.py +++ b/aircox/urls.py @@ -24,6 +24,8 @@ api = [ urls = [ + path(_(''), + views.DiffusionListView.as_view(), name='home'), path('api/', include(api)), # path('', views.PageDetailView.as_view(model=models.Article), @@ -35,15 +37,6 @@ urls = [ views.ArticleDetailView.as_view(), name='article-detail'), - path(_('programs/'), views.PageListView.as_view(model=models.Program), - name='program-list'), - path(_('programs//'), - views.ProgramDetailView.as_view(), name='program-detail'), - path(_('programs//episodes/'), - views.EpisodeListView.as_view(), name='episode-list'), - path(_('programs//articles/'), - views.ArticleListView.as_view(), name='article-list'), - path(_('episodes/'), views.EpisodeListView.as_view(), name='episode-list'), path(_('episodes//'), @@ -53,7 +46,23 @@ urls = [ path(_('week//'), views.DiffusionListView.as_view(), name='diffusion-list'), - path(_('logs/'), views.LogListView.as_view(), name='logs'), - path(_('logs//'), views.LogListView.as_view(), name='logs'), + path(_('logs/'), views.LogListView.as_view(), name='log-list'), + path(_('logs//'), views.LogListView.as_view(), name='log-list'), # path('', views.route_page, name='page'), + + path(_('publications/'), + views.ProgramPageListView.as_view(), name='page-list'), + + path(_('programs/'), views.PageListView.as_view(model=models.Program), + name='program-list'), + path(_('programs//'), + views.ProgramDetailView.as_view(), name='program-detail'), + path(_('programs//episodes/'), + views.EpisodeListView.as_view(), name='episode-list'), + path(_('programs//articles/'), + views.ArticleListView.as_view(), name='article-list'), + path(_('programs//publications/'), + views.ProgramPageListView.as_view(), name='page-list'), + + ] diff --git a/aircox/views/__init__.py b/aircox/views/__init__.py index 4e8a364..ed44b56 100644 --- a/aircox/views/__init__.py +++ b/aircox/views/__init__.py @@ -5,5 +5,5 @@ from .base import BaseView from .episode import EpisodeDetailView, EpisodeListView, DiffusionListView from .log import LogListView from .page import PageDetailView, PageListView -from .program import ProgramDetailView +from .program import ProgramDetailView, ProgramPageListView diff --git a/aircox/views/admin.py b/aircox/views/admin.py index 6683723..49ec58a 100644 --- a/aircox/views/admin.py +++ b/aircox/views/admin.py @@ -49,6 +49,9 @@ class AdminSite(admin.AdminSite): path('tools/statistics/', self.admin_view(StatisticsView.as_view()), name='tools-stats'), + path('tools/statistics//', + self.admin_view(StatisticsView.as_view()), + name='tools-stats'), ] return urls diff --git a/aircox/views/article.py b/aircox/views/article.py index 8677f1d..e81cc1a 100644 --- a/aircox/views/article.py +++ b/aircox/views/article.py @@ -7,10 +7,10 @@ __all__ = ['ArticleDetailView', 'ArticleListView'] class ArticleDetailView(PageDetailView): - show_side_nav = True + has_sidebar = True model = Article - def get_side_queryset(self): + def get_sidebar_queryset(self): qs = Article.objects.select_related('cover') \ .filter(is_static=False) \ .order_by('-date') @@ -27,9 +27,7 @@ class ArticleListView(ParentMixin, PageListView): template_name = 'aircox/article_list.html' show_headline = True is_static = False - parent_model = Program - fk_parent = 'program' def get_queryset(self): return super().get_queryset().filter(is_static=self.is_static) diff --git a/aircox/views/base.py b/aircox/views/base.py index f293ca3..eb4c0f0 100644 --- a/aircox/views/base.py +++ b/aircox/views/base.py @@ -3,6 +3,7 @@ from django.http import Http404 from django.views.generic import DetailView, ListView from django.views.generic.base import TemplateResponseMixin, ContextMixin +from ..models import Page from ..utils import Redirect @@ -15,8 +16,10 @@ class BaseView(TemplateResponseMixin, ContextMixin): cover = None """ Page cover """ - show_side_nav = False + has_sidebar = True """ Show side navigation """ + has_filters = False + """ Show filters nav """ list_count = 5 """ Item count for small lists displayed on page. """ @@ -24,27 +27,29 @@ class BaseView(TemplateResponseMixin, ContextMixin): def station(self): return self.request.station - def get_queryset(self): - return super().get_queryset().station(self.station) + # def get_queryset(self): + # return super().get_queryset().station(self.station) - def get_side_queryset(self): + def get_sidebar_queryset(self): """ Return a queryset of items to render on the side nav. """ - return None + return Page.objects.select_subclasses().published() \ + .order_by('-pub_date') - def get_context_data(self, side_items=None, **kwargs): + def get_context_data(self, sidebar_items=None, **kwargs): kwargs.setdefault('station', self.station) kwargs.setdefault('cover', self.cover) + kwargs.setdefault('has_filters', self.has_filters) - show_side_nav = kwargs.setdefault('show_side_nav', self.show_side_nav) - if show_side_nav and side_items is None: - side_items = self.get_side_queryset() - side_items = None if side_items is None else \ - side_items[:self.list_count] + has_sidebar = kwargs.setdefault('has_sidebar', self.has_sidebar) + if has_sidebar and sidebar_items is None: + sidebar_items = self.get_sidebar_queryset() + sidebar_items = None if sidebar_items is None else \ + sidebar_items[:self.list_count] if not 'audio_streams' in kwargs: streams = self.station.audio_streams streams = streams and streams.split('\n') kwargs['audio_streams'] = streams - return super().get_context_data(side_items=side_items, **kwargs) + return super().get_context_data(sidebar_items=sidebar_items, **kwargs) diff --git a/aircox/views/episode.py b/aircox/views/episode.py index a4a8697..8e1aa1a 100644 --- a/aircox/views/episode.py +++ b/aircox/views/episode.py @@ -35,18 +35,14 @@ class EpisodeListView(ParentMixin, PageListView): model = Episode item_template_name = 'aircox/episode_item.html' show_headline = True - parent_model = Program - fk_parent = 'program' class DiffusionListView(GetDateMixin, BaseView, ListView): """ View for timetables """ model = Diffusion - - date = None - start = None - end = None + has_filters = True + redirect_date_url = 'diffusion-list' def get_date(self): date = super().get_date() @@ -56,19 +52,7 @@ class DiffusionListView(GetDateMixin, BaseView, ListView): return super().get_queryset().today(self.date).order_by('start') def get_context_data(self, **kwargs): - today = datetime.date.today() start = self.date - datetime.timedelta(days=self.date.weekday()) - dates = [ - (today, None), - (today - datetime.timedelta(days=1), None), - (today + datetime.timedelta(days=1), None), - (today - datetime.timedelta(days=7), _('next week')), - (today + datetime.timedelta(days=7), _('last week')), - (None, None) - ] + [ - (date, date.strftime('%A %d')) - for date in (start + datetime.timedelta(days=i) - for i in range(0, 7)) if date != today - ] + dates = [start + datetime.timedelta(days=i) for i in range(0, 7)] return super().get_context_data(date=self.date, dates=dates, **kwargs) diff --git a/aircox/views/log.py b/aircox/views/log.py index 3348cad..f61670e 100644 --- a/aircox/views/log.py +++ b/aircox/views/log.py @@ -48,6 +48,9 @@ class LogListView(BaseView, LogListMixin, ListView): Return list of logs for the provided date (from `kwargs` or `request.GET`, defaults to today). """ + redirect_date_url = 'log-list' + has_filters = True + def get_date(self): date, today = super().get_date(), datetime.date.today() return today if date is None else min(date, today) @@ -56,8 +59,7 @@ class LogListView(BaseView, LogListMixin, ListView): today = datetime.date.today() kwargs.update({ 'date': self.date, - 'dates': ((today - datetime.timedelta(days=i), None) - for i in range(0, 7)), + 'dates': (today - datetime.timedelta(days=i) for i in range(0, 7)), 'object_list': self.get_object_list(self.object_list), }) return super().get_context_data(**kwargs) diff --git a/aircox/views/mixins.py b/aircox/views/mixins.py index baabb90..6b56260 100644 --- a/aircox/views/mixins.py +++ b/aircox/views/mixins.py @@ -1,4 +1,6 @@ -from django.shortcuts import get_object_or_404 +import dateutil +from django.shortcuts import get_object_or_404, redirect +from django.urls import reverse from ..utils import str_to_date @@ -12,13 +14,18 @@ class GetDateMixin: `kwargs['date']` """ date = None + redirect_date_url = None def get_date(self): - if 'date' in self.request.GET: - return str_to_date(self.request.GET['date'], '-') - return self.kwargs['date'] if 'date' in self.kwargs else None + date = self.request.GET.get('date') + return str_to_date(date, '-') if date is not None else \ + self.kwargs['date'] if 'date' in self.kwargs else None def get(self, *args, **kwargs): + if self.redirect_date_url and self.request.GET.get('date'): + return redirect(self.redirect_date_url, + date=self.request.GET['date'].replace('-', '/')) + self.date = self.get_date() return super().get(*args, **kwargs) @@ -35,8 +42,6 @@ class ParentMixin: """ Url lookup argument """ parent_field = 'slug' """ Parent field for url lookup """ - fk_parent = 'page' - """ Page foreign key to the parent """ parent = None """ Parent page object """ @@ -54,8 +59,7 @@ class ParentMixin: def get_queryset(self): if self.parent is not None: - lookup = {self.fk_parent: self.parent} - return super().get_queryset().filter(**lookup) + return super().get_queryset().filter(parent=self.parent) return super().get_queryset() def get_context_data(self, **kwargs): diff --git a/aircox/views/page.py b/aircox/views/page.py index d64f161..1dcaa7f 100644 --- a/aircox/views/page.py +++ b/aircox/views/page.py @@ -1,6 +1,5 @@ from django.http import Http404, HttpResponse -from django.shortcuts import get_object_or_404 from django.utils.translation import ugettext_lazy as _ from django.views.generic import DetailView, ListView @@ -19,9 +18,11 @@ __all__ = ['PageDetailView', 'PageListView'] class PageListView(BaseView, ListView): template_name = 'aircox/page_list.html' item_template_name = 'aircox/page_item.html' + has_sidebar = True + has_filters = True + paginate_by = 20 show_headline = True - show_side_nav = True categories = None def get(self, *args, **kwargs): @@ -36,7 +37,7 @@ class PageListView(BaseView, ListView): # (by id) if self.categories: qs = qs.filter(category__slug__in=self.categories) - return qs.order_by('-date') + return qs.order_by('-pub_date') def get_categories_queryset(self): # TODO: use generic reverse field lookup @@ -56,6 +57,7 @@ class PageListView(BaseView, ListView): class PageDetailView(BaseView, DetailView): """ Base view class for pages. """ context_object_name = 'page' + has_filters = False def get_queryset(self): return super().get_queryset().select_related('cover', 'category') diff --git a/aircox/views/program.py b/aircox/views/program.py index 5506b82..e9698fc 100644 --- a/aircox/views/program.py +++ b/aircox/views/program.py @@ -1,11 +1,13 @@ +from django.db.models import Q from django.core.exceptions import ObjectDoesNotExist from django.shortcuts import get_object_or_404 -from aircox.models import Episode, Program +from ..models import Episode, Program, Page +from .mixins import ParentMixin from .page import PageDetailView, PageListView -__all__ = ['ProgramPageDetailView', 'ProgramDetailView'] +__all__ = ['ProgramPageDetailView', 'ProgramDetailView', 'ProgramPageListView'] class ProgramPageDetailView(PageDetailView): @@ -13,24 +15,25 @@ class ProgramPageDetailView(PageDetailView): Base view class for a page that is displayed as a program's child page. """ program = None - show_side_nav = True + has_sidebar = True list_count = 5 - def get_side_queryset(self): - return self.program.episode_set.published().order_by('-date') + def get_sidebar_queryset(self): + return super().get_sidebar_queryset().filter(parent=self.object) + + +class ProgramPageListView(ParentMixin, PageListView): + model = Page + parent_model = Program + queryset = Page.objects.select_subclasses() class ProgramDetailView(ProgramPageDetailView): model = Program - def get_articles_queryset(self): - return self.program.article_set.published().order_by('-date') - def get_context_data(self, **kwargs): self.program = kwargs.setdefault('program', self.object) - if 'articles' not in kwargs: - kwargs['articles'] = \ - self.get_articles_queryset()[:self.list_count] return super().get_context_data(**kwargs) + diff --git a/assets/admin/admin.scss b/assets/admin/admin.scss index 884f2ea..8b299d3 100644 --- a/assets/admin/admin.scss +++ b/assets/admin/admin.scss @@ -24,3 +24,9 @@ margin: 1em 0em; } + +ul.menu-list li { + list-style-type: none; +} + + diff --git a/assets/admin/statistics.vue b/assets/admin/statistics.vue index b19e6dd..bebbc65 100644 --- a/assets/admin/statistics.vue +++ b/assets/admin/statistics.vue @@ -26,7 +26,6 @@ export default { for(var tag of item.value.split(splitReg)) counts[tag.trim()] = (counts[tag.trim()] || 0) + 1; this.counts = counts; - console.log('counts', this.counts) } }, diff --git a/assets/public/styles.scss b/assets/public/styles.scss index 8ff69eb..1c4c987 100644 --- a/assets/public/styles.scss +++ b/assets/public/styles.scss @@ -5,6 +5,7 @@ $body-background-color: $light; @import "~bulma/bulma"; +//-- helpers/modifiers .is-fullwidth { width: 100%; } .is-fixed-bottom { position: fixed; @@ -18,6 +19,14 @@ $body-background-color: $light; background-color: transparent; } +.is-opacity-light { + opacity: 0.7; + &:hover { + opacity: 1; + } +} + +//-- navbar .navbar + .container { margin-top: 1em; } @@ -30,10 +39,44 @@ a.navbar-item.is-active { border-bottom: 1px grey solid; } -.navbar .navbar-dropdown { - z-index: 2000; +.navbar { + .navbar-dropdown { + z-index: 2000; + } + + .navbar-split { + margin: 0.2em 0em; + margin-right: 1em; + padding-right: 1em; + border-right: 1px $grey-light solid; + display: inline-block; + } + + form { + margin: 0em; + padding: 0em; + } } + +//-- filters +.filters { + margin: 1em 0em; + background-color: transparent; + margin-bottom: 1em; + + .title { + padding-right: 2em; + margin-right: 1em; + border-right: 1px $grey-light solid; + + font-size: $size-5; + color: $text-light; + font-weight: $weight-light; + } +} + + /* .navbar-brand img { min-height: 6em; diff --git a/requirements.txt b/requirements.txt index e76f7e2..2cd3016 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ Django>=2.2.0 djangorestframework>=3.9.4 +django-model-utils>=3.2.0 -dateutils>=0.6.6 watchdog>=0.8.3 psutil>=5.0.1 tzlocal>=1.4 @@ -12,7 +12,6 @@ django-filer>=1.5.0 django-ckeditor>=5.7.1 django-admin-sortable2>=0.7.2 django-content-editor>=1.4.2 - django-honeypot>=0.5.0 gunicorn>=19.6.0