From ac89c7e20d32275dd7f2a8ac7190131c30ef30a5 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 31 Oct 2022 11:05:11 +0000 Subject: [PATCH 1/2] Support wave file attachments --- content.py | 10 ++++++++++ epicyon.py | 2 +- media.py | 1 + metadata.py | 4 ++++ outbox.py | 4 ++++ utils.py | 6 +++++- webapp_media.py | 5 ++++- webapp_podcast.py | 2 ++ webapp_utils.py | 2 ++ 9 files changed, 33 insertions(+), 3 deletions(-) diff --git a/content.py b/content.py index 45dd940a2..ad09ef71e 100644 --- a/content.py +++ b/content.py @@ -1441,6 +1441,10 @@ def save_media_in_form_post(media_bytes, debug: bool, 'ogv': 'video/ogv', 'mp3': 'audio/mpeg', 'ogg': 'audio/ogg', + 'wav': 'audio/vnd.wave', + 'wav2': 'audio/wav', + 'wav3': 'audio/x-wav', + 'wav4': 'audio/x-pn-wave', 'opus': 'audio/opus', 'spx': 'audio/speex', 'flac': 'audio/flac', @@ -1460,6 +1464,12 @@ def save_media_in_form_post(media_bytes, debug: bool, extension = 'mp3' elif extension == 'csv2': extension = 'csv' + elif extension == 'wav2': + extension = 'wav' + elif extension == 'wav3': + extension = 'wav' + elif extension == 'wav4': + extension = 'wav' if filename_base: filename = filename_base + '.' + extension search_lst = search_str.decode().split('/', maxsplit=1) diff --git a/epicyon.py b/epicyon.py index 811bae57b..f064d75a8 100644 --- a/epicyon.py +++ b/epicyon.py @@ -1222,7 +1222,7 @@ def _command_options() -> None: # comma separated list of preferred audio formats. eg. "opus", "mp3", "spx" # in order of preference - preferred_podcast_formats = ['ogg', 'mpeg', 'opus', 'spx'] + preferred_podcast_formats = ['ogg', 'mpeg', 'opus', 'spx', 'wav'] if argb.podcast_formats: podcast_formats_str = argb.podcast_formats else: diff --git a/media.py b/media.py index 2a62d98f9..92b6d0375 100644 --- a/media.py +++ b/media.py @@ -670,6 +670,7 @@ def path_is_audio(path: str) -> bool: path.endswith('.opus') or \ path.endswith('.spx') or \ path.endswith('.flac') or \ + path.endswith('.wav') or \ path.endswith('.mp3'): return True return False diff --git a/metadata.py b/metadata.py index 56f4d4bbe..f6db54e23 100644 --- a/metadata.py +++ b/metadata.py @@ -193,6 +193,10 @@ def meta_data_instance(show_accounts: bool, 'video/mp4', 'video/ogv', 'audio/ogg', + 'audio/wav', + 'audio/x-wav', + 'audio/x-pn-wave', + 'audio/vnd.wave', 'audio/opus', 'audio/speex', 'audio/x-speex', diff --git a/outbox.py b/outbox.py index 16d5befb5..a3313554e 100644 --- a/outbox.py +++ b/outbox.py @@ -353,6 +353,10 @@ def post_message_to_outbox(session, translate: {}, "avif": "avif", "audio/mpeg": "mp3", "ogg": "ogg", + "audio/wav": "wav", + "audio/x-wav": "wav", + "audio/x-pn-wave": "wav", + "audio/vnd.wave": "wav", "flac": "flac", "opus": "opus", "audio/speex": "spx", diff --git a/utils.py b/utils.py index c1d6567fb..a6abd5c8b 100644 --- a/utils.py +++ b/utils.py @@ -490,7 +490,7 @@ def get_video_extensions() -> []: def get_audio_extensions() -> []: """Returns a list of the possible audio file extensions """ - return ('mp3', 'ogg', 'flac', 'opus', 'spx') + return ('mp3', 'ogg', 'flac', 'opus', 'spx', 'wav') def get_image_extensions() -> []: @@ -2897,6 +2897,10 @@ def media_file_mime_type(filename: str) -> str: 'ico': 'image/x-icon', 'mp3': 'audio/mpeg', 'ogg': 'audio/ogg', + 'audio/wav': 'wav', + 'audio/x-wav': 'wav', + 'audio/x-pn-wave': 'wav', + 'wav': 'audio/vnd.wave', 'opus': 'audio/opus', 'spx': 'audio/speex', 'flac': 'audio/flac', diff --git a/webapp_media.py b/webapp_media.py index 46427ee3b..f91ae26a2 100644 --- a/webapp_media.py +++ b/webapp_media.py @@ -275,10 +275,11 @@ def _add_embedded_video_from_sites(translate: {}, content: str, def _add_embedded_audio(translate: {}, content: str) -> str: - """Adds embedded audio for mp3/ogg/opus + """Adds embedded audio for mp3/ogg/opus/wav """ if not ('.mp3' in content or '.ogg' in content or + '.wav' in content or '.opus' in content or '.spx' in content or '.flac' in content): @@ -290,6 +291,8 @@ def _add_embedded_audio(translate: {}, content: str) -> str: extension = '.mp3' if '.ogg' in content: extension = '.ogg' + elif '.wav' in content: + extension = '.wav' elif '.opus' in content: extension = '.opus' elif '.spx' in content: diff --git a/webapp_podcast.py b/webapp_podcast.py index 25108df52..4388b4d83 100644 --- a/webapp_podcast.py +++ b/webapp_podcast.py @@ -358,6 +358,8 @@ def html_podcast_episode(translate: {}, audio_extension = 'spx' elif '.flac' in link_url: audio_extension = 'flac' + elif '.wav' in link_url: + audio_extension = 'wav' else: audio_extension = 'ogg' else: diff --git a/webapp_utils.py b/webapp_utils.py index c8deec424..ce51a8e05 100644 --- a/webapp_utils.py +++ b/webapp_utils.py @@ -1372,6 +1372,8 @@ def get_post_attachments_as_html(base_dir: str, extension = '.mp3' if attach['url'].endswith('.ogg'): extension = '.ogg' + elif attach['url'].endswith('.wav'): + extension = '.wav' elif attach['url'].endswith('.opus'): extension = '.opus' elif attach['url'].endswith('.spx'): From 1d9f95b507e349ad726ec214d230b676c2a009d3 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Mon, 31 Oct 2022 11:10:23 +0000 Subject: [PATCH 2/2] Add file format to manual --- manual/manual.epub | Bin 1982976 -> 1982989 bytes manual/manual.html | 2 +- manual/manual.md | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/manual/manual.epub b/manual/manual.epub index abe125d1d26437285beb46ffba60302b9b45c579..5020d2fd05ccd0e553340ddc7ca86b4551ab0c03 100644 GIT binary patch delta 6066 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 jbMH|T#s5BY`Lpx88Pn8MTJ6 zX&K#=tfWlz2=ev0e%vJRxgux%N2{rctH#c%@)*kCOppL*w+CgVpE8hUbH=GXq_M>P z!!@-|GYvbH!oF8jkqGnf3M#Yy)UAbL8^450k~ygjJ;jA-x?Te`Nc~&h@pwnZ;4){K zeE-fR6_e&5i|-AinbRRp7X_OpnY0VcRE9*A$)8+HSI1|vvhCWFUX7+SONgcxef^lz zns8>Gm}~sGBrX~=7GPBt`}2wN5=*ktJl8Q*T+8NM608YtBqwe=i%IUdo`2=y z%-%`z_Civ&Y5do#jg5j6oywdBBaRnY(fU2!hgrVJS2j?^n)AkD1egQ$%Z5rHj3_Vi z6&|pilylIHUzqwLUr0MhJzE=H8B$~aIJUMFz5Ar*m9f5F9!HWTr=8WQ%Ha0Is2zRN z-5zTPrSQd;?=@dF)T}@70sP+5eMt-Rt*r%47bmwrSV&(lBe1y4MfiFuL z#8=VC(RlC3%)Oj`0ao3J<+D7DB0S5ZM$`(mi+?91Pk5s2ul_CjMrFdlYDK&EJN`&} zw)3eoN%{3+asMtm3Js=+dbph5JtVsDZz!{lrorH=J(u)S#V1evEjON<#jJ_#Ut~2* zsUs@*h>F!WN{xq|D>l9xeMILegDOQl_qiCT5r5-sB}+n0Zqg{q_^Jdn!@Iv^qEqpi z(~V=rvl7zYclaNxo9lT!=2rS3X2ToUhgBM1vhO+nK_tgvnfVu6Sz)%q+zemXbr%Hy z(`YEh55r4Up<-)MAfie5=FyQ4Q!$T;u7PqC2`m+#T1)7R4VeVR=^f7qj1SVO$nM$6 zi2V9nx5ub{uUA=UZfk;er zC!(=7;wY@3@6r!Pj(pdEp@~`F(0to*#%OxZ(LMITbu0it;aty|*AdgnLU##ElXnAP z7Zly4LY#q%9=xU;%SrEaRATk%oloyTTLcv9*J|tyx+F{zmq!QAixcditM>4N>W#=6 z_oJSm=;8hRjsPe){939G6CaekkHA8GDu83B`(O9RD9}^W9|uk8l6O0BX>>{21V~So z%8eFwq9X;)fp;Gw(+3QKy-f7j!zR0~Ps0=`g=6zm)BG?ibW5&T{9byr!UeoP3*w>} zhEYc(ain@Il~m7pQXLr#%yYtxi#jmRt-2R61BpCWPa>93HswQuA{7n5+;%!6F~E zV3B`G6frA9gYL|5ry}FOGWtBiGPv{fnKP%rBzi|~27HGglPb(C#l`9)9qCgz z4Li6K=hlUTn*iJdscv0DE2W6mm5i4SfIC&gU=I?fLXAlfnW5q+OBH>l!}EB1dMB7c z*w7Ew#61cSralVTevlI$P#Mo|KbT8K_Qqm7S!#T%Sk>j#~;RSrh^f(){A`5XQ+{z|9pFmrcd@N^9#+E2OvdBp+N48>5Az` zavEjTWxIuN)9w`qQ6$0(J|s>Un6S6-UcyE>`NdiITB zh>$Ky0_{AQ%rIh4*_AAr&5erpXxsKhrTMs$)m@fnK^~voLs%cL=GZ2+u=nLo4@&_N4wUOQtmMP|6Xk2(M0<-k$9rJtI|beJ9yFFI!4){87JiE`&U_swtR zjL_-il~*|qOM@8^+ACb#0u4X8{N;%yJY%F?DJ{ZE1z3Y^{`KYLa_WkY`A)|nmiF4< zkP&me*x0idZcM6Q3hvdtLR0AT=BDc7dCsesUvn%CcSN}kbv-4ek?xbhFQTi}Ur~X^ zjJI?qFHI$`>6Vclmb{LUvB%$cklMc9T;6#^k^4ZQ#fL~K=jGF_G9sm9*KDm|YI~Sc z1~D`1;_QQu{XRZpgMBW8;S1x6yE=>cogQW-o~$2f1PRl`aK?d*uVa!Yuh?sLXqk#J zhZNW_+etHa`5pD5WI|uas#QE_mSj@xZ%RRB8r5Zl z+ofVER{eEX*#KC9b&Rc!meYlzX|&!fC_zVoyJ_}iaKtgihJltU9ZG25(Kwr>SXHo9 zF++!~navH&DPp8@P0WZvI(mmeK)b)!`7u{;KBMBsx7%IQE)??q^I2iI2vm={qq`ESD2CIbWEJBQ0eI<%zZFb{Vk)!gUc6Kn@(wx_(!nY1sWT? zZM|eCjs#n!^z60C(LS9sUhl}c`yFWrk58u)>da!yey*^5FEg)DA^37+Z zX_-+JWwmO_Xnzqiqh#$5N(a|Uems2ml04TRx+YFM5{07wgOlM0&h@|WwWO}>Iwk;k zAPxZR@FCO8Qm>Dujt83WAwk3PWTq3!s!=wIn-QWMWKV^hB5O(yBm4V9?ggCs`QOf} z=XwUN!5QqPt(b)bdnb)1AJebf8~#e~V3KL3=%t=_oXMWO*|}TZc%a2__QhdI49(Ts zNvtdCgJo1|$j{INM;_UwXFrtSgp4Kcx}wCD%RR~7?K>o$?ivYvY!uiFsa|t!&rTTF zKep5Hff?Vqmqzyzja6m)QL^y>Ex5uY$NN4_bYN0XrO2U4ky=9&HH*Ju?UDTXHfopl zQ1EKqt=3`cN?qDXCWark)>hACM)v*~s-8bKmhSUo$?EYmCL@{QbfYA}=tO>5JwAum z^tCk~xvL<5QhnrFh_{u^3Z>ve-#44OzT7$KlH3FC&m$M7#%Jf-`uvVM84-a?^%pAh z0xEnM+7}Jc+-39 zG`_%ie~pM(aQvY~qB-t#5KTOoJ!wY56p9FIN~t>veU%|7F}@#3)Pr`)5>yyVsXi&j0$!Dr%JSFi%hd4e)uu$e` z;;^92L`}bULE6y3Lg#2&Nm1BnU9)H60CCLggt$ttr{;cPcZXb+49zyy{;w9VchQDl z)E)Gcdveb$@&nkcpfPpI*@gD8!{CaH(?9o0$jSJU&lCQXhzBn`eD(M$&>V3ika6O> zgJyks;iMug~KMi*ho2gGmYlf=?&%>zrLjlZ=j&`j`z>2Qp=!w9uZ# zKbD&==@yzB^avd+E=jk%WrC3|(=Sr9O4nLl2r_Rv^O%pvY55IWqo$(nA@irN>UgDc zZt}&?HKZ4+r$*t2qR>4aZTEo@7#|AAN z*qju&%pwE#jSTDyOd2lYv zmZkl~0?^1Ff*69!TNQ#ZgD5uut*WdGqIMI6(N}m=OL}nN|1m}WlORP!SVa{`jppRv ztTIuC!?1M&kdN|u7#}rQkop3EE~%{xO6Y=q0P5Nhd`F^OTPB`Bh5zmlE^k zEtIQ7*g?0V$lF|!eTD)Q-lG74Kdj`^q4!DzDLP=DuMbL@z<~V)m;Fy>B)VfDrvvMG zB*U4aIXt0aWr8@eBwqzMQ9f@BbXj5DpcE0f`(dDG8v<(>VzhJs6sofBVXBQl6O4g~ ztN1NI4r##3i{Th3rxwc(ftu^MXu>!!c$~&SHoG@CP`jXMV%7-&XZisECjIXZC1zg~ zqz%(k2Vu%f4d_l(1po-X1OTqzHV8Zo#vFjJlV7ltkGzjlI4L-Y=~Cj8iB zj@ewqIbn!XoghxX;rTjrma{hk!1WFQfG>H!Ka`lqV&HFFNba6~TVXk2u`($=_76-H z0=%=ZzkLx@e~f`ZkY|vOo4=F08!-%d%l9XyCoH!AzSM8omygClDCXCZk!k0^yb1$= zB=aX5=O;i&bz`^g+XLe!IR)9kxFIMx zl=)oE&%_ERwzS3UOC1)XY-}@jWNoq!v5<`RIzw(C2US)J7SajBY{^Vm6IS-OVWH@H z>=xw-M5zUEK~b87?MRwgumByr7pm1H>_EoD$e8UOw5&;xpeJmtnW6bq6a_@+paAYa z3e3sC59#b9h#+p#$ce@-frAX-6OHZ{5s(=X4X3ucg|tC3IOv7q21mE^S0x;W`Qrea z{#n|c@({Py#tt|XR7ZAzt%9~#6%%og#KulCKuUH%5eK=$0()f7tF!MM+6gaO8E${F zbB8JpK!|xFFeu!|Es*FE7`U08New$!kLv@#__58$O0X(qp|xI$a4i_GpQj;6iy(;r z(SVHA2cg&N`m_V^P%R!Jz@=P=b8MS+4xEYCmWsRlz+b0<{19GkgKCZ5wKfy5>ANka zYRh

Attachments can use a variety of formats.

  • Images: jpg, jpeg, gif, webp, avif, svg, ico, jxl, png
  • -
  • Audio: mp3, ogg, flac, opus, speex
  • +
  • Audio: mp3, ogg, flac, opus, speex, wav
  • Video: mp4, webm, ogv
diff --git a/manual/manual.md b/manual/manual.md index fcecd8658..e481b3424 100644 --- a/manual/manual.md +++ b/manual/manual.md @@ -391,7 +391,7 @@ A *wanted item* is a physical object or service which you want. These posts will Attachments can use a variety of formats. * Images: *jpg, jpeg, gif, webp, avif, svg, ico, jxl, png* - * Audio: *mp3, ogg, flac, opus, speex* + * Audio: *mp3, ogg, flac, opus, speex, wav* * Video: *mp4, webm, ogv* ![New post attachments](manual-attachments.png)