From b298d90be8e7f77afbfb50da7f97ace0cca54181 Mon Sep 17 00:00:00 2001 From: = <=> Date: Mon, 3 Jul 2023 08:13:46 -0400 Subject: [PATCH 1/9] Add upload extension --- extensions/Clay/upload.js | 69 ++++++++++++++++++++++++++++++++++++++ images/Clay/upload.png | Bin 0 -> 12311 bytes images/README.md | 5 +++ website/index.ejs | 6 ++++ 4 files changed, 80 insertions(+) create mode 100644 extensions/Clay/upload.js create mode 100644 images/Clay/upload.png diff --git a/extensions/Clay/upload.js b/extensions/Clay/upload.js new file mode 100644 index 0000000000..57577fcef2 --- /dev/null +++ b/extensions/Clay/upload.js @@ -0,0 +1,69 @@ +class Upload { + getInfo() { + return { + id: "uploadfile", + name: "Upload", + blocks: [ + { + opcode: "upload", + blockType: Scratch.BlockType.REPORTER, + text: "upload file to [url]", + arguments: { + url: { + type: Scratch.ArgumentType.STRING, + defaultValue: "https://store1.gofile.io/uploadFile", + }, + } + } + ] + }; + } + + upload(args) { + return new Promise((resolve, reject) => { + const inputElement = document.createElement("input"); + inputElement.type = "file"; + inputElement.style.display = "none"; + document.body.appendChild(inputElement); + + inputElement.click(); + + inputElement.addEventListener("change", function() { + if (this.files && this.files[0]) { + const formData = new FormData(); + formData.append("file", this.files[0], this.files[0].name); + + const url = args.url; + + const xhr = new XMLHttpRequest(); + xhr.open("POST", url, true); + + xhr.onload = function() { + if (xhr.readyState === 4 && xhr.status === 200) { + resolve(xhr.responseText); + inputElement.remove(); + } else { + reject("Upload failed"); + inputElement.remove(); + // throw 'Upload failed'; + } + }; + + xhr.onerror = function() { + reject("Upload failed"); + inputElement.remove(); + // throw 'Upload failed'; + }; + + xhr.send(formData); + } else { + reject("No file chosen"); + inputElement.remove(); + // throw 'No file chosen'; + } + }); + }); + } + } + + Scratch.extensions.register(new Upload()); \ No newline at end of file diff --git a/images/Clay/upload.png b/images/Clay/upload.png new file mode 100644 index 0000000000000000000000000000000000000000..22beec96f30608a4d137dec64406c25439a2f925 GIT binary patch literal 12311 zcmch72UJtr*JnbPNRcMerAzOS&n) z07MV~04PF1Mxb!24x|$PUGmYf@&^E@KU`eE6k%#s0#P|Y8xnBK+tU-~6#xkKQ*u$# z(!A{jmp8uW93-P8CE}qZEw3OgBdI7MBO@s-BPAuFC@m)vpd=+NAuk~t3ia}kxonT_Yo<0P80N`FgfRB>6xR?LG=mZJzV5pC{q?m*_KqXj- zAm<4SfN}+UBE0;Sf>j0nP*)=Sz95SWs8MqL>rchc#Z}2v>-N7y33sXj|3VK63K9#F z7W4LV6PHv}R1}wx5|@$^B}j<+-}efD28(+6^AM2!38e+|clLAl32^uJ;<|u_I(Z`l zR0Rb7lKRsm7w5l*@j?0_{uso?SsaFdT{z93FcHarSn1-d6yP3!fc=}{nuvgZqafTb zW}<|Edbz0z1dF=BT%kxrfPk8X*B|;WTrMzwcQ-FCQ7%ap@e2bH?ter0gYr*M@&Cop ze~A5UrvFVRXa)rMxjX&kh>K|cK|x-4PwXP5P?rl=Nc_VUe`+ady7>Ri@Qaz4!F>OX zLU6_f!w2f;4>P~-15*_+h536U{hVQc&wzgc-tvP%17I#{QW8?qq7w3=64EN-|Hk?& zh${bLXa@)Ax~M^+E>g}CuCk)?Qm(F|GICDxqKYsnCs9QONqH9;n3IH}0`xDeKUMw{ z(rqUKkgSxfl$@-hq>QAzqO5|%Upjv<|C5TjH`4ju#kAC<{*wF;+JA`uZ^Hafcm2<) z{?o1hj{@!Uw^j9zHA`R+;w$}+_!4MJn#h2A-hOJg5YYPp-d^TfhAQHJBmdjf{_hi! zP%i$Fg@4qVzt@z%rwc(?>5p9T_A~ePMyTC_dIb`~`|srclaYTFpFjLds6KzoTk*fD zm)d4f@Eiaj6r!u8X&#)tJ_|>~-0XU`=R0!x0$iu_M~(DxbuuO;%VP3;_7AqSCAjN& z`EK(Llf;1eOSGJ6DLcMsNwm@4bdurE{Pmc&nG15l2Y1-uDPzbE7Tr%s}7wXsh874epUnm0C^G{C~`vO{USpm0surk zxKc&9p}dVD0ssV=fgpl_*g_l?UdF zf#<4!SY!SYbazyT^5#iM0$aTR5z`lwyWHK?3<9|20^Y;9!nEWL<46a6(=u442h1Tz z*|b;`iN(Qt<{GV2ey;*C)!!eQGwY9jAxcq3Bux_oLFs0Lu+g#6nRxCOqP7Ei#iIL4 zOidxpW!S{y87RQKe_mJs8c0e?R@&}!LcF3yyX-~#Zny~Dx8U}Pp<{2-TGYK14(?3r z*wXcMZ3iTC86o&R=vFvXgj>LLRZ%Q{gI=^t8Z5=p9+fwHm3GhBUzv<3oJ3Ueh#nR! zchrs4W{9P-0NIlLr*5sv^apNrOJ}#w(*QvwPu&HnikMLRnyRkFy^C;;2L1zNSqfQ2 zPF>RD3OT!DfFSnW)q+~nh{vc+n%5*EdE60!ZW7gwjNKLqB}#*ZwaDl?xw@^Rs`}|h z!WfLvD}6%-vyc_g>TdL_DAN9~yvYq8M^>87j2$g@?+883e z#cY{uJysrf26NR+S6?F*!;K`wkx!v`xfm=Oq)|`jwr_f*!6@$%i05je0+PnjyNA2H zLm4SsXNu^)Uzeb=eSL6nP3+hgxEx0Zx*M^&>ykDh8W)45HhJlO@0|x+C6_eAkWK)% z5*?7{ROt+bBR|_uvQBC?Q9Mh~)dP6fh+pBKhg+a=XUL+one zjzt$7oj6NILOyY!LbUb?iT(nkC=796-5HZh_?T}uNoIAL>R?)cyWyB*dy;(Dv35^E zfr!b6;%V(PYX2Kz=;YS@zzOeq8>=l*qN_~0i#05$;ba!n61O9eoVMHQn^JpOrl{}4 zFXT&*?U_z4V~9__=1#Q76{DBwvIHFZ(YoP6^%2rIfvI7-H+;%f)3N2tIb$26t=-ijI${duVP1O&L*#ec40rsJ zJz63A-W?l?&mN7bEmjNM0r`l*!oF~`tU_)R3j)w5HRej1DZYn`B#Cx5%D2GA)|+%K zK4E8=;Lg4T7F5V}$ANVJgF4op1D5Uy8(!Z7IM&|3vyyMkXrt1;2e0;9n0lyL1Ts8C zTI<6Tu-q|e?ACldyN=)XW@+^?%DjyYy(_!y_?@5IF@^V8Z5A$GSZwPD183ciJ{=oP zO{+pRhb1dd2qZt`?Cj;FhwiD7+|qIy>-}_V5jB%#(CAdRiux}KwW1GG1HLTN>M`#3 z9EOfLHJPy~mFymkBd{l4ElZ`|-A!>Gbk^sncQNh(V_D~puQwr1h{l>Jv2*X%Nmxep zjUD}nGZl5B@!#Bz>`9TCKU<&R+v<|%HEYyrw)T~*Ch^Op>C1lZ#&7qpljf#JKCR7o zKK#Ovxqa|}?{?&sHoT~A4Tt$sote^olp@R7c8JQ;TFzg;nI`W?W>PrcV8ha7xa`{s zH}gN!Z};c{Cri|ve;klxpBxU0APaS~x#A$F@e>s*I5#)uZ@okwz{Uv_UcC**&g`vc zua<^)D>tMCVR6@+a3Yf`<6$43iWVc{Gs=m0Pc#w&LG~NAn(Z|9i1ZuDks60(?60C? z+qG-I0OR-(;*5M#{RuAmG=1#|t7f--S7@6h^cCk7p$R^r$pPiw*c}~KC^AGUC3Pad+1#tuSc_5?oY)g;Z1iqBDSAY z|Mc@vz_ME>lY8^9B9>}1DB@V7+skFWXc#E`q=rlO(mE&E3xPl;#Ew4o5s}TjRyFvG zu_d#cvW(($hLXpln;X2mHeTz6wYKd>EFVUeKMrPZTEAFa|0ZP+b*vMA-C(_#d%)7JC}Ewu;K~y4PCFhmFrK{5q#Ck?)*Qm|LE-PEukAL1zOu z!$XWeb>@<;uGezw`BiQoXfSrGe8^|^zgm@zRV(}E(C4x6^sTR6@yPu}Vy0BH15916 z*Cr6L3NM2}4RP?Zwbzl*#hOt`x-`|cqb*>q=~~os5R_2(HF9YI_t*lz=DT}bsrpTC z^s*v|9Cw*9+8oDa^evf$7_ zZYuJe4z?CL1aIhPSw*b&jLfTCS3Po)btaBFt()6-zY|7e!djlXmmj3ddDeY8^zkIt zTi@ZBN%;$4%vdz=3Q-jAYunVbJ^6yhnaHa1)06od?cdt=$Row=W`%+f03T-mke9%y zqUP1-d)@O&!A(2%{*8Of^Qrd8ifmsX<}Pg&zu`{www+7Sme{@Iq0HucpHNqbil=xP9CgzZrSW*-ig{MNgBeJy@9?r0aVP(lF# z2yK7dZ9s#~n|6#ubaNxkkDI|)PgaRAP{Kg{Ggyw79Y0Izro~r>9PoOP2NAe54x!Z{ z@~G1b_SjH|>2bfe-f2?ShXCwI@w~vP)OC;sDFN1XW#CXZQthG7GIDx^lfDLE9u-CE z$Uhfgf4oj!P&kJ;x96;xJC&|I4F!tGDK!%d&aw{a=Z0!o=lC}5D0$*&=HXkpzdAiW z0vxLeVk?`2XyCdxc3xO=a1=}8o6o|bnLIOO*g_rikN2eI0p zhwP*`c~ei*ztBGVvj zPym;DvC_cb~9<;8CNG_o{akj)^P~dvbGaC+`2(|9TfLT@rIviasl`( zyyoPxk-ljwU%hqnVNE3#R~9+%HFdi3kx;Q|xP6(Db`B-Zk?AkQ&s%oGO~>}kfD{l+ z_RrDjw}PQkppoM0*Ydqt?#1#QUi$d@(Xv5R$Ml2mCC2F#quh6)il}aSdA`VBANXy4_0^SJBj=VBD2#TZ& z|CMue8O(7Vv@7NtSP9A1V~w6w$IE2ZKDhwlHJZL$5Wlz5#K-`?ci-HIY5j3x01Pn? z|J*f!>j?1BRT^)ceUKX&5b>Vi=&rU)PPk*O7NzPF@@SMj0YLk9Vx3&#MA68~-cOsT zvIQ68j}J{+B$DTRJNJ(66wv!~T*Lq`W>6r^gX{gk@xjD_1byw2^Nj%0Y!~g&>RPAw zffdYElc_E4qWw_3gGr>=>%tbf>f*sH(V>BdK{MjvOU@&omr-|2MF=?eJcaC7bSFQK z4|y#)Qb0(32VHr|njds=wRfoo!q$7PvYotfb|9}Et1o2fkBu)Ct+vaODQ?=^aBoto zH{I9i)%`Hs!*1(osaraOxd{+K&vtr80uD`~v__$%_i3i%SAdct6%Kc5_oIv>Q(g^NxtZ?OM z>e-L>18;oRd}W9Xgaq6(BAqo5Dq*8Vg3e0UYC!vo&gS0*zk-B7?}3Z?2pdjIc(-dK zh0QXEKC3*$_v?Dr;+sdpm9t4|`|yLDmyc=?WFw=jBbJbT9TNtk3F^_Wcv!`A&nfS@ z54gqm2F} z&oHf`{A)s(1f{fj|G?0`Si@f5}M&StYdvrL=nBFnV>aHmJbHV2N+ zSFC^n^ zk9g`2IH(z9d-?@KF{8@_-P03+LTLdM$LBCEmv64O^Y`8()nb_}-V&vXYehsjZZP=- zL>&1vJGato+13|+;Lp&S5IyQnl=Zd?h$(w}-32Otm24s++N!L3{7KaE!*PEbQw%vQ zpWi(p)lI(qKJInd#17Qntv)R4QQWQ2N7rrHX|99jWKtvQ8WcQjs~VfBA!l6uxn7da z7IMXCAiUGF-Z}`~Z(KgXTa%lj&l6!881l;t=b*0Hq$GBeNi3lt7g3c+>FPy1ks<>T zH8p2X&+RH_(U1v>u||OPxqFP za%RxhW)NhOf5ce6@cKIx)8qWTfO~yUicd!RED<-VQ6c3L)x>F)FFY^3B>&ugrGl_Z ztwmVPgk5OTuk}#-(^ttA9b7kB#fJDLO%S(6)LehPu3MajkY6l~xZktOI~aK8NygOC zm|m(x+hx&AVKuOty*GogG>w`aQ*)%cg~JWFzP{2#(Qvahhf_y%%5?E_$D?w3JNM?$ zUtgB9*(D_@HddX4>y}=m7b<1PZq{T9{|O`ew1Bf5`;fgVZJG=%(ID_J?k(!hgC)Nj z6B!E6!<@#kYB}2WhB3p+z`h6O>xe)hJ+xprOYN;X3YuA1E9p=UI)pba`sKJv+U*fD zhMFaS$JMH&y_oG)1!&uLm`@jiwgRR3$%Bk?$`?|93DU9LRcpflBGTruwTOEuJ6~bE z&h}1Q`6qjiSzJ{8H63*;H#aVm$CEj=7Y5c-SnUcJp~-$}>sk1aq>!Px8aU^KmxS&B zWhUW6Q(o_sjV)B^bYjr=Yt-tkgnOBN%u`52R?)$yQ-*kSR1Iwf{^?5#?|$oiL1`L@ zP4wOpmC;r5UaclnW1#-=Sm?Uiuc7(c**blkY~^a0+`DP55Wj~?jttJOK*D32TLU6a zIBG{FxOne_00kI1>7}0=-WlL7626Z;Xiu#<;M1SocvqI&kvd)%l&Jl*-oDA8nUc~x z1mibYWSu*k%$-UcZK@hvJYYMEY{4fk-8s#DJ)fF`5V;VgIV*!V#7REi>N zs+JQftnD$^D(~J~7MgTtewM_@QC0E0pja-$i_~@5A_y|T_|4;t@k-6XqOlRAZy*F| zJtC@#OWn)myRMu1hPiV)C{0*Wg*GG+4Z|9-o*e2z!iv z?Ihqy5@@H>**HVkW=lKjriCNfV3}HhWccnx_HMHN-fH4h{UPeGz&K8O$5aaNfNbB( z`cd9g{w2g6yGEGinu~hq>)6-Nv!eI9FoV?J-(Ip%u*6JLuK(13(FAmj^BE7bc#LlQ zq&rz0sB5VcsV@$)CG0*HvrfkSt3%Zr!p}O=>57D%x$=x6!}WP>^CjA>^d!nL2HJ63p(J zF|2r^%%2#3@OKgCUjl2S zaGWD?tDGev3?(B^`Ea>vLbDCl`#J!&4>^QQLMVKzCLr2tU868!S$3pn-fmyeg#2(` zEd1z}MFJ5!iI6`9I<5C9Oa!(O+@&6%sN{~aNM0V6vrhzmtH~T@7TSJN`fTd#2v@;;(!~&7JRBY@-WDn{7~6Q z&&_!H;8aRA_yu3@?1!g&_2(joTRPcwYDpE;1#wv;k7RMJLprP~mx=wO3CDV4&Qnrc zT!Ojkv*V20BRhm(QUZ{2Z%5w{`hZO2|G)c>e>Oi4&IyB`pKr`sJ$JSWC-i081E(tR zoB7a|*x@`8t}6qA586mB0i7s%dE356rwIziz0tgRg;$TEx-IW=)(0jnxRL!qYjNXrUk6t4zCzCdG6h~8z7gsfsXmg@H*RNFjM`Ys zJzt$UFHKV=SWx9?z(1uWRqA5)nI-7c@vS5eQ^>0anG9ovRbr2X`KVhU7p+hUHFyDf zDM3f7+NE~;teh*kE7csXw{KB8Ary#~*1G89zWvO7V>V?(^=ip8r}*TJW*+;X=&}y} zabw+j*&7tkPVCM8X!rK?DVf$RJs59dMBTMo>Ts)BdOvZ^eYvj8$AS$AVov$Y3rng` zdfvJbfyQ*cr=0ctV&{O_=LM|1)Gc)BBW24RL5z1m4L6J5AD(a*#pZ5oZfVXPlvNXw^DHeasE37>df#yqIaNJi*yudEjV1YpvQ zmcnyCHP~Frn5vQw6AoA zTaq`ERg;LU4qauZk}{3`RtJ*?vq(fl#OP0uB&~elQhrD2PE0@tAVfb#6yR+2 z$+13RpkPo|es)R;tfwwY#Kfe})cWdn%bF2)-1n*~3wX5`2(xXlSf&hOLmx<2*9GaK za#O7v2LrCF071J$1!CrW%H48pWi`=Nj4iKvdU4I0A(tKX4Db)f1E+Xy7`O0jZ0Zi! z6sAZ^AElCr^b2G)3t7}GF+CBNh95(PZMUIo$#Bx>8`UER?@x2wpzWP$*51bTEevQA zJFWX6ag&X`9J;cQr6Q_V?4`&EJeZZPNF z6t!0GPc|$J&;fv0z4RJG%?pBPR+!&;kXSyeXq`;CVNn}=`)wwIzZ+XoXLoRLIS#|S z`GM7&wgL498{D8APCrH-ns=qi$8_S?>R}OuB~S14$lP1g-8LKRyIeW%N>T%c+E4U? z`Zzu>_QsaytpuSQ{KfGGHYq*Fak4FGgXH_R@24zopeN+GN&s*>jf6?NPhG+2M5P4% zscZ6{kT3UNMm^fe`0xlNgy3&MwAeTYREpufu%m0-#tTC6hUDkoU5{zrn{%Y))JN!N zQ4MBj>ov?;x|cOF`X$l=LCaMi9Y~u7ETSxuj@p^)zisvyC+~fbx)UQtukUNH?3-aF zT!=N*s>)=c*KbYGEnA({zDdvJ2yLh_>a^~*j>c!DQ8}ayXe>+mm_6M$6Z09UO5}F! zZt-_*s}8107XGZaQD(}M#A3|SI<8kwlv*#Af;EuJXx(7HowS{%z3PxoeEy#NG)JcW zq(1!AU12-9t6=l{ON4&vD`FFoHEi0i3BG#Eb8a%G-XVGTY^KTs3&lmlM&(aWa#@0-k^d}@%v=?@ZVRd6$PuW_D#<)IJT}21NwN@ns{2SKQau0nV-r);W?0{ zNrG^euZJ*S3y_Hrz3yFJZTZ>z<=EiVDhtC|yK9SvMXO~WioDd{Puy?ho4Uk!A|hQ% zWBPi=X-d(`%{lBRe!rk}nP^f7yusG1=U&|TPAZL(czjG%;Ep_njfFEEC%U1Vbre-& zx{B(%G$5d>6k#{vGK3b{OnX~9=#(PmDc4k?nQ!i`n_uZOp4q2do?dBQ7}_>Uv@#G~ z)h*+6gHSBdUytDt&#T1Xb#AY83lYY8*iF*FQWRqZr^<2;1+nTw>$vvPvd_QIPb*H& zbJKcxqu%a!O$^Lrmdnb4a#QDyQKDkU8Q@u@6}*x2NJUY}(P~MU(G#367f`&4MW3JC`==|>D$HYLFk(?X#xyW$(aJQzb!VkB9|-CK>#tDk5e z0{g5FN%XN5)`{D1Li{48Mc}QTAcpU9{+@&HTq`Vl={O5cogEX4!hp{|@_H%p&J|SS zn(p1LT|kdT*m|hk_258!vQ5)HjuzT@LK>)D-TY|x%uLhMVL_<67gie%|G~W-N#j^@ z8gB?Mk62iIwx-$6B&)oMWQ-HH50VZm-zD}|!%w$E7E4l}5ByHH@#0yk+6?uVo#}yY zF1_hk)##L*mwSk3h^qdM+8>TTGk5az+@5^HQ51BS0dAgV*&@8bH-g`2pWG4}vJxeK zrKcAwztkU;M{~1zbMNc`fZYn7UyI3oCZH5miZ|l(Fnc&&KHhCF=$&-NVsT*h=sP8I zXo6n3fd0M(k!9hOd2fjfF#YNgK6NJR!)CX7eG$lZ*ZP~(S-j5#G+v0>Eq<&+M0V(6 zV>fd$n~w?ZiRAv;=zP02^XfSy%f@uL{aKDSo>?>CHQ`-jIwQ8Tsz{jPv}Lr&9R4f8 z4T8hl|8)MHcognuWgmU%0%f_nh_hu!`%PY|O{{g=%}Di+EP3nuAGS4@%7YU{;u4et5?*16&3%mGKRnSjSOnvc_U`) zRDMlDOb7yaQCID@Cq6$T8p@oqonMJaQzZfT6WX&25bvY0+f%nnV#v?jjA>N6h=Kq; zJdQwxi6D-r$n$IicO(5wtM-E>`96-1Kkg~fBtIZ1X`Su8pG11X@7u_=?T@k^52{#J zLX^n=_VDb!BZuugnaM^nEK8)zqVdwy)}hto$3{glULb&L%ta&qd5RqNb{0s99&81& z79~Z!(B34RR!Irb1^^hIU%aw6ksx9M05skan)&}_28QH$y>s}i^(*#ZNmh9LHU~W8 zMlcs9i4b;rossR1&8vgsaqJWlTB6Aj+rNVo>IJWD4G;rjqeu<%R9E7@c&quBFC+rU zRS(mwmB!h&WI9>zb`kMwVu<*C?mM^9O;oCtmxkt4TmQTlrCAxiJyqQyrib=gr>%<8 zC0v)nww$C6CLo*|B(Jr`f{2sO1kC?CBcH4afLL2VWh|vx^(| z9tQo+w%@gJ+aHs>%0rwqRzlvgdadkuugq)mj=gVI=Kgl2`RUB9P|_EdAx6>mJI-Q^ zKz^Ss(BO}U;>r%6I*~A*(S!=#-pj`N*)vo1CPAu&`76EOH`FUUVJ%C`34*XoOcGb- zq=@N{SIL9+!I3^?gLVAk6!Q@cMcAPUN@hlhoXFpJxo?z$0J9iOjNIY#vt$1(!tzT0 zYVWewF!U2b_DlmqMENs~27%umK(9jq^!HEPkG@n{TH6}xjik*BfCAxt3&W2&8rxACvEhO% zyURmrVYg_`6bP#nbCVEY(rE;1`;T()$GMy2>Gh3~uD7;M56drL*$A*zv6Y1(-?GHk z64zox%&}Ot_I!c`wS+-HPYKa~_elR~&S6W>o?(%liKef|eothiUF8w;H_CJ-!q*FY z33L5>ZIccot?I@O*Ufw0PtwhvKGqMR8GV2;ueP9;AP$-zA31RdF$$U+77P`Hm=Yjz z#1Xi9&d$>I^ieelPZANw+g%zV+qFix<-?gbty>YuXPexq8~0x!F-x=%(IYsJsOk){DnH`mEZKfy1iD@706Y!?z=`bq)YM z!bTyK$E0Tr0ga={J;sPhT|}RANn74^svoU3I0rJ`6%Pdf3i@^AgAAtL6V_Qw83kdv z{g=Me8NSC*!VTwx^Ip@Pm<1ocEWog99?B&%JY)I^Frgw$ZUUWXut=SCoN!wHoW^o# z2P#Zam?sw;gS=tud&fi=Ukn6X*2HA;!TGX2w?EN4eHN2arlUhHOfQR~+wJEyWzywO zG7y2OnH$DOKA$o$_50-jy2;tV(u{o!f&!wR`pStu(+!t>6Pnd*lXWx%!y9is7c9}$ zw4-coJkt9>2}BE_eW5~eyraI2a>AkJ@0WWrua4P%LCF?Y;k*?M0hkg6{};V14o{!h zS#ZbAp8CEYecDl6slz7c&mdP|-Pg`MVJ#L6l`{}23^kojtqGiZn~^;*Gn9C4)x}ua zfai2B6Z=67c%g++dRDJyfb<(xxnt0p-2Ln2B)c`O9<;BWYr>|2PBW#9nSX=)Wu5dg zuH)H{imUn!GpF_oJNa=KQUEz^)ed?e+S?iBYF1%j7$G0n^fRvt^ZU2kjEW{#=B8R2`Hu@nJ*rax3dbE=2u<`e6tn6qBAdH+ zL^~l7;}+LZ98Ct(xd-}}uqjZw!}Mp9c0LY@8z>tC9wG?sZn#_@cMuF*)5@0Cmo~V$ zmdMZ|M?0&3@IEOk=V01H>vV#p;en^D#3wCN2Hjz*s|&5rxQ#GCfAtXv5`&_YJS~Oj znl5DJ$oVx6+$dkFiD1nPt^!|UL>*0(r{h~d8^XmDHh`6pFcS3Uon2541o_dl5SW)p&_dCT>(#+6Mo~rp!#kEvv}4aK4eKeP2_PCc zY70n_ZjFMKJCt+`ShE2}-JEW`;PY%bfsQsZZj*!giPGQT$kFH}AqyNeb_^hB9Hd`j zzu?h?v}qT%Wi=2c66_BciqSgxO0^4)Gf z;A>BaJ!M~0ccVFi;2Y()J@1ALM2D9phpi>g^)#mnwKEZ#EWpcxVvbY&vgZbk;qUJN z(&dXHQx+vO1>GHJ8p8nB4z`vb4pjXd1?e{bl%bEXouEG5`}82Bv&Rmy7RfdiW>S9T zBg%;@eU&4UIN|;E1mop1#E)?IpFkIX`CDp{+?o|&r?b&_3%OM7oSUr!ySaUx8O*9TXSp42>Owa%T literal 0 HcmV?d00001 diff --git a/images/README.md b/images/README.md index 9b629d4eb8..95305040aa 100644 --- a/images/README.md +++ b/images/README.md @@ -233,3 +233,8 @@ All images in this folder are licensed under the [GNU General Public License ver ## Lily/LooksPlus.svg - Created by [@LilyMakesThings](https://github.com/LilyMakesThings) in https://github.com/TurboWarp/extensions/pull/656 + +## Clay/upload.png + - Created by [@ClaytonTDM](https://github.com/ClaytonTDM) + - Upload icon based on https://icons8.com/icon/367/upload + - Background based on https://app.haikei.app/ \ No newline at end of file diff --git a/website/index.ejs b/website/index.ejs index 653cd4d146..12ec7f85e0 100644 --- a/website/index.ejs +++ b/website/index.ejs @@ -727,6 +727,12 @@

McUtils

Helpful utilities for any fast food employee. Created by LilyMakesThings.

+ +
+ <%- banner('Clay/upload') %> +

Upload

+

Upload files to web servers via Multipart Form data (multipart/form-data). Created by ClaytonTDM.

+
From 1820f693711e43c73b8bbfa78db897949a72563e Mon Sep 17 00:00:00 2001 From: ClaytonTDM Date: Mon, 10 Jul 2023 06:30:15 -0400 Subject: [PATCH 2/9] Fixed errors --- extensions/Clay/upload.js | 48 +++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/extensions/Clay/upload.js b/extensions/Clay/upload.js index 57577fcef2..854131d176 100644 --- a/extensions/Clay/upload.js +++ b/extensions/Clay/upload.js @@ -1,3 +1,4 @@ +(function (Scratch) { class Upload { getInfo() { return { @@ -19,7 +20,7 @@ class Upload { }; } - upload(args) { + upload(args) { return new Promise((resolve, reject) => { const inputElement = document.createElement("input"); inputElement.type = "file"; @@ -32,38 +33,37 @@ class Upload { if (this.files && this.files[0]) { const formData = new FormData(); formData.append("file", this.files[0], this.files[0].name); + + const options = { + body: formData, + method: 'POST', + mode: 'cors', + }; - const url = args.url; - - const xhr = new XMLHttpRequest(); - xhr.open("POST", url, true); - - xhr.onload = function() { - if (xhr.readyState === 4 && xhr.status === 200) { - resolve(xhr.responseText); + Scratch.fetch(args.url, options) + .then(response => { + if (response.ok) { + return response.text(); + } else { + throw new Error("Upload failed"); + } + }) + .then(text => { + resolve(text); inputElement.remove(); - } else { - reject("Upload failed"); + }) + .catch(error => { + reject(error.message); inputElement.remove(); - // throw 'Upload failed'; - } - }; - - xhr.onerror = function() { - reject("Upload failed"); - inputElement.remove(); - // throw 'Upload failed'; - }; - - xhr.send(formData); + }); } else { reject("No file chosen"); inputElement.remove(); - // throw 'No file chosen'; } }); }); } } - Scratch.extensions.register(new Upload()); \ No newline at end of file + Scratch.extensions.register(new Upload()); +})(Scratch); From 9a929e75cb5d976cb1e0aa578dfcacc54495dcc6 Mon Sep 17 00:00:00 2001 From: ClaytonTDM Date: Mon, 17 Jul 2023 22:30:54 -0400 Subject: [PATCH 3/9] change id & use strict --- extensions/Clay/upload.js | 131 +++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 66 deletions(-) diff --git a/extensions/Clay/upload.js b/extensions/Clay/upload.js index 854131d176..4013ae0fca 100644 --- a/extensions/Clay/upload.js +++ b/extensions/Clay/upload.js @@ -1,69 +1,68 @@ -(function (Scratch) { -class Upload { - getInfo() { - return { - id: "uploadfile", - name: "Upload", - blocks: [ - { - opcode: "upload", - blockType: Scratch.BlockType.REPORTER, - text: "upload file to [url]", - arguments: { - url: { - type: Scratch.ArgumentType.STRING, - defaultValue: "https://store1.gofile.io/uploadFile", - }, - } - } - ] - }; - } - - upload(args) { - return new Promise((resolve, reject) => { - const inputElement = document.createElement("input"); - inputElement.type = "file"; - inputElement.style.display = "none"; - document.body.appendChild(inputElement); - - inputElement.click(); - - inputElement.addEventListener("change", function() { - if (this.files && this.files[0]) { - const formData = new FormData(); - formData.append("file", this.files[0], this.files[0].name); - - const options = { - body: formData, - method: 'POST', - mode: 'cors', +(function(Scratch) { + 'use strict'; + class Upload { + getInfo() { + return { + id: "clayuploadfile", + name: "Upload", + blocks: [{ + opcode: "upload", + blockType: Scratch.BlockType.REPORTER, + text: "upload file to [url]", + arguments: { + url: { + type: Scratch.ArgumentType.STRING, + defaultValue: "https://store1.gofile.io/uploadFile", + }, + } + }] }; - - Scratch.fetch(args.url, options) - .then(response => { - if (response.ok) { - return response.text(); - } else { - throw new Error("Upload failed"); - } - }) - .then(text => { - resolve(text); - inputElement.remove(); - }) - .catch(error => { - reject(error.message); - inputElement.remove(); - }); - } else { - reject("No file chosen"); - inputElement.remove(); - } - }); - }); + } + + upload(args) { + return new Promise((resolve, reject) => { + const inputElement = document.createElement("input"); + inputElement.type = "file"; + inputElement.style.display = "none"; + document.body.appendChild(inputElement); + + inputElement.click(); + + inputElement.addEventListener("change", function() { + if (this.files && this.files[0]) { + const formData = new FormData(); + formData.append("file", this.files[0], this.files[0].name); + + const options = { + body: formData, + method: 'POST', + mode: 'cors', + }; + + Scratch.fetch(args.url, options) + .then(response => { + if (response.ok) { + return response.text(); + } else { + throw new Error("Upload failed"); + } + }) + .then(text => { + resolve(text); + inputElement.remove(); + }) + .catch(error => { + reject(error.message); + inputElement.remove(); + }); + } else { + reject("No file chosen"); + inputElement.remove(); + } + }); + }); + } } - } - - Scratch.extensions.register(new Upload()); + + Scratch.extensions.register(new Upload()); })(Scratch); From d6a05ef4ee677658af9486c0f4a419cee7114bf3 Mon Sep 17 00:00:00 2001 From: ClaytonTDM Date: Mon, 17 Jul 2023 23:14:20 -0400 Subject: [PATCH 4/9] Add new upload block with dropdown (only one option for now) --- extensions/Clay/upload.js | 68 ++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/extensions/Clay/upload.js b/extensions/Clay/upload.js index 4013ae0fca..b0fc2fe3e4 100644 --- a/extensions/Clay/upload.js +++ b/extensions/Clay/upload.js @@ -1,25 +1,70 @@ (function(Scratch) { 'use strict'; + + const getGofileServer = async () => { + try { + const response = await fetch('https://api.gofile.io/getServer'); + if (!response.ok) { + throw new Error('HTTP error ' + response.status); + } + const serverData = await response.json(); + return `https://${serverData.data.server}.gofile.io/uploadFile`; + } catch (error) { + console.error('Failed to fetch Gofile server: ', error); + } + } + class Upload { getInfo() { return { id: "clayuploadfile", name: "Upload", - blocks: [{ - opcode: "upload", - blockType: Scratch.BlockType.REPORTER, - text: "upload file to [url]", - arguments: { - url: { - type: Scratch.ArgumentType.STRING, - defaultValue: "https://store1.gofile.io/uploadFile", - }, + blocks: [ + { + opcode: "upload", + blockType: Scratch.BlockType.REPORTER, + text: "upload file to [url]", + arguments: { + url: { + type: Scratch.ArgumentType.STRING, + defaultValue: "https://store1.gofile.io/uploadFile", + }, + } + }, + { + opcode: "uploadToGofile", + blockType: Scratch.BlockType.REPORTER, + text: "upload file to [url]", + arguments: { + url: { + type: Scratch.ArgumentType.STRING, + defaultValue: "gofile.io", + menu: 'websites' + }, + } } - }] + ], + menus: { + websites: { + acceptReporters: false, + items: ["gofile.io"] + } + } }; } upload(args) { + return this.performUpload(args.url); + } + + async uploadToGofile(args) { + if (args.url.toLowerCase() === 'gofile.io') { + args.url = await getGofileServer(); + } + return this.performUpload(args.url); + } + + performUpload(url) { return new Promise((resolve, reject) => { const inputElement = document.createElement("input"); inputElement.type = "file"; @@ -39,7 +84,8 @@ mode: 'cors', }; - Scratch.fetch(args.url, options) + // @ts-ignore + Scratch.fetch(url, options) .then(response => { if (response.ok) { return response.text(); From a26026e1b95952cb4ff85bc733cf60b668a6a661 Mon Sep 17 00:00:00 2001 From: ClaytonTDM Date: Wed, 19 Jul 2023 10:49:58 -0400 Subject: [PATCH 5/9] Return only link, add file.io --- extensions/Clay/upload.js | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/extensions/Clay/upload.js b/extensions/Clay/upload.js index b0fc2fe3e4..e7cdb8e316 100644 --- a/extensions/Clay/upload.js +++ b/extensions/Clay/upload.js @@ -1,9 +1,9 @@ (function(Scratch) { 'use strict'; - + const getGofileServer = async () => { try { - const response = await fetch('https://api.gofile.io/getServer'); + const response = await Scratch.fetch('https://api.gofile.io/getServer'); if (!response.ok) { throw new Error('HTTP error ' + response.status); } @@ -13,7 +13,7 @@ console.error('Failed to fetch Gofile server: ', error); } } - + class Upload { getInfo() { return { @@ -29,10 +29,10 @@ type: Scratch.ArgumentType.STRING, defaultValue: "https://store1.gofile.io/uploadFile", }, - } + }, }, { - opcode: "uploadToGofile", + opcode: "uploadToWebsite", blockType: Scratch.BlockType.REPORTER, text: "upload file to [url]", arguments: { @@ -47,24 +47,30 @@ menus: { websites: { acceptReporters: false, - items: ["gofile.io"] + items: ["gofile.io", "file.io"] } } }; } upload(args) { - return this.performUpload(args.url); + return this.performUpload(args.url, true); } - async uploadToGofile(args) { - if (args.url.toLowerCase() === 'gofile.io') { - args.url = await getGofileServer(); + async uploadToWebsite(args) { + let url; + switch(args.url.toLowerCase()){ + case 'gofile.io': + url = await getGofileServer(); + break; + case 'file.io': + url = 'https://file.io/'; + break; } - return this.performUpload(args.url); + return this.performUpload(url, false); } - performUpload(url) { + performUpload(url, rawJson = false) { return new Promise((resolve, reject) => { const inputElement = document.createElement("input"); inputElement.type = "file"; @@ -84,17 +90,17 @@ mode: 'cors', }; - // @ts-ignore Scratch.fetch(url, options) .then(response => { if (response.ok) { - return response.text(); + return response.json(); } else { throw new Error("Upload failed"); } }) - .then(text => { - resolve(text); + .then(data => { + const result = rawJson ? JSON.stringify(data) : data.link || data.data.downloadPage; + resolve(result); inputElement.remove(); }) .catch(error => { From 9d50411d5b5f36164cdfc0d8874edb6906bbb8fb Mon Sep 17 00:00:00 2001 From: ClaytonTDM Date: Thu, 20 Jul 2023 00:02:04 -0400 Subject: [PATCH 6/9] linter warnings --- extensions/Clay/upload.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/Clay/upload.js b/extensions/Clay/upload.js index e7cdb8e316..76bf49f84e 100644 --- a/extensions/Clay/upload.js +++ b/extensions/Clay/upload.js @@ -12,7 +12,7 @@ } catch (error) { console.error('Failed to fetch Gofile server: ', error); } - } + }; class Upload { getInfo() { @@ -59,7 +59,7 @@ async uploadToWebsite(args) { let url; - switch(args.url.toLowerCase()){ + switch (args.url.toLowerCase()){ case 'gofile.io': url = await getGofileServer(); break; From 32449adac95a6db8fa9791270c6b2dbf35b61d25 Mon Sep 17 00:00:00 2001 From: Muffin Date: Sat, 26 Aug 2023 22:40:52 -0500 Subject: [PATCH 7/9] format, modernize, some nits --- extensions/Clay/upload.js | 225 ++++++++++++++++++++------------------ 1 file changed, 117 insertions(+), 108 deletions(-) diff --git a/extensions/Clay/upload.js b/extensions/Clay/upload.js index 76bf49f84e..a9727985ee 100644 --- a/extensions/Clay/upload.js +++ b/extensions/Clay/upload.js @@ -1,120 +1,129 @@ -(function(Scratch) { - 'use strict'; +// Name: Upload +// ID: clayuploadfile +// Description: Upload files to web servers. +// By: ClaytonTDM - const getGofileServer = async () => { - try { - const response = await Scratch.fetch('https://api.gofile.io/getServer'); - if (!response.ok) { - throw new Error('HTTP error ' + response.status); - } - const serverData = await response.json(); - return `https://${serverData.data.server}.gofile.io/uploadFile`; - } catch (error) { - console.error('Failed to fetch Gofile server: ', error); - } - }; +(function (Scratch) { + "use strict"; - class Upload { - getInfo() { - return { - id: "clayuploadfile", - name: "Upload", - blocks: [ - { - opcode: "upload", - blockType: Scratch.BlockType.REPORTER, - text: "upload file to [url]", - arguments: { - url: { - type: Scratch.ArgumentType.STRING, - defaultValue: "https://store1.gofile.io/uploadFile", - }, - }, - }, - { - opcode: "uploadToWebsite", - blockType: Scratch.BlockType.REPORTER, - text: "upload file to [url]", - arguments: { - url: { - type: Scratch.ArgumentType.STRING, - defaultValue: "gofile.io", - menu: 'websites' - }, - } - } - ], - menus: { - websites: { - acceptReporters: false, - items: ["gofile.io", "file.io"] - } - } - }; - } + const getGofileServer = async () => { + try { + const response = await Scratch.fetch("https://api.gofile.io/getServer"); + if (!response.ok) { + throw new Error("HTTP error " + response.status); + } + const serverData = await response.json(); + return `https://${serverData.data.server}.gofile.io/uploadFile`; + } catch (error) { + console.error("Failed to fetch Gofile server: ", error); + } + }; - upload(args) { - return this.performUpload(args.url, true); - } + class Upload { + getInfo() { + return { + id: "clayuploadfile", + name: "Upload", + blocks: [ + { + opcode: "upload", + blockType: Scratch.BlockType.REPORTER, + text: "upload file to [url]", + arguments: { + url: { + type: Scratch.ArgumentType.STRING, + defaultValue: "https://store1.gofile.io/uploadFile", + }, + }, + }, + { + opcode: "uploadToWebsite", + blockType: Scratch.BlockType.REPORTER, + text: "upload file to [url]", + arguments: { + url: { + type: Scratch.ArgumentType.STRING, + defaultValue: "gofile.io", + menu: "websites", + }, + }, + }, + ], + menus: { + websites: { + acceptReporters: false, + items: ["gofile.io", "file.io"], + }, + }, + }; + } - async uploadToWebsite(args) { - let url; - switch (args.url.toLowerCase()){ - case 'gofile.io': - url = await getGofileServer(); - break; - case 'file.io': - url = 'https://file.io/'; - break; - } - return this.performUpload(url, false); - } + upload(args) { + return this.performUpload(args.url, true); + } - performUpload(url, rawJson = false) { - return new Promise((resolve, reject) => { - const inputElement = document.createElement("input"); - inputElement.type = "file"; - inputElement.style.display = "none"; - document.body.appendChild(inputElement); + async uploadToWebsite(args) { + let url; + switch (args.url.toLowerCase()) { + case "gofile.io": + url = await getGofileServer(); + break; + case "file.io": + url = "https://file.io/"; + break; + default: + return "invalid host"; + } + return this.performUpload(url, false); + } + + performUpload(url, rawJson = false) { + return new Promise((resolve, reject) => { + const inputElement = document.createElement("input"); + inputElement.type = "file"; + inputElement.style.display = "none"; + document.body.appendChild(inputElement); - inputElement.click(); + inputElement.click(); - inputElement.addEventListener("change", function() { - if (this.files && this.files[0]) { - const formData = new FormData(); - formData.append("file", this.files[0], this.files[0].name); + inputElement.addEventListener("change", function () { + if (this.files && this.files[0]) { + const formData = new FormData(); + formData.append("file", this.files[0], this.files[0].name); - const options = { - body: formData, - method: 'POST', - mode: 'cors', - }; + const options = { + body: formData, + method: "POST", + mode: "cors", + }; - Scratch.fetch(url, options) - .then(response => { - if (response.ok) { - return response.json(); - } else { - throw new Error("Upload failed"); - } - }) - .then(data => { - const result = rawJson ? JSON.stringify(data) : data.link || data.data.downloadPage; - resolve(result); - inputElement.remove(); - }) - .catch(error => { - reject(error.message); - inputElement.remove(); - }); - } else { - reject("No file chosen"); - inputElement.remove(); - } - }); - }); - } + Scratch.fetch(url, options) + .then((response) => { + if (response.ok) { + return response.json(); + } else { + throw new Error("Upload failed"); + } + }) + .then((data) => { + const result = rawJson + ? JSON.stringify(data) + : data.link || data.data.downloadPage; + resolve(result); + inputElement.remove(); + }) + .catch((error) => { + reject(error.message); + inputElement.remove(); + }); + } else { + resolve("No file chosen"); + inputElement.remove(); + } + }); + }); } + } - Scratch.extensions.register(new Upload()); + Scratch.extensions.register(new Upload()); })(Scratch); From 7c37f42370abe07c9b0a6ddd19eb34e0c9c426ea Mon Sep 17 00:00:00 2001 From: ClaytonTDM Date: Sun, 27 Aug 2023 19:16:15 -0400 Subject: [PATCH 8/9] fix stuff, add direct input --- extensions/Clay/upload.js | 311 ++++++++++++++++++++++++-------------- 1 file changed, 200 insertions(+), 111 deletions(-) diff --git a/extensions/Clay/upload.js b/extensions/Clay/upload.js index a9727985ee..4a41426edd 100644 --- a/extensions/Clay/upload.js +++ b/extensions/Clay/upload.js @@ -3,127 +3,216 @@ // Description: Upload files to web servers. // By: ClaytonTDM -(function (Scratch) { - "use strict"; - - const getGofileServer = async () => { - try { - const response = await Scratch.fetch("https://api.gofile.io/getServer"); - if (!response.ok) { - throw new Error("HTTP error " + response.status); - } - const serverData = await response.json(); - return `https://${serverData.data.server}.gofile.io/uploadFile`; - } catch (error) { - console.error("Failed to fetch Gofile server: ", error); - } - }; - - class Upload { - getInfo() { - return { - id: "clayuploadfile", - name: "Upload", - blocks: [ - { - opcode: "upload", - blockType: Scratch.BlockType.REPORTER, - text: "upload file to [url]", - arguments: { - url: { - type: Scratch.ArgumentType.STRING, - defaultValue: "https://store1.gofile.io/uploadFile", - }, - }, - }, - { - opcode: "uploadToWebsite", - blockType: Scratch.BlockType.REPORTER, - text: "upload file to [url]", - arguments: { - url: { - type: Scratch.ArgumentType.STRING, - defaultValue: "gofile.io", - menu: "websites", - }, - }, - }, - ], - menus: { - websites: { - acceptReporters: false, - items: ["gofile.io", "file.io"], - }, - }, - }; - } +(function(Scratch) { + "use strict"; - upload(args) { - return this.performUpload(args.url, true); - } + const getGofileServer = async () => { + try { + const response = await Scratch.fetch("https://api.gofile.io/getServer"); + if (!response.ok) { + throw new Error("HTTP error " + response.status); + } + const serverData = await response.json(); + return `https://${serverData.data.server}.gofile.io/uploadFile`; + } catch (error) { + console.error("Failed to fetch Gofile server: ", error); + throw error; + } + }; - async uploadToWebsite(args) { - let url; - switch (args.url.toLowerCase()) { - case "gofile.io": - url = await getGofileServer(); - break; - case "file.io": - url = "https://file.io/"; - break; - default: - return "invalid host"; - } - return this.performUpload(url, false); - } + class Upload { + getInfo() { + return { + id: "clayuploadfile", + name: "Upload", + blocks: [{ + opcode: "upload", + blockType: Scratch.BlockType.REPORTER, + text: "upload file to [url]", + arguments: { + url: { + type: Scratch.ArgumentType.STRING, + defaultValue: "https://store1.gofile.io/uploadFile", + }, + }, + }, + { + opcode: "uploadToWebsite", + blockType: Scratch.BlockType.REPORTER, + text: "upload file to [url]", + arguments: { + url: { + type: Scratch.ArgumentType.STRING, + defaultValue: "gofile.io", + menu: "websites", + }, + }, + }, + { + opcode: "uploadData", + blockType: Scratch.BlockType.REPORTER, + text: "upload [data] to [url]", + arguments: { + data: { + type: Scratch.ArgumentType.STRING, + defaultValue: "Hello TurboWarp!", + }, + url: { + type: Scratch.ArgumentType.STRING, + defaultValue: "https://store1.gofile.io/uploadFile", + }, + }, + }, + { + opcode: "uploadDataToMenu", + blockType: Scratch.BlockType.REPORTER, + text: "upload [data] to [menu]", + arguments: { + data: { + type: Scratch.ArgumentType.STRING, + defaultValue: "Hello TurboWarp!", + }, + menu: { + type: Scratch.ArgumentType.STRING, + menu: "websites", + }, + }, + }, + ], + menus: { + websites: { + acceptReporters: false, + items: ["gofile.io", "file.io"], + }, + }, + }; + } + + upload(args) { + return this.performUpload(args.url, true); + } + + async uploadToWebsite(args) { + let url; + switch (args.url.toLowerCase()) { + case "gofile.io": + url = await getGofileServer(); + break; + case "file.io": + url = "https://file.io/"; + break; + default: + return "invalid host"; + } + return this.performUpload(url, false); + } + + uploadData(args) { + return this.performUploadWithData(args.data, args.url, "data.txt", true); + } + + uploadDataToMenu(args) { + let urlPromise; + switch (args.menu.toLowerCase()) { + case "gofile.io": + urlPromise = getGofileServer(); + break; + case "file.io": + urlPromise = Promise.resolve("https://file.io/"); + break; + default: + return "invalid host"; + } + + return urlPromise.then(url => { + return this.performUploadWithData(args.data, url, "data.txt", false); + }); + } + + + performUpload(url, rawJson = false) { + return new Promise((resolve, reject) => { + const inputElement = document.createElement("input"); + inputElement.type = "file"; + inputElement.style.display = "none"; + document.body.appendChild(inputElement); + + inputElement.click(); + + inputElement.addEventListener("cancel", function() { + resolve("Upload cancelled"); + inputElement.remove(); + }); + + inputElement.addEventListener("change", function() { + if (this.files && this.files[0]) { + const formData = new FormData(); + formData.append("file", this.files[0], "data.txt"); - performUpload(url, rawJson = false) { - return new Promise((resolve, reject) => { - const inputElement = document.createElement("input"); - inputElement.type = "file"; - inputElement.style.display = "none"; - document.body.appendChild(inputElement); + const options = { + body: formData, + method: "POST", + mode: "cors", + }; - inputElement.click(); + Scratch.fetch(url, options) + .then((response) => { + if (response.ok) { + return response.json(); + } else { + throw new Error("Upload failed"); + } + }) + .then((data) => { + const result = rawJson ? + JSON.stringify(data) : + data.link || data.data.downloadPage; + resolve(result); + inputElement.remove(); + }) + .catch((error) => { + reject(error.message); + inputElement.remove(); + }); + } else { + resolve("No file chosen"); + inputElement.remove(); + } + }); + }); + } - inputElement.addEventListener("change", function () { - if (this.files && this.files[0]) { + performUploadWithData(data, url, fileName, rawJson = false) { const formData = new FormData(); - formData.append("file", this.files[0], this.files[0].name); + formData.append("file", new Blob([data]), fileName); const options = { - body: formData, - method: "POST", - mode: "cors", + body: formData, + method: "POST", + mode: "cors", }; - Scratch.fetch(url, options) - .then((response) => { - if (response.ok) { - return response.json(); - } else { - throw new Error("Upload failed"); - } - }) - .then((data) => { - const result = rawJson - ? JSON.stringify(data) - : data.link || data.data.downloadPage; - resolve(result); - inputElement.remove(); - }) - .catch((error) => { - reject(error.message); - inputElement.remove(); - }); - } else { - resolve("No file chosen"); - inputElement.remove(); - } - }); - }); + return new Promise((resolve, reject) => { + Scratch.fetch(url, options) + .then((response) => { + if (response.ok) { + return response.json(); + } else { + throw new Error("Upload failed"); + } + }) + .then((data) => { + const result = rawJson ? + JSON.stringify(data) : + data.link || data.data.downloadPage; + resolve(result); + }) + .catch((error) => { + reject(error.message); + }); + }); + } } - } - Scratch.extensions.register(new Upload()); + Scratch.extensions.register(new Upload()); })(Scratch); From eb1654c8518b3d4a378e36250b234170446ba676 Mon Sep 17 00:00:00 2001 From: ClaytonTDM Date: Sun, 27 Aug 2023 19:18:09 -0400 Subject: [PATCH 9/9] prettier --- extensions/Clay/upload.js | 408 +++++++++++++++++++------------------- 1 file changed, 204 insertions(+), 204 deletions(-) diff --git a/extensions/Clay/upload.js b/extensions/Clay/upload.js index 4a41426edd..a01c42e679 100644 --- a/extensions/Clay/upload.js +++ b/extensions/Clay/upload.js @@ -3,216 +3,216 @@ // Description: Upload files to web servers. // By: ClaytonTDM -(function(Scratch) { - "use strict"; - - const getGofileServer = async () => { - try { - const response = await Scratch.fetch("https://api.gofile.io/getServer"); - if (!response.ok) { - throw new Error("HTTP error " + response.status); - } - const serverData = await response.json(); - return `https://${serverData.data.server}.gofile.io/uploadFile`; - } catch (error) { - console.error("Failed to fetch Gofile server: ", error); - throw error; - } - }; - - class Upload { - getInfo() { - return { - id: "clayuploadfile", - name: "Upload", - blocks: [{ - opcode: "upload", - blockType: Scratch.BlockType.REPORTER, - text: "upload file to [url]", - arguments: { - url: { - type: Scratch.ArgumentType.STRING, - defaultValue: "https://store1.gofile.io/uploadFile", - }, - }, - }, - { - opcode: "uploadToWebsite", - blockType: Scratch.BlockType.REPORTER, - text: "upload file to [url]", - arguments: { - url: { - type: Scratch.ArgumentType.STRING, - defaultValue: "gofile.io", - menu: "websites", - }, - }, - }, - { - opcode: "uploadData", - blockType: Scratch.BlockType.REPORTER, - text: "upload [data] to [url]", - arguments: { - data: { - type: Scratch.ArgumentType.STRING, - defaultValue: "Hello TurboWarp!", - }, - url: { - type: Scratch.ArgumentType.STRING, - defaultValue: "https://store1.gofile.io/uploadFile", - }, - }, - }, - { - opcode: "uploadDataToMenu", - blockType: Scratch.BlockType.REPORTER, - text: "upload [data] to [menu]", - arguments: { - data: { - type: Scratch.ArgumentType.STRING, - defaultValue: "Hello TurboWarp!", - }, - menu: { - type: Scratch.ArgumentType.STRING, - menu: "websites", - }, - }, - }, - ], - menus: { - websites: { - acceptReporters: false, - items: ["gofile.io", "file.io"], - }, - }, - }; - } - - upload(args) { - return this.performUpload(args.url, true); - } - - async uploadToWebsite(args) { - let url; - switch (args.url.toLowerCase()) { - case "gofile.io": - url = await getGofileServer(); - break; - case "file.io": - url = "https://file.io/"; - break; - default: - return "invalid host"; - } - return this.performUpload(url, false); - } - - uploadData(args) { - return this.performUploadWithData(args.data, args.url, "data.txt", true); - } - - uploadDataToMenu(args) { - let urlPromise; - switch (args.menu.toLowerCase()) { - case "gofile.io": - urlPromise = getGofileServer(); - break; - case "file.io": - urlPromise = Promise.resolve("https://file.io/"); - break; - default: - return "invalid host"; - } +(function (Scratch) { + "use strict"; + + const getGofileServer = async () => { + try { + const response = await Scratch.fetch("https://api.gofile.io/getServer"); + if (!response.ok) { + throw new Error("HTTP error " + response.status); + } + const serverData = await response.json(); + return `https://${serverData.data.server}.gofile.io/uploadFile`; + } catch (error) { + console.error("Failed to fetch Gofile server: ", error); + throw error; + } + }; + + class Upload { + getInfo() { + return { + id: "clayuploadfile", + name: "Upload", + blocks: [ + { + opcode: "upload", + blockType: Scratch.BlockType.REPORTER, + text: "upload file to [url]", + arguments: { + url: { + type: Scratch.ArgumentType.STRING, + defaultValue: "https://store1.gofile.io/uploadFile", + }, + }, + }, + { + opcode: "uploadToWebsite", + blockType: Scratch.BlockType.REPORTER, + text: "upload file to [url]", + arguments: { + url: { + type: Scratch.ArgumentType.STRING, + defaultValue: "gofile.io", + menu: "websites", + }, + }, + }, + { + opcode: "uploadData", + blockType: Scratch.BlockType.REPORTER, + text: "upload [data] to [url]", + arguments: { + data: { + type: Scratch.ArgumentType.STRING, + defaultValue: "Hello TurboWarp!", + }, + url: { + type: Scratch.ArgumentType.STRING, + defaultValue: "https://store1.gofile.io/uploadFile", + }, + }, + }, + { + opcode: "uploadDataToMenu", + blockType: Scratch.BlockType.REPORTER, + text: "upload [data] to [menu]", + arguments: { + data: { + type: Scratch.ArgumentType.STRING, + defaultValue: "Hello TurboWarp!", + }, + menu: { + type: Scratch.ArgumentType.STRING, + menu: "websites", + }, + }, + }, + ], + menus: { + websites: { + acceptReporters: false, + items: ["gofile.io", "file.io"], + }, + }, + }; + } + + upload(args) { + return this.performUpload(args.url, true); + } + + async uploadToWebsite(args) { + let url; + switch (args.url.toLowerCase()) { + case "gofile.io": + url = await getGofileServer(); + break; + case "file.io": + url = "https://file.io/"; + break; + default: + return "invalid host"; + } + return this.performUpload(url, false); + } - return urlPromise.then(url => { - return this.performUploadWithData(args.data, url, "data.txt", false); - }); - } - - - performUpload(url, rawJson = false) { - return new Promise((resolve, reject) => { - const inputElement = document.createElement("input"); - inputElement.type = "file"; - inputElement.style.display = "none"; - document.body.appendChild(inputElement); - - inputElement.click(); - - inputElement.addEventListener("cancel", function() { - resolve("Upload cancelled"); - inputElement.remove(); - }); - - inputElement.addEventListener("change", function() { - if (this.files && this.files[0]) { - const formData = new FormData(); - formData.append("file", this.files[0], "data.txt"); - - const options = { - body: formData, - method: "POST", - mode: "cors", - }; - - Scratch.fetch(url, options) - .then((response) => { - if (response.ok) { - return response.json(); - } else { - throw new Error("Upload failed"); - } - }) - .then((data) => { - const result = rawJson ? - JSON.stringify(data) : - data.link || data.data.downloadPage; - resolve(result); - inputElement.remove(); - }) - .catch((error) => { - reject(error.message); - inputElement.remove(); - }); - } else { - resolve("No file chosen"); - inputElement.remove(); - } - }); - }); - } - - performUploadWithData(data, url, fileName, rawJson = false) { + uploadData(args) { + return this.performUploadWithData(args.data, args.url, "data.txt", true); + } + + uploadDataToMenu(args) { + let urlPromise; + switch (args.menu.toLowerCase()) { + case "gofile.io": + urlPromise = getGofileServer(); + break; + case "file.io": + urlPromise = Promise.resolve("https://file.io/"); + break; + default: + return "invalid host"; + } + + return urlPromise.then((url) => { + return this.performUploadWithData(args.data, url, "data.txt", false); + }); + } + + performUpload(url, rawJson = false) { + return new Promise((resolve, reject) => { + const inputElement = document.createElement("input"); + inputElement.type = "file"; + inputElement.style.display = "none"; + document.body.appendChild(inputElement); + + inputElement.click(); + + inputElement.addEventListener("cancel", function () { + resolve("Upload cancelled"); + inputElement.remove(); + }); + + inputElement.addEventListener("change", function () { + if (this.files && this.files[0]) { const formData = new FormData(); - formData.append("file", new Blob([data]), fileName); + formData.append("file", this.files[0], "data.txt"); const options = { - body: formData, - method: "POST", - mode: "cors", + body: formData, + method: "POST", + mode: "cors", }; - return new Promise((resolve, reject) => { - Scratch.fetch(url, options) - .then((response) => { - if (response.ok) { - return response.json(); - } else { - throw new Error("Upload failed"); - } - }) - .then((data) => { - const result = rawJson ? - JSON.stringify(data) : - data.link || data.data.downloadPage; - resolve(result); - }) - .catch((error) => { - reject(error.message); - }); - }); - } + Scratch.fetch(url, options) + .then((response) => { + if (response.ok) { + return response.json(); + } else { + throw new Error("Upload failed"); + } + }) + .then((data) => { + const result = rawJson + ? JSON.stringify(data) + : data.link || data.data.downloadPage; + resolve(result); + inputElement.remove(); + }) + .catch((error) => { + reject(error.message); + inputElement.remove(); + }); + } else { + resolve("No file chosen"); + inputElement.remove(); + } + }); + }); + } + + performUploadWithData(data, url, fileName, rawJson = false) { + const formData = new FormData(); + formData.append("file", new Blob([data]), fileName); + + const options = { + body: formData, + method: "POST", + mode: "cors", + }; + + return new Promise((resolve, reject) => { + Scratch.fetch(url, options) + .then((response) => { + if (response.ok) { + return response.json(); + } else { + throw new Error("Upload failed"); + } + }) + .then((data) => { + const result = rawJson + ? JSON.stringify(data) + : data.link || data.data.downloadPage; + resolve(result); + }) + .catch((error) => { + reject(error.message); + }); + }); } + } - Scratch.extensions.register(new Upload()); + Scratch.extensions.register(new Upload()); })(Scratch);