From f759f91cf5694b86156570c922e623d43b144fe0 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Mon, 11 Feb 2013 14:28:23 +0100 Subject: [PATCH 001/118] Show the correct URL for recent ownCloud instances. --- ampache/config.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ampache/config.ui b/ampache/config.ui index 5bddd082e..aed9f47be 100644 --- a/ampache/config.ui +++ b/ampache/config.ui @@ -47,7 +47,7 @@ For owncloud installs, server url is -http://[owncloud url]/apps/media +http://[owncloud url]/remote.php/ampache Qt::AlignCenter From 5210570d97a20c07207fe824930fc03dd0fb444b Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Tue, 12 Feb 2013 14:52:58 +0100 Subject: [PATCH 002/118] Merge branch 'master', remote-tracking branch 'upstream/master' From e7286be47099f44567c749e022f4b2577c2a5c68 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 12 Feb 2013 19:28:13 +0100 Subject: [PATCH 003/118] Don't fail if the server doesn't fill out album["album"]. --- subsonic/subsonic.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsonic/subsonic.js b/subsonic/subsonic.js index 4a43d6372..36ab70e15 100644 --- a/subsonic/subsonic.js +++ b/subsonic/subsonic.js @@ -278,7 +278,7 @@ var SubsonicResolver = Tomahawk.extend(TomahawkResolver, { { if (albums[i].artist.toLowerCase() === artist.toLowerCase()) //search2 does partial matches { - results.push(albums[i].album) + results.push(albums[i].title) } } } @@ -286,7 +286,7 @@ var SubsonicResolver = Tomahawk.extend(TomahawkResolver, { { if (albums.artist.toLowerCase() === artist.toLowerCase()) { - results.push(albums.album); + results.push(albums.title); } } From e94fd59e7c9c8bd787d159ebc038955ace354024 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Wed, 13 Feb 2013 14:53:38 +0100 Subject: [PATCH 004/118] Add empty resolver for Dropbox. --- dropbox/config.ui | 77 ++++++++++++++++++++++++++++++++++++++++++++ dropbox/dropbox.js | 45 ++++++++++++++++++++++++++ dropbox/dropbox.png | Bin 0 -> 45123 bytes 3 files changed, 122 insertions(+) create mode 100644 dropbox/config.ui create mode 100644 dropbox/dropbox.js create mode 100755 dropbox/dropbox.png diff --git a/dropbox/config.ui b/dropbox/config.ui new file mode 100644 index 000000000..73d05cb09 --- /dev/null +++ b/dropbox/config.ui @@ -0,0 +1,77 @@ + + + DropboxConfig + + + + 0 + 0 + 410 + 436 + + + + Form + + + + + 20 + 150 + 361 + 251 + + + + + + + + + false + + + Delete + + + false + + + false + + + + + + + Nd + + + + + + + Associate + + + false + + + + + + + Account : + + + + + + + + + + + + + diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js new file mode 100644 index 000000000..9a373b528 --- /dev/null +++ b/dropbox/dropbox.js @@ -0,0 +1,45 @@ +var DropboxResolver = Tomahawk.extend(TomahawkResolver, { + + settings: { + name: 'Dropbox', + weight: 60, + icon : 'dropbox.png', + timeout: 15 + }, + + getConfigUi: function () { + var uiData = Tomahawk.readBase64("config.ui"); + return { + + "widget": uiData, + fields: [/*{ + name: "username", + widget: "usernameLineEdit", + property: "text" + }, { + name: "password", + widget: "passwordLineEdit", + property: "text" + }, */], + images: [{ + "dropbox.png": Tomahawk.readBase64("dropbox.png") + }, ] + }; + }, + + newConfigSaved: function () { + //Tomahawk.log("Trying to open a webpage"); + //Tomahawk.openURL("http://google.fr"); + //window.open("http://google.fr"); + //Tomahawk.log("Page opened"); + }, + + resolve: function (qid, artist, album, title) { + //this.doSearchOrResolve(qid, title, 1); + }, + search: function (qid, searchString) { + //this.doSearchOrResolve(qid, searchString, 15); + } +}); + +Tomahawk.resolver.instance = DropboxResolver; diff --git a/dropbox/dropbox.png b/dropbox/dropbox.png new file mode 100755 index 0000000000000000000000000000000000000000..f8810b451bb5b550e71029214ea8b73115dfbb66 GIT binary patch literal 45123 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

I1o~QDv9PU-bvp?`* z;FHPBq7O6OQYR|5QN2Zx2S}G;sA+`p_6%OJ&17Hd!G-9A(0aDZV$|uNVf`iP5Rn&L z&BRZ>GGZp)`&|v4kfq@Pn{VO98XHcNA1A+ulZ7*glqFoGxY@zJVF7tnxvsxcI^23| zD`*zv8AjYP`3vJnW>Z&QjI7f18es^*#od8a=WTU*!$%}d5|C57Z+aw-#t6m!4m!Wf z%kqWjanev7>BhVC8p1m0_E2?U{K6QkDT^T^M72c;b3c{GnJmh}cVSys$49v|{v7D@ zL92?d!k&N42jN0=nMX9b~-$%j*u|@Py6}?V$Lesxi{LT2sPQ$^>*}y`XXi2l%bSY1&75? z>5%Nrcji0LiouvTobA$&kb*nKjUk3e zN*r69eAI{gj(^@`CW3FmE?CjbMDib^2Qr7NSlJqNE6=`mXcF}6c)De6#}-0{td+Sk z6F8Bn_r#G!Ft3yzKdUh@S4y*>KGO}QJ<=a65BD+Q()9ij!L>oB!FfvM?W_76nfcqY z@-XETP4p>1`O=+~H0{FIZ3h7JrhGSPh=9QXuJ$LdK5Ng zfXMZIYZ|>_wyUhCH}U+jv?-7_oo427$w~%r@hjv4wcn`l%p$uqm=?yDz&Y8q+w&#U z%K)mVn^^EjjddnG%}{ua;3*diskl}##*{2T81JSG1GK7}J5008T}q8bGWdthupU2d z`3E-hdcB~2FaP-Lk}$vMNC}AL*~q<#M@7?JL0ix7^^(p0V_!a#O^cC;yU^VIU|{Cy zkV_|j7||we<0KwIXq%0>iTFaJdMOqvJMwuEk9B>)rD@MXcb-{6ZL4D}1q|-*G^u{c zbi=nT8Mitag5i+RA^4jMh-pscsiZ#gr0sY!@5A8K^`E9`O7@+%z)tX>{k0gLG;<52 zMeU*qcsQ%+aMk}}ba>b7$2HTiLlFPu#O_Lk+2Aih+HCQ%5gpoyXw}Q5>I|%IcP?%% zBMNde+nPT`-}E*Hw>5bRx4^nmYAEwl;*pKMeeh~UZIc*#5|7S)9f#ah0-6utm$W(2 z%wE;SE#{rg1rvb7XTGNvz;iDt-98`G8S*U;EboQb(kJCA8CD+uXuvuG*%bcpgouJs z!wy}P{=6Q5zU5@cMGDzx6QeecEu>E1-sNzd9;&-tX6!fDtZ7dKZG;P0`Vw=kr++fQ ztjre<8b_3h7aFM@X{i$_OKB=5heA=$o78~7j)a@D3`i)|15;T%$ukW0w%U6f!m=i}Qw%`IRd>M$3J&h2V!|Ro-wF zO{9I?6&m0w-#7maNbzfIeTwy`%#+?SWWkcm9vVNiPC+S0nK7aXO;^~81~GEzG(m7W z7wSET4X7q}TJu*xOLFExPeQ{vUWru?_Q4WZK6-$deQwYDi~q6qZ!%yI-g@4$Q#2%y zHDuzG7P`q?od!T&Zqus8eQ7GI+2`e>HODgk1jiJH9NFz5`YV7jMPy(7Fs81KQCKd< z(w3mYp?=LBt!nd7fbaNYWyoPUstNqr7v?eploxs@kHSH5igD(n(|}yr39f_Wf~OUL z=fIB!@-%@F-Unu1Mkbbc1!mE?YHjnQVZhsAZSuNhk=g7VTc|DSc79Mk$8EF{(1Zbr zTgWXrMP|oX1Y5M#3*GLxM$aGY^6+!ejN16I%@doNUMUS4=^pB9d~rd%;JZX1~$1Go`DbwB$(LKQRPOWo2x zNkTS_em&^rNtUfY<1r*u@!CTsP|+MW>;Rh%5wn8BB}jruZ@f_8f|F^*wx$@=g~-+R z=+Vb&F%X`tX|EgZ%!w8BO{CanQ^tP%H)GHZCwcFmf^Gd(_$oc~j}_TO_)<_^X-_m8 z_3raN9a( z?ZVdK5Ir||P+4kZByzu`Gm|Aducu;@eq5AW#oA$BUM!5`^(EEr5E#l*Kv*K~u5)1*;eQqmYz~omMKlP!&YmD&iJW|H z)1=5kMTZ9*VRX}jYX79OL|*R!jkp6D1Df@)u1zOLx#M}GlSymYgYfptu6FL?y?{@| zy-@sIWnep`jr|W0_L(XX{F*!D;7fx(vmkRmC5*i~Oku9MDr+c;`7qDA7W6ZOT)})< z<99mCh}v%8oF{i+K0ifW6^ofKva1;y{{?!>xl!nqc2)Se>rn~g_ps`V1ueX7wk)K`d(>?~&NN%L?Gm@`43=?(ZIjbiaBo>z-YP?E5Gj&`;p3T$*{IZ9A#evC z*7^0W6zqougLGrT(;t;}Y5lO=QXGT>{z`s^R0nz!xI{;>9U*Rc2N=RFjCBzT*V^0H zgQ`C0oye04INnz1seq72pRm^)g;jqJU_{Fr?{ zH($o8)IKgxC88gkZ$ME>aa|~qj}w6?%G_%cw>x3mZeB(x+T~drhzzG zDJ#lP>Pku;K2Z@;YRT*Ug#2|(yp3>I2Th_`uFn{GM%_Ftoq@b=Vd|6QG%)(6ud%?_ z*AM#GcSHmZk1J6;wb&^+=TG7-TMDZ}u~?W8@cGJ+$<&Q*O(d(_(Nc+*-RhC?lw^KX|E7la6qAO*ZsByDgG!h|>T`dpR@ zpr+^v4QWsA?6lBYUMJ%?W4CT6OH3b&>RnfWB*ZOi-ZlVsYfCcDlndb%afto3;F+I9 z2g-g!Hnv%2zf(gEwl+4gzh3(T=Ecx`Vb?*od0$Lwu~YLXl%> zLtu5Fw^KRrrVipT*)x9%CFpF1Yo{&mA-!X_Dy>*@0sjcDA2`DDC}cq&X&MQl1LwSh zz*8jJN-@H2b{fepU{7WChKlp(qfumS;q#&v?VD2iGuWEWMeenX-KJo!T>pYGx#3S5 zxe7x5c;@UTX9!PNkwgM&_LQkPg2po1Azdd?R7c41hus@1sErRlt;UjYS<8i38D!Vz z9KNU|X9!S!p4!B(Euo<$Ar@pX?BN2^CZ?iq?~`!rEfHLW>YHB(lB&sr5&k& zh!e`&&2%!&u3yt&uRsljK;70~Z|n`_$Y@^>v+=}>C1jm7E4EIF`|8T$Ya+AE6^RS*BWZfm9#@Ht&=bI_swLWXINfVkPB^}P5O|qTJF^|PZ`lX zRQ1$29upnDKVIV;HUk_lCN27;YLb3Y?$^J9MsOSEW9|{UiaC&-d8>xWGajX)Nj>m| zK46xv_wZf_sxvzQon89ZpmYg?V?Y4E9%CK$J)|M+AK-*^hZ=SFm*r%-<@f0+jhgHX zCt3sHGA5QN9YWEDDYXyU>*UiZjYS)|YTrF+2+M&hJYmgx$-6yo@g(kpB0!OnY&nqP z@BPvdl>fnFJ>5SahbEHSV}&F01qQ}(ZtB6_fpHuQK>SrE2ee1~t)E*2@jYHo{W3jK z-V9Z=C@t~`u@J)q>@VQBfzo z3~^I?MmrIFuv$+4EAND*42 zZ2cij&s-VI`y*mYartIgKb8bj5C@s8RdBfclbqqLcwSYsHy7Z<5Bg?I{rkB!7(lK5 z2_@hv(oz}jG%EF?<8Z8qX2DFb81c887>fm3usv+~3XOAqx2JN)6b2VM*qe~e)0wKn z%D&GjZNJ2qtC=)HkZ*fPM~dF+mJx6NrEI@#556~$>+xup$%FL94306xr4MTOm6Z!` zly=P0F)c$Rqt$=sPv8lCfSZH|54C#j7%%>|gy#M|w3J9o?rBJSosWDDLqqC@BzR>a zJ~q2s-O%t&RV;?<#~)DT0|8vu9o%SaS3Jk%9|&YP{R$y6U&+ke69@1iX1i(^G{v*eV7CM$*11g_tw<0N)??k&g}MQB%cG5@t|7^kXp zo0?WC-bR$Ex}}(ro41@l73H5MI{U!yPaWwe|3Hd;Dh|5Uw^o18jWV(@`_9PZhr_S{ zqPkkCm@X2ez-oUTT?Grj#Uv7}33l4+0kg%!m6bZX|jP2kimkuy1%w z^A3dLlt+|@Cx2nrV&_gok@o_P{*>p57J?e>!|r{)=>1e2Fp)GRAv67fYqppp#P~I_ zQ)~%8F$yevC1rU0XyZLR1vKcOH*rbZPle~=zbNNaz21W>%vnn=>DC;bxe&T|n(>?b zL=(IAV&f^Ac;qWvIEXe*bHpo#N-A9kZ>Zv3tNGX4XlynoxVs{sCB6<8>Yk73ga36C zf~4sYQelk=g&@bAN1783FM9H#kA1U-Xe|!q=C+PQi|$%Lh?OE!sG`+pSWW8>Ctz=bc)7_uHu1HL`Fxhb6V`sq|jrp)eT& zsgXpL*?2ve{W(Y(11S__sFRu#@SIf^g}MmT#PpcJO;mAD#7~WIc+I z+~ktDOya&DatqLAN@il$J;o~xC9JE0E|%=m$3(%^BPiYfrsL*y$`Mv^igq*}P6*F_ z2kd+RVK+|x*`b7R&f!B+qu`q!5Z4;2duSLwnV>yc_$e@r633l^T>`f^c0tPLKhFer zhqaH%1x{rhzfO!gTHm(hM(=ZKh<(hK?0c0~gKx&U77^GcibI12rU@{YDpKKVMhfBp zO|cajU^MeSKL0-6$H?ii%vquHaDw76KidlqHLd#B(iD-?O<;N!G~W>_56gNrRk4b+ z!c_43><8@Ddy`s@P($i3crks*f8mSI9C3-`K`A(_1Dqesqu^G%4F}RZ+G9dpX(BOS zqi&lEsNTFATj3(|IaumKVIkhT%4- zm&>{_T22K&Nbkd^+U;-u$oS9FZmvBGBzD1@H278RP?4QoOOZ#w&rdn4r5VIE9R%F#1 zUbA`s&*3Q^Mr;W#&G&S*35wveG0d3W(uX1upsIz7SoSQFJx5~yn@W+b&TM@)0$Gv7 zOD;Te0tVk{=|)6~%bl-j>_vsK{RX$nRo`e4S@Db>5R)$;CWp#)g(ecv8r4wZbL=#~ za%W-&oX(8ct_sL{&}g~)p?Fq;E{40GfrSV;`tWkO8@rpdV~MjQXyV5K;gQREs>`^8 zmTq8GX?r1`A*JBhl~C}I)Rx&YPXaOfSxs~rsX3n8KIv7!Ls(U|xthmU4+EQ#92sw7 znUj8AXSeC=fpfv82U(x1U)NwuUPLdRNsT_?8| zc{H}#n?$uuJlTGo)4OUQoI|SbqFHV53vT<52OA-)7@7h?+YqHt{REdQ7~l)5k6G#A zQ47td3E^gFeH`V{q;T-X&Kgmo`sy+Q^Tj)mCBr?64hADekh#oUEvtVZ*113o!jgF6 z+42w{_a7c0X{TPP4~sM8+^NHng?s9AxG zN4jBWd9gO1#kIZ~^<2rzT19_ep1N$MyOJC5Vh;%Z1ZfpzddT_RBoT8!+jJq@p(r+W z^poRrCF2n#OO-f+4A$kkar*r^TQNw~G)xsEEDB%OU9rUZpbGPTp~w5D>nK8)#yRyt zr{{4CXU5S@X9{No_EZMW4b0{g~0a1%~!20AcOCG!y__QGFea%t`@L-hHSY{WxRWO~YbO-aZvsD&VV zQL~~l0CoqL69m!&hh0R>Ln*`$0}q4Fk2?66yLi?$KP4Q&f0{%*9tPID@_IHBl9vdt zRSJ>ISP>?qxPq3ta|T7A%uawC)_&S`-7|%7*ytU#&%S}q+FSw|(4mhh0t@YvbD)I7 zKK~#fbR3am{=IuD^-fWfbRV~8>&3rpMw=9i0VGLp^j#M0WcgKgVyp9Z`<~Sh9%+A# zGh$TlOeA#3Y5qB4TtC(EBChpPyQfTEmWn&1P1i8>@z1NX>;SZ9V$EsDNAxX<_=@{fi{cMLL!QrIczU0py3l4nIgxVjWas3&J zx~5)d53Mn>a1)F;p_O_s7gpqw#7)WG3G7MB2O;;|s}M~zGmD=Ds)_g3w0j%Z6|@q_ z)}arW;2fwJ$YM)iBL+bpEDEvq?S^_Q=}mr}|0ev*@#|AzUd%f7sSunODiyx6&bXZx zF1%Wa#0Idt2fMfm{hjS;^z{`!}|-Ww>T?H=nz_-N%*>PZb@dxQ`sP zNu9^KAa+`o?^CvGAAKlrBA=8_CgwZCcRzuKaTf^C$pF2;et8!Ryt|Sf&yTep`|wTo zU(xX33%=lN%*bFWS?gpYAATilx<#mPKwX;2aoX+T4j&*5ojPh&{FI1^o`PE?zSVN~ zyD<67=fx*`IA|-`LxR)4NRwg|AuxH7=!P}40EK}y-Gns23<@`0S~DgZ0}PDBer1!$ zf{P3JL1VkL@`-y5ZwAz;Cd@f?DevheQb##vzJ+Kj$>;j*{MjDabfk>o6Y+PD9UQ9( zntK~s?&@yKWk^!dL95}!N7|?J$pC1(K|6MZnFMkxtRFU$>7(19yOXeEtd~NXScPzN zjRjSCk=j}3Qkg`dC%_p}I}kCecGYU8xh@oOK4>m^@X@*5 zfX11>eYM&Hyz~M7vnIOd{M-xj{1)XX4caygN+HS9Jr2V70VnohEqn>aK%?C##^;Oo zgb+Py7_aBIZXx>eVrAyDZ^8M*^mm}9p}JaO6DbclKF*>I+iK^10F6TsH95guIGP9I znsZ){Ju-84rCe&qa}NhwBiSR_ps1nXmVkaD>pj3l6j2Q6g;jODp-xm~|>!VJT``xrT(ux(FcUl@XcU8497z z=+DW7^i_<0QjshifE4`?sm%U7O&Om*c8@0#gJgrWeV~l?aG?OGb(>DLvnVe}jA9U) zvYROZkX55L(==pq!Skg#>*GmnA7*qh^;v@0%y%#L&vr*B%S&X_35`VtLJWanODX+> z-pBv2bXrV&!(!H9o5`YE59P+b_9w+elXtRV@jeVF8ZCJaxXe;bnwFAxb6fQF^L`-kXZ?&0~Xy``FbamjT16 ztTet>Z;GV0iiehhXhuDIr#S7mjt+Xq!*n3+!hX+pW9E5JxPJckSuV*zxmHJz{&r)+O(8B@9<&e z^Kow89gvC@NTJ;WoWc6R3_GfF`J=do`#EGwAiPTSkpOMaC5`&Bccy1!f4Prl>IJyO zI`8lTF06k`Pq({-oxc(-xFTqmByHms6P2a308RnWevnu)L2`jq$ha>T13ej2o36i5 zG}Q6bS?Kf%b%U!6Yos48U0ZAs1dx!39_$C8JhvvnQ6OPZDShSmt^eUqYOS{nSz)cQ zZB{X%AietBVe!GO=9u<^JCfaH43x*-rv9GIs#A0#-%<`%i$$lbeaaK7yL)WSH>yB z_V`*TdbkjR74~8!%kLG=Sn>;{@AcZtUfVt%(cyCswL6aae;l1?X{jWh!CNp^qNZ8MW@;# zd~1K6ptDTkJkXu_l)#jm=^QqPotf4env5+*o*$Nz(32-8o|Lw~TXs9Hvf&vVD5H)G z;bA@42ctA!-ceKbkQs{>r3ypgnM|ZxEj-pzfJ8&lBRrdYx9!VdZLmobojK5r8}rb+ zKt77=rx6w<`+OtmWfQVmT)=Z42o4)iVNhm-*c%UKrq$bEmE~qgx)62*OjIAA)KNW^ zK{q*z8v8SJb*Uyp3PN5_qJpt#EcrXJKqX&k>eSTRkISss8|+WH>#RWA7S(L^932|> zgN}dU{Qm|yhy&vI2i{=Ng?j^QxpMCCj{smIlPx&XF2~_Xp&-nEB%k-rcO<`3+o86c zXC-j>diMn~%>bq`zWcBSZzT7;aBh85mB9zNVSBBDd%L*conUIZG@?!i!_0UEzARW+ zLqCYzO}+bpD6^^o#lSmfk&PHz#aZ@&Z@GevzD`wJO=V+)KR02Iu($qitHD@>^(6o1 zyLmjLqMNB$M?gTFmdg%dyfwK-`LR@ttdTjb2{~R7;;RTWOAVU zeCMJ7LmtT>a_v{Lt?^Qj65zW|#{qN^m<#=`-%H{4Fe%kH+Eg4pb6=%%Zez8(bkgg8 zlNE6axj@!JEbPF8KOuEE<(-P0~-8Xs5e+OP(P zVe|nFh-Dtf?mvb?{0kvnz(8@%*B8Iq`9-;KU`6rQcP^-r%sp`?&Wk z;S{Us@nvRpde05)h|m!r^WKB#PqXYx_lQd9)W_$GM~_w;@qo%=gQOk`UAqCW%qWsXJyky&812(bxn{%)rX zvfdB@p|*ay{XN%;vr=IwVqSVhtQF{PgcWv;nuBqBruL_}v9Hl!c6^Y%bx~G0{6sRp zOz8l18r7}_1kp|m&L>7~*n2+-)mKjKDwsycvi0^0^~;Ep#98xprd8S2Q1~z`N} ztKC2ha)+BteH>ujVnVGYqnFxuyrq1wv8kKE>JSfys%mSJ1d0HW(XFG3wnUyUyqP9u zp7K_6TS>SAow-_!-=?V5kjLdsSKN@`wd$?BFLZ|UBH5JbA%1nBqvaad+*0C>n)Pbm z8N8CHOg^)R$l!aL+udE@T+sw_1%4{-p;!npv zjT39TW_$(Rk-zXK7FQah#OgHvj%OR@E3|Cc!MGt{*Dh-;JFZ&^sOo`Cml99$yD-`q zZw?mix;^2lC=c7Ia=)zoK0yqid|*!G_ZcmZMSYz54EKt;5I*xqvhgboH*K<_S!=EPsUTbyf)|(=O38Rr(7-I5|_hyyNB-r!!|D=>Yr8y zyp^WLodPER;x7scAPko@#k{hImh1HWif=$GZ*t)Uy%IjwPPI@RBWUh4_I{Zo$I6dw ze)&8)Skx=Rf@OzLAdsrw^!nXwo+QC+Exm*e2#l?(&37s4`e{s%^)kEm=1aB3lw`Ng z#4-c*PNqD&m?*rWi(*Sy!+wR2ieW5!PKz`|ERiOkhu#o6L}0;^eP z@fD&>QYrj{p)NsSkk*tw0(#~_o|oyVjd{VH%yzRL_j;m5%X$z;hxCfyL;*}~iZv3X zly8k%$AyPWH-DT3O%(SzUi!9bsDbf`=RCteC6cC}yy6y;1APV-fUq1Qp+;( z^DMO$sN={z)UQ1zfBwv%7s5Ib1&9Ett}XPMqP4$ZsE`8Sz1k-87ZqiI+|x?bOlc>U z7t`!{A2r_LMw1n-i~V`sjiq?n3^>n*i+HxLq0iUnD&o|i1Q3vR{+xaiXaW3bOdhWN z9raA+9==^Ka%N|egl@J|cqF0KXo370XvKm5446Qklz5VN-hFNVqmWZPkljxf?Pnmvx<4IXo<_Un$LL>*JRCY{vA76R2Kx$ zg+N~4bA7I8zEpGeK2`*^Vhx;tveXnUD3=kjJ<%iu$+z zi^{hb$nH_9z;;I5Xuo+Idz^kSr@8yDYA`oln1jWkJ$lupA01l1FSA8!GUqmx)|SF2 zWsQcUu_^N5X%lVPEx|vcM#LG!w_*;EQz-GQVI%HK2ExOez(g`__V>mc(3x(Mj+eKT zQV<0YmUB6w0-r91XM-#FDJj}j23U;x@AX2I6>r+>(cg)f2MK9aa654~KHW(CYg7y} zt!Pceg7gg+A}y}q~v67M)V(huk*u0S_)HAn*VYWoji zI!#N>rmvmAa~T@8#K{5p)r)?0}Lj;y#BX1~!Ls*l?m2 z_3V!0L0S{M6;(h>`#9H~?`=o11RvYk`2Nd7QX;%^IpaPABq{&~8Co*}C(WKc)Erq!UzK@oZqYKpzN*+<`J^};+0ua;xlv-_6U$yU5_-AsY*Ji z!24>|XDq@8#Iy2s)a4BYY)zwI?oo+%%{Qp~&xlqoOfjV(WNn2UCIGGp??KZTV^9Ue z&l`O%vG?mn2QbPe-P4yoe3;*>Kn83kP#wXqkzaVRd1nYeyFe6KB@0a}n9GB&H9U7O zLIg;(JR?>-=`GK*!iE-7%4-vEHJ~FLbMaI{)FoPLzY_)(Yr_jbjUPz1n^^0d$o$ zrD>N8AEX%A$|ZB}lcL>jGZeXgwX)zYVp_H_O-hQ(6%RNSWyQPalQ;4UmJRJ7WYU+l z)Dl@l|9=+(^f#}qU4Me%xHT1Bjc0iDc)rY7kPLe>;(@K^s*0J+K}b`K}_ z*hgX_vGKC8xc`(m_xH#Txr|h&GRc~JxAy+$9HH$nJfY65+;8|YPhf$#mFuN_L&U+g zp14gw#_PV%Aw+TK_mW8Wb!ysgZhMniP4+4DS0)#kI{=+{7lamkJNkG=Ke7stmx?eu zys3BX5o-!e9IT{hLZTOhiiTo-Fvl^VqL)UhYEnTnbPX?l;$sqjR2Kj;h_$eErAlV9J(T(voC$~$#C zH+;e9Ev;fxR8s%*Z74jV`rCfAI*KP1tD8M74G}3P6}rwW(md4-IRwy-M6WYx)hw<_ zce1YECd`|D0%e}}M0B0r3yb+KdQ?<~`d}otMqSx>sHZ80?kKVB$VFFmsw4%)zC|yN zQw#L~VmqucarvO5fro*r9#+CT5#qaig{CL@EG88O4P2LCw78E~z#}YQBoVdLDk#8uFb1{V@C-Wt`1LU8-K9CIfe10D&XTlq=}b16`3EaF zX~v*h3+O&&g7?A4VX{VZuibujJ5lx$Mo{!U!tbMRQ@CFAJio=wge5k;cFcR=BiV8} zW5Di$*lfaB^pt+6FWz3WdP-o-Gm*_q`R~}{*taxAm&2qR2}!{C83;8x8M5P^`A}VK zk!ZI?c^j=&HTU9@fU{L17i^c$mfoO|5q-U9NvVNtC4H-MYHM}kBQbNb!W;GqG6t&Y zV&l>@yuw&m6yT=)&*ANbDACvEW!>X$<63-0hfy2fU;)n|&?^b6hcsBr##PJFccQ;`mJ8J%qZW|bU+2f0hxxU$okKk zNnZZgH2*RSx+w4ZE3Z8WE&Q>jVZEq#jYAu+9N5Lq118ro1IR-poIV$jg*@NRtL(pK zj6vIY@d*-Yd;UgL+v*8vL%Pxu+@fLx79^@-dT1CcE>%4Pl#q=xX@Y*XsocL3p`ffj zrRe1dL1-g78Nk@;Q>oduswUxS_3Ef6C5ljuCBUrIVKBM;i4?FCBqHJ{u+ zoN-VyB?G>~%dT-emOv5SZVqI#wE&lRKz>!M=lJu3c`T-MsezL6Q?o^2csm_Wb;_!b z7X+meQ=#k>+HE)Y!D-xio(Fu?r&$qy+hwHj_8cl3Ncio0$Qq~(b%?P&QP*wK+d2V# zSrmf=wCis2VVjT}HkIPPNg@1zS;uw{Xx@HU4PE9!bAh0^nR{@BgTeWJlGl^6j5|vs zVfLgpP;dr!50$3PFRehxs(CXpWu50*axG!!;S1_BZB@x+{+Oa1V!MbJ-bKLgF>Tu! zUM*zQst)E=9mPYwWB*r;8PR+tkC;t+l-J7&1xFF=>-hbh<|-lTnpw?O)Yc#TsYm<_ zh+p$n{_VZ;BFm}cT*)xM_n;()?B9~M)W8~vG4CJsj|%@8gLi`G{GcbXK6L=KVJNgZ zh+}{Wz<(gJjBb|JS~*_k==F|K5|7pw=E=vhD`L8O8Ngk;uji3?{u~`@MPVXPSHkJ` zt>%VU-66+*qwnJ|M(c>*O#upK+|Q3_Rdj)(iY)fFkpLL0!GnZ-)UzUh=Ypz>jP%93 z9LTzo4OnjE2T4jReh9M7BpXBq!nWM01cjN!C#A_K=xe>mXL&nVj+FZm{sjGI;JJ`l zF%iwEl#XgA+zas1x*twNw>ccVNbm8SK19+u3LyTJ4NNf>LHnR^ z4sov!TC}9DPUzaSGzTkHjqgh< zLvMTsHlBQcyP%_b>fde+eL7#PRyo`=3BA2wIutMFk2Sw5D6%+ay%bflr3`B4rf@_Y zCALUnEGAX8x7N^}aV}_!c8|>BUfH#ASr3$A5ZB&4OE|xO37;7eS&&-eO}xd2BW7u3 z&<}@3%8fFZT0Qg?5&$BP^J+SKhOk z^uxyMX-|N-kEZZqP-y_}VC{Kj;`ZN87!^R2`mYDuy8h7TwRyCJre45?PC>HpnI9hx z%#ziy7VA}1>1svopC);ylNG5#?|0ll&Sgk8nI)jyw*=8t9S>is01+u#^+hIVHvN+d z?=3{pVU`6uEiPHJvea2^02xTrgXY6TGukw*vac-!$E*MbqNw>E4*cKBKt^!u3TdM; zF#;(l%44gGjF^=;!Zp!EZ!`yT1Z&8{OTTt~5uFNOn6l!=zZbV$V}FWL{N}oaLMpB$ zW20t!`bixNoT~`zO3{&EdJQ!f7xavwZwqukC=s1^S*5ktu5Lpiy=H0zc*>C*@I_|k zlC)=@Ksd2H3Rrjo`I-2lw@d0Jybl&hutEQkE-J4?`TA@)|Jwv{$UDW-{gGBSkRR`+ zM-GEcMWu08EX{3zZikSJF1oq4<6yY6>y*oU0V=TVJGbmq%_U+Kc&m&+^A;59Hn$w5 zo%%28L*tRb-n{ZPUkKpaNNrGF3^xknC_VoGEUF88gjehbK}-LR(u~=A=bYk_Y~?-O zwFr)WDf2F}-fmSW@_EiqhZ)Oy4MXqlA6nO76WYl~K^a&Zi(JvBC+Bc|to{>G3i$mw zobp8l@x-1ZL9cBjCAogL0Uo(6%P7&o=0{2R3_1qK|0ZJpPf>eIs3m{>^b$jPXgZU| zSH>bW`7Kin>!(btURjbkG53m3RnNFOO65Z0=B++&*?CnTiw6IIrfxyloCaAb{YsnU zUPmF18G#%lZy5WzjKBC=%zz(H$b5y6yA_8Jl}m0MjomLSnXj;t3Bu+bM7P04*nmzH z0VBfo=3ss+5?*OpQ_0!$dCl0*?qoFoCX{=EkYqevoGP%W&tDFAt%+k`WG-@tFR^IW z3|U4O7J-n~E;CB}KS4bG#Uegl^n=}C_y|wa>kV-J?ma!~i z0^(YD>g6k{Ghh|!SOMhmJ9KKcF{+;xyQL*Z&q(&xeCT`VE?a=n%A#C2$?lwtnn?cL z+2u4!VBkH1Ck2Yv^d0%K4_r+_L79nH@!z2cqy($|p)j($RPPgWKqWjjiTSt(L5J_7 zq}}LIkp|BJ*$haeipURRmHCEwYPqy?>G9c-ILbFy8N`=G9`t9Vi?c_7o5M2_8Bq`T z3P}~C^Kl>2q&WVSaKJO{Hy=v%m@zQ{eSXxR2;j%i8^&Z+N!d%CE3oXtM~c|qju*q! zYVr;YpRA#)N?vp%J-BN~of&qcP@BB|`Dubu_e^xNR2Xcz_rsFy;=M64V7oY!O$ZeE z5fbnUqS93zKj7SHFH`n)OP>{CMwnXY`jl3qk%W`< zolOEgdFhjf#iH4FVp2xa0r&w^z_w&^eu(cxjW=HB;NZbiIpC{1LnPe zz)KLFQla`Ji)Sd1yO~DD3%t#lQ3WT@-(GW5cNNB*S;)E|(=3e?>~2p5nXc?s2laUe ziiUNhSQcE-wc6zo!6BO?PoSs%@7QBr5~Le)iBk>h@Q!vj3mJH<2hdoM>9-5MnY;{m zb&}&=5g=~YSDJrB(w3~X4VF7Sajrwp_bTg=9>A+uP2L=?CuyloPpUB=J+%7Cj)o4T z5a?3k_3sA!%#6aNttjS(+a0w5UeyYD}IJZTzXpeoj_Ym-D~%j}*bIKKhL5$&4z z*7&E=_!JL&0vKOhk{8jR-f~Y*@?TDnkOO{;Sd2@`ynp|WR^6`pTwl&8szz_x_jfHJb+KJi};7s{%i9_ zuo@}_iPvhCMb*K-qksW(Q6~5fcm)vU2S~T=him*_-z5c*9s)Kpf-!2jM89*{Ei5?x z>ccGW6P2V#cM=AydxLZYXJQZ_YGB^%&fVi(iupNJR&6A-dN#IU8B6nF7{ZG@u9&QB zu0O49S{?m|Lz|0=8-0g8e_@xnbQHk11mz=e!Un+J1_!F~vp(?G^I;0?5SB&(|ocDn3b!=_Y8vx1l~Ds4QQG5RTaBa6T^bkVcb`3YOe=kBQamdmt(t0b;gvvo#+s{^8ew5-s;)*%eWYvW?SjEorhapP>s7nzSngZV2Ec+DBY!cA`(nsUGr?IHi;K zI^xTawfI>NKHxmOr~g;pc=tnY+!NSUnYMLvhtkt4T^6@tu6k`e@kN+!*_VawQAJs z~rx)W6utqEA&DWV`yjcyg<>U8pT~A5a&+FA8&{^%4@13N& zi|x5B|Bil-X^PS=EFdMhr2amZAh_<|{N0ZyF4L=np6^pOO2>q2*vbMlupiy`(W|dD zas$A_)7wd_hUOSdOrS=pGUt~wUf=Pe9cgK+xdXUrluUUb2s)O70WUL>arZN~T#6^x zC6;uR(N!csP~S#Q10J|tC+}v1%%XBs026Q zloo!JibjrS_|hm~>gFl0-_NajN%~23ulQ@M`e>B*WG~Q?U3f(!ClsgRg5~Dq&mz{O zKJ|X29dey7<(Zp%4A=b?s{SqDwuc}`C%ncZgbpEy-x=7LR3vXOxZkr`&d+liS z)aST;nWCD=53&l?7QhY}?SU^MV^vC3L4Q8(Qmij0`}wsD;6q+&Z};0Fhg z+4A(^JH8IOY`+H>q|oygy5yKd(OZwMPMBig_+`;i2nj$my?EPtBocQuT!RE}{)qbb zQD$mkOwsO3n{p}1)DE5W$;Rt83-Y+i#Z)~`Cr7BnB81FR@-jM-INPVi{{mv#p@TKJ=$BMW?0YD zt2F-+IQj~G8ahmW`9lpvMh=s=(OQT796W(j5RW@T*|@I#khf3cO;f?5qtmp!n9c0r zSz;gw1^o4AWdNlYmfF%??SJ;ZH`A%35QvOlU|_Uvz)AhYlJn%0qj>OjYHs%5I=Fs$ z&anHcC->pN*fe17Hf$#(V}Fhjtv(j! zc%-1p<0McPtZe;DxM|mTbh`wvLXXI0ECSs?L@8Gh%d)usU0LS)yi8}mvufUT;m>EB^=sy?R1!;Be0e7x9??=5UjH!x`oOfI}oE~>hlU5xzIQ}2V+ z2lSbGQ-LnK;6V5Q*auXOiLPqRvwJ`{qAN%hF@;oD6^u;~c@GmXwR%{{;AxV%kW*g! zU3BnLwN&=?GEE(c{F#Itj|BNyzhhtVVBT|b%-_gAhwMBw(UED1{hWjYTkp034vmj~ zGHcDNS6j2N)hQIu?40ngXp5zuK-&pT*IFnrf_WynXjvpuLq65*H6~o*P(Et-QmXdH zAOT(2sp;0ar-Cp3&wON?xdT9s2iP-HU-)o!m_MeA)1erxYVJL*5~yU5H%s*#dktkx zly=m(0BxQ&(ptmci4>HkO=D4`b{{HNWnUiLO>ux6oX<6)JAvVhG1d8uSj*Lq31IqH zlW1-r(S3G=t-Q#gVVgal$@?VkbiyOSMZk|3v5z5RURIJU=#z>%=$VFrL9qXCYMVi# zv39hO2`{885e?&gA@VPNinXZLFXo#q7!e(9yKGM&xf_aMTY(`0FL2OHsQrj zry^tx5x4;%Fp*PCUD({Jqho9Wk92EBbuzBm71Nwu7#$0uEW)j~^}3BR?>G$T^@%=} zasn7V)M=-hd%d_)P53CT4Gi zZ=MFztrOiZ-a@OggB;PHpoT3_$YVXc@|CTMd&Th(U3?dC{d**{?SB*4!jMezaumg` zwWHrX+Ca9v!_O0Fa4THh={!*^*9L^cGX9M)s6T@xOv z?=3K-b>YWV6?bDMMJhpLvBCc(9nT~oHRmV7+Lch}*_J3%^R5tmE!bv@pvq=nZxt0E ziCgRN$`e*TLSLZMJ$m1K#eNAqQG!9of(Yn@^az3GD=AqvBsnti9+8QhdA>kbUt%Wm z&WB8m=|Nqp8bHtAG>bYB4}TE(YPz{}fWyWSUjB8BjIFnX60f9r-eIV!UW}S*u=l;k z%c5DZ^1DKUrhECGNUB`(dwE4`4At-ZJHtK6!qIT;UW42^Ren1z1LHVg>WFAvgc6h43T19Iq>H0=u11l&6u&mo>yA12}CA*fZM;_*mftNMf%~Cy^+q0S?po2 zJJWy;h07qr^)IPQHd@;|U%G*JvubVc6ruZNZq57|86m8eU+d1XN*RreN} z3fZg}4nKi8Q<02=qw#A9D~Ne-_TVM1yoSw6#K$#q#D)@(fVsC)62;R%P}AggCR_l$V?P z{4FD((QvwtIdSyD&wMZ(GMxgct!8q81Qo~F1IQM`SahZV3Zc`Oe-CsFlp;x{?0}D? zf6yhHb0SR^huSB_XJHBByn}lq1zfb^y~3CEfhIEvrj_D>jUMgw+$O}l*%IdlEyxIV z4b}rQp3)R6Pq+6sIl@{BeX<|^L78@Tm>yk5LoAI7C;_4zq>)9aL&f=R95VHaVLc|*)&^(oMY^wMv$x)8bEqrG;9*bvSAOT-NAwhMb zL9A~R01)~d<|k2riSEA79zMaX_BA#YWTRIO=!rbdNBfgmd?%u57qjg=`QCMX-8_-7 zqHZ+{&W3Krse9(^5##7zTD!SFSNZv6Y;XK3p`&wa`h83xpZ6%(_i(Z&8`qc=;s~_Z zMl!hQKMj@15$3oPZ*Qys@Dd02d~_v0Uwyc*1b-1GW~`{h>jHg39;)|0;2wfIL}5CU zhw!$vcA^rtL*cs{55vU?ZfqocX=tg!fX-jDlO7I!a@vJ)5}=eFWuoM8ncqwmz6EH9 zI^t~i2f13=M8K5w!U9muhb=>w*hhX*=>j)un3Qj|!6nu#n? zwt10qc6fBx3QE$2HTd)9iL1r-czw*LQu6E;&^U#>*g53}RfbPl95(R4t;2K>RJ-Rr zP7JFgTSlNErHCeLXaj{8Qw^?`gyEH+H#mGi4!1%tV-xWYZSJ+kc&+2AZ`22A#;P#r zk0m-hDX?MB1=C3UWb!__;J<6NQDW2mf9uFfes?@JPDeZ+wO;1ac0V0;GgLKLdmYaO zb^q9RYXyP~(6h=8%)`nK*a!dgs^$?jv`3Gwd}@T z%CC^G=9oqH^Zi=72KrXOX(koh#W?#2adlv*wNTw zBv67M?w^>NpR9+y7V$`>v8{V@rbxZaw-+h9kLSpc+|u6`4~fek7X6W0ursEKwBOns zSo#|^LL7t6WwqF(Z;8m0NrW`GZ!EhQj_Qi*IOpW$eQ57iT$oLugTmV7ae&5<-sST= zU1udg%sZDDH~Pc8B$5yaA$%Zq{=Flter4=;>j`Dxrrj%ExX#B?xoRFTi`VWw-c-)u zkg*}bWx9Vsi$q^-4ti^xuHG-B%gu^34brAfua=Cy(KgaZH|^L>V!zXCU&9|CY3^(J zQOp!Zuf?OSM+J57&A`KhfF%t#L+`;g=VdvpA~^{#(lj+Yd@*!;x8@&++4ZzMba-Yi z_+AXrle^D?Te1E=Pigl*+#?T@=eVmk!vokPJ(7I}^v-s&j&s_P-B7~)EO2iF>>GMp zq|Dk!uDk!hW1KajSv~6FZ?#p`W7s}m5rc&?BN>~o=(H!%k;n;5C*mnrHMclih6IyI zNiC-{fNK#Iy_w+*-Z55qlb|PYnqeTThRI_}9uXurpeAwkIU3kgxwE2VEUja|%BX80 z)T_-ZqJ|=R?T4p#|JaQ2o&J~IS_UT(L?8Ah5Hs`Lg$Gd_W)0(6{w1b9d)gEMxVhsP zn`eHpvg|Ya)Q|%x;=e5#7_4YJ3|6%Zeb21cu{&B8;S?zde+?-XXNyaWPY`ijAiFjK z&b2M`4}!cOwNkXx(v-HSsd^e6cyD&$Bs!Epls(PG-#al+kR;lPw{?`?cM`LF8UgMn z0FW^sz}6R~C8@R<{4zZ9nWCuZttw)7`5Z3)j-u>@EOe$RLC0^e9}>~n6LJ+EmY10x zp0_P>h45(|fO8qf#sm8Dt$qvs?UG6DYkbr%xoJjz@h&KwCp~}2(526QbUEFhIf4FD)AI^6lc}c_n5xlm6uq=p*9#??<5WhK*5#C#l6ms z{%ABeVfj~D54wPFK^h7|$7Kpcl5N|(hq(A{yz<_YD|v0Fv+Mh&H%!g=J}f~{&pRDL z^f3qfPRBo4wb^)-{uu4^K3r-j#artby=w=y49iS7tWDYCbcJ8Ht2CLdI3LabAhRIm( z)DVYsG(L7v!sFT|Az^K!C>KH2$_khewn3DIP&kXfTW!j?+TwvZ6!lls9{VK1x~_gc zR#}npOl>Yo@i9nnyfL3Uzcy?EEeXL|;IVK5M1=>_$JJD3e?O~C{l_ak;Ls^f#Guzc zDM+~}9Z;tfJ+0P?&p8&xJOOwUH|Iv^?<+qYA_rs9aj167ldpLTtKP*jMRcI!mv?WL zP+EVRI+_uzi}tm}%Ob7cF4gPJ7?4wYJzGPm(4lZS-D8*j8@^aBcK)9U#b|}MTl=d5 zi=G63*yc@9!0+AA0!N~)Tb)n3BwqB3V(1(0C><^9ZoRMri;DHB)8i<{{xA!j#Adpq z@Xgy%`KPuUM@upF>2840bzS&ozkrV0yo~9#rAJ#Ye`bjF)enKI%9LAOW%JRW2PGmY&CuObr5{JWwJ) z0v7&{mLQlpX>~@`E4B6?FiXpm zA$hOcRv zz)lF_RpflFM{zhxT-a2CN)HAyg^}3Ce`Xt%4A;5U*ObBW=X>3vRT1{Mj3=|G=27ve z{3pSqF!3r=_F5-$pW29ui4-*SYQ`}Zj*og7H+S}b+aeY!L+&G-D5JbjG%!q=WU`6eS9ByMby%zb>yQB!e5w_{m2ZCgD;m~J` z8nZKNg~#yh1wjA3#FAKPUKd_Hz{u>&3e~uNEAY3=a3}*MdP7R zlY}E3C(U4uW=w4tl~{W_Q(9j%^*qDqF&4S%y;z`<=EXtVJdxBLYQ5ypO+rc6JPz~@40ov(=LR4$jL9FUr>O2q5?3EJh#Cfi+#oo}yZA^~5#&>L z4bSw&;@_s&XGpP%XJ%8mHqS9R+$}Nis`sy3O(`Xku8uHt=jxID9;*SB#433}Mf4lV z0mste(mex2L*1KS>B){@mt-?I7m=*%tQJy9b+h8v)WU}KXL2`7=+cn>^7N$(QcUSY zhtS?HJ-GO|kK?pVG|#zU8@(KMO`aXr7C!4uw`$kMq%zB^Wg}sW#1qH9_&dD*I*CSQ z6UgT%e=hhE{MJ_42QaOix^a>AwRjsB4*0dQla`(xpk3C8XJSYHP7DV&T@Hm8a5MuQ z_sAbRv4iQTF^r=~Ni>kt#M`o8zu+Qd#F zcv-h3k1Wjk2Kw;&};EHa^FHA9ZJ^)g*QSBKorqO{z)ZTjDT4Z-|!Bp*0d(62-2sN z9P)!d1VGodQ`pk+$fr`fIKR)>^oCELb%@Ag!T?x5;5F9^`{8H>kxpAeRc&CrCH8tr z*;2zz*gKCY+)=mg=Df0u;;J=#KgZ0&|}MT z$NQ(oeu`}$#-SI4svT+00AktgG+&dhW2Yi&KQUw;8G6`=|KTv_^PfO2*{W(WYShhz zUpcl2h0JUuksrgBYpdM)u6O<8eZfAA+rP7>S6u7-fjN`dHDaT)xKXykgx$$|El?wD zC&CwnTW{UvPa5RpY|+bK0_Tzwz9&DFk{ZeAD*G9bENMi`;$iy^^|iZq0Uws8u0}oK z$aXh3-^>aofWP{WQcA*J-_89y-_;jeM+BS z1P~TA`fu#cL>KKqHs`3aT;H>7d^n#57=>#?@_a=CUOHDY{5(c;MOTm~ml8lnS9B{OZvxKKva zynK7Ar=f&7$>7KvGQ_p2{@_F4S|SSE9pn?s-wu}b{2%N{1xeQDx4uPL!&$tr-V)#*_hDj+c^aEGQ6_(0(g&*aZ#Ig7 zx;un0#o<6mDGc9+^}s|}S}+Wp(Xv<@B+jIO>`^~R(jUu|AlH#dhZnz!hfStre5-6A z5@@??J;v-pDRRFy<A*WAVdsS@!=0wDe&XnTmNj_#S%V|)4?rB_gK;Bk?=i?mz?wO*E zitPu8ph;MXV1pkF(Y+pUlO+l_TFpUKe^mjW@vl`}f#}Q8luhf7b6J}YzoVy2W+zXR zaG-%_?tWfYq8?fj_fF0*51Jc!U8`{cXwa}-Y}fpRS^#n|5M%^zi2SiWM!@LdWjnrM zf;&}c2flL5FqNseVZ%*1KTT+vcEVR=^mvGr^N`Q}jJMCxWWXk9b3Dk;SlDY$buRg{ zMV2YH-P}ai5bjFAjN8j=YBjMa-!CXxPNkCX}A9Ptqk>kYYitzsVuN}B{FEBBHZX|h^ z^8ki!kmyo?-sEh#R4E%R4up;c_L8L|9wkK$?o-PVDf-3ESs(ePkwL%yMPT=qUIj^T z1vBGTzvX&%p3tUD0Q^{?hxDA4I-NqfO^?>3Ym*w-G4*9eFPD<5dn^(_|GMUKNb6g! zMMxEP1;PZPgC+ryPG9dmkj)0{O{RbE`MTU}iDH5Aq!;=Vd0k``t5tL?)9q_pN_6V3 z(%7C0;5Q5t3X%&GG374|edOF#V2W>0!jbUAouN-{;@N zPLt`Uemy2YzR$by`xgY<)snSy>Lz_c*+hVI1+7+2UW3GI;kqZ{hGNk~@V^l)mV1KR zb=k^w!P?(<=+W05sm-Y8P9MJ&Fz$W&wb^yk#L9yIp;x9oonkc+g<2)U@p3bmK24T@ ztQEedV0-Wvoy&Fl13#jAQid(BMs2{raL;B?8G&{q9iH>F$w0YWQAHc}aERC3^b0X? z^MRe7v9=-j4~kFRQ&M`F(fb+#uHOc~>Miq>K~Dp~U4646m&bpVJR2=n%308)KaJ*$ z9hOsCeQav2xoCs!{fS9(Y?_xPNl?%H-Wuar3?4Pfzjn?g_u4hmE`6A8r;#Avu z!d3@Y!;sF_=uJ-)a{u`v+BY(D9`+sV0;Pehu^H zQ@acNnztNnF5Ehw0`zAY-#RVlmzdSKuwuG@ zEc`vAP{?8yvJrvdbE7|c)6j!IXV}Wd*yzgK&yfQ%EVn?WYeGxNnok4U7J>~Rsy8K zhP1NdLIWzom)ODw<0L;ILBI%BmQlQ6D2F!dcea?h>P(+B0Hsd|n_|Li+7H|QgA78J z6Aw-^W8u3Wa6$?|Yog?dwb9iI`5rn$^oo^?a7ov7|9Q21UXXaLYpBKw6x@+pz-9JM z?K0eHZ`5$NRF_k%7U+6S?J_n2>f#4xlY7g;uN7-aJoaap!q~#`31YcMloZQ;{&_hy zC-25?DxM>x<9!o+hbvfj+&ZU22jicqk~*k4po%y*q`uhF*~>Ua4@7ek@S!X0yBdz^ z(PagaR?Mjw!{1>%cCGpEYg_l8)6tCO68^*K3nnVBTB;m9zMZam=h81~Ec?1UDN4)6r?TP; z6)!m~_=0_h^)Z!p^I5r!?!i%f(*h)Fd%mZO=*AKmAV&xSeI38vaNZcT|9;@!`41Ii zBVfazOqCG?71WnP2AIh-8#EiI2iE>_KHOtbxz-3j^{Z;-;9I@GC$&5ttyvZ{QCyOX zT2ps7^&^4{0Z2VxPQ-u!c_8zY`jx0+mQNPu@j?4V>04(O(vJXv$Q=3d1- zsSx&|JKdUVsK2d9EmpwKpZT^vN7v>UX{KFiEzsn_x$9Giko+COPH<9&@|St5Ph<3p z+gMRiMIG@%vDg*@p+K#3axf)yvnoi|GjEhV z^qmH`w+MMXYig6<16+A6YYMO!bu&Z2p`zBO=j^YTS07v7f~AE)yWYk+^TRk8JC3&< zSK9|s&;DIHCD6_kL0>6wp3MB5WCCH)Kf&Z39h|(gXz7iUFUGXEj=w*YQ+rh++O$;n z-&!V?9^USNmJOZc8?i(U>opJ9j_e9z=0_@bTBbxFUMx1p%W+D6iqpC2h4Y}jr$}x? z!|JxU_e}B#nbXU+?#ke_U7RcZd56o)PtK_AU%0q)Zg@&{(CK!IO679 zcNAoh50sLJ{%}L;$E%MU%~9@<8kD}zNfcf(07^(ez>GWc7bqX=Fx3bket@}C zQ?fWYt+!Ur3$u)-Qyfoid=TOE8g74PU;K86FQ{SE4Kcs@R&lj7iBQWy zP;fxbR086=m6|DzGvFLx3Uo`x&#LL_;PfFM9k}?12Z5)99BT2h8olfZ21_CZAm-T$ zWtgDkY46!=AO};ysBlScOmIE=p$}Mr2KM1qcbJ!iULT{)MQ_4k8nJ{8J9~LPPpR4s z>M6c@$OpPfNEs9j?_G zWI|Ydbw4NEybCCQ-s@F64;o{JNsIbx-pt1*QA@Wf{Lf%%?E2^(Y1O`7kF*sWGG~KL z|D%C!p<_3_9?S_*a7v!UeOVQBXBOoEZ#!qA{?-WLE@`D?`u5h6To^>Kp!fCUn82^> z_$Z4!%f1dKd6GViU%EvtNZS$bZgyoWowM*SDtYBeS6Xs-w>*U@!-o_(+!j z;8^Sn^BiW`9&CdNmvbT#?OpK5%1b_er~jO=d7!)z>=wMO9;~N&pH}&9k7Gl(?(gA1 zcZbCMFx=y&CyN6?+YTSk|Z54QuSv*Q}yB);Qs)a7p*AHG{iH~lq+)aQ8prZ}$K z9D9k^b|kPxTs4Bs-fqU>hRit-|9&T~+Bd|~)U-h~U&4347H(e0nd4i>`D26?lh_7< zvKjkfO2$EY)u`p<*E3e|I?}ku<8$pe+~cDNY#aRP*4=iOcFjp}`^on;O!6GeQLXSi zivx~>hDKrd)%rPopXu={kH!>fGfI3#Ows@wr9y8Tnu8YGdIV30IA(C~B1z?X zBy-NWiKt$r{kY&4ET$#kk}NcEf)8cqfruc+Y{=U29C4at5YiRcxbVuu1lHeQVB#ei zt9B;4p6aIef8|~GKh^L1cW|s@X792kE6SdknMJZwWN#;1&M}g86vfGwLWzTO>~Ij? z$~t79!$I~sWsms2`urQ;^NSzOaX+s6zOV7T#(iCm!K&loK&Ew^`Ox~YiHhH0CR^>= zK0Dsi-^=H&4eC~LDd|E8-`W%8)8Tp3jZvzD;0gM>m6J(-94wMw_(yTE#0r0c$4 zR8Za$2*u|0EHMNPPa2M5OpoA^r+;IMuc{l6u%BOw@f2i0o8Ks&=Q6~(HB;mMX3f(W z>sr<|{Pd(YAMCU?nR3FlkTfZIf1t7jYFWu$NQO}&B)!{JGnMReo$OrOB;7C1GQ%+q_f@YsR z=lh!26QY%;!rS2zimPY@K!q}TP4j!aCv{^i$k#**zid=KE4~Sz7Tek!i`g81Z#jGq z&1t+cv3F(Q&PcENkw1IG0gZHr^@<{O&eXkaw-j$fl%x1hPpoN`lhE@OFmun2o z+tjt4k(aX##n*#@xk}27Z$L#4eoRh`CG>xBHrM857`(k;;tDq$>N8c`kNezzvp>b< zf`zEz`TSnn*lLjn$B0rdJEEf9RRq_3I@>=VIt28N9CEKMiV^iVeyk+E+WvHZSrt5^i=M>_!V=DK1}p&iUrY3>f_K6KRG*OC!N4`{Xv&l7iH2hc-Z<*2X)W5v^hxg z<=kfBx0_Q+Y2f{I&QdFj`K0Q~OOZeT3NpaPq?OhAr<~z=*Ad>7kgAb-(0%4M`Dg1V zPK5f3?4-`Rz~NUl=+7tz&bIWoLx`>Iuzfa6~F-GIA#SOt&o?|m;ZcN$OYWuXU_HMp0RCR+Eb8Axx^uXwD-}|u^k5%%q zL8QimK1*ZIK6q%($9~norG6FSFz$k5IP?^+RQbiidAV~5 zdsO_6l!Ku*bwCech$PJFT3Y+7x&KrJCiMf&4Oa-ktS!#+JR?Wr#0Rqpoxz!expmgr zU!&BYI|UXB{lK9%{Bx@n3-?AuUrdEvpvBe{Bjw|)&|QXzh#f6X1;Wpyid%8L*D#ca zOfH>YOMMgO_&H$nhFL3fw9ybb8k2NqT^IyXINeZ#dN_5TE*#Zkdb@7Gv!&cIQ@b!r znQ^T`{Yulv`Jle5Y!DNWu*Kv%JL8D)IU#)8gS^)KqJx%+!mN^HYBxLD>GX3VSh2b4 zmrI$nx(d(nXoXA=8zFc1Hx1C?7xkWh)HKOXdsoJycyl8_XR~X*P~erDs(%T8`16~A zRw#}SlAO>Mf8mKx@Sx)(zPGDJv*LE+f4c@_ZZxzG;(p!n_pHkg?0dygqN1?m)pJct zN8=p}o$;t6MrU%I70$UZMXwI+3<+jye3D#Nx0G(6Q!r$bTFw?0f2J|ukulZu;slEqJ7Q2R_+E+qel@xgd!QRuH zQ43!e9sZqs8&XA|lj?NM>3%B3E1SGlogzc(H;^uC;lM!C#`lBubdmv z@2v>%{tnv+T}Z$kg~fRgzCggVd|}g1`6fFupc_#)@`#xy=<1gxA;+uhg>TeNe?69( z`QwwS;fwN?o4@b;xw9av)7hVPy#a+CaxM|S9_TCNUbhgEbtC6)e2dJps-;WiHPfUJ z65fsY>7HMZeHt_}CVlrLYt06eK{jaKA?tn%vPSR|@N*%7iRCaQ5WB6-SFo}YFS3H# z|Fi1hctWUaOkEQtKliUd%l4+*?d4*46^VTgzczKB(R*L0Uu3#9vu61jtp0scZ76U< zunx6)L4hKkiw>BT?oMFV zG&T$**cTTeW~)71XtkDmdPJ5XqxA|QH!E=WbxkFYyk)5DEaE{qky2du+V|ZgAx71d z*059=vzOpKd~%k%iV~9^zO738qlkTa)tGpwaP|0Rn1=Zo>e0&T=U1_L%> z&)ya@Gn>ofRrs#n535I8`_FQvawem~=EiZKP3P0yzsUyt!b}mnXniFiYS$6LHxHU7 za^{km^?4gL+)Jga(b)@c9r)BLBjX*0f9Z^AMBltVKQ12K)9?~rx8|erH>OWurgp;N zk)#=EOBNF5pFTCa%b}+HedAV{7)cAZ3)ZB-sK)rMZ2a2iX!oKoO}^eIb3_3mWY(cK zxFj}nR0<+P5Ix$3-P6xpykt*yJ}-?s@KY>Dn|J4$oP78*lbu3J*=CvbsXLAoh=86w zJ)J)6ug`{b6>9cr%nErwwc{In1Y|8_T?%kFe`GG!p$2}aBf(Hid;JY-;XbHUR8_g% zp9qE(`If)#0jR*U;_LyxvvbkYcjFwqTi-0DXpj6;mF1UJv`XJDJNt8A_ZfAP-Tn~i zCOVq*j_{X-LPIt3NVbC?O|}m`wI8TQ!`h8M%sQXm?b6P0E#pS|Q}Ss3x|yfJIAZnl zW_485EgWju@2)r6sL@>oTGhlx8|I7q9$a3IVel!8i<}{f7LRQLfri$s(2m;S-8-$# zZ@~LzLWJ!5MkxkwDs=MV31crWy&rDf0Iidnf84al>a55R&uQEM)B&;KcPk7 z^4W-#{sO6j&>d-A3!U->ah^g0hs*fQ>G>IBFNQ7Yrwa(3#}zj)-J@m%UuT5dhwC-v zk9b@8_>Tq@$z>|XnX)7gugckS93H8K9;v0UeEVHzaJSzz@>PD>S)M+}$li5HMynL4 z^^TrQ#9fQ>H9E!yn*?v1yz}HKX&d`Q%-80dvCSnyV4(qI7;9`O?snkrH&IZ`6ywJ< zD}@*hU0Bl_nEFc9^4?8+4y>qETu!Dm&UZ!)ESNR<@cA!&Z9Si%>B(yyz3#A{It(aLvETTmj$1=H@<$L=vu+%@~8+1xJVeNlB4f6 zN2tu)eAwiZYAH!+Zu&w5UOnc~&;Ye|mc{~H+pYubpY$Hp{dPH-M%66fw|XqFr>XJh zk7I875v-U)Z4$k43Ujb#_Yuis8M@5%!Ky~e#sjrb>w3c|-%h+^Vnfms%0_zqeYV8X zCHaHfZ(46uoRJ05_@WH91k(m)-_(STDDk*!VO4bMCU3E`vcGKR>l|`6tm5K&1ZxgmEhFa0GWnvE{nt6YKYrBqKe`=K zH9Gyt??DNdJ|Axew-XJUgD%cW| zsnRCf#HRg71Q7;&ln)~2ukQ481^!DB=0&G=28n%E7-7+ypGT|eQ{O3A7YeJ3SECXN zJumRscfFqN^tNvP(r0ElTlKVTovJ5E`bikI7M=k6x z5Xd&R{j}h@f~otz#Y73K&dgKOQa@AV?laxMWKUe1JR9DS#a@8=EbV;T@V;D3M$Cr? zo55qRYmw77wnu4yl%+}5&+rYRPfVVEQgGz_Rh&y-3-hlwCKJ()HLl=DsEu@a&+RFC zYYcVtJZEm8;gCk@h_*hiT5zTU?~9r0MtrtR5kjO#^>V12S8GkZDE3*75q-Q1TgryN z)P1vmt8uuwnTlg%@Y!!2L(bO7#P;`c_Dln}DGGgtUsxC}w0h5+V)#Tm`L+x^ZaZpI z?2bICBl`-_6qzX4!^Ci?waSv*)tk?saos?$4#)wvZz2%%# zYfy|ckF0*QU}iCbbz+-xU=2O+{^KxPCSb)Bb8aJ;{cJoY^AcC2 zXf>@ylrYfE$H+Gr`Bx`_p=kfb51)Qie;#=l2Z6{DXi~XbWS^n#HvY1P)S$$+)?W8q zmYbpT{Beh;*oak2J<%%&vv8guZTyeEMa(*`Fn4J}r_UvWITPV^$fC5_3Gneld2N{e zJwSTZjdOjzew&GGc~Fj`JUioyH~y0+PY^5655^8su)K|1`cE(K-3yz0j++Z(;?o6x zHM*+e5qaK-`!gZfvcdt?I+*{2Q_BihvKZ_5-N1j|wqqONM*6Hn6f`3uz}S}`2h|Y7 zu>C)qZzW^ZQN#R7N1u$0y6@Nuo_qn4br zMMG14_Y+G_m#7C*lj8mMi=&&p&`KcUqb>ELE!glipaQzl0vSLVn@h!wfAUX24aUzH zr;Z)q=e$h42^6QDN=(qx+}m#_|1MaUTP%ov99w63|6t{AS7O94)G7-WdY~Hm0Bo%K zaXNj-&6wu2S=tbYOr|8D$7*-ZD^&csp+7V4MdZJJD$<(dk&`}x9R^8If`E5RVx$DhmlG~0nxKk@5i!@Sl-jn;aiK9UL+sw+J0m+nJWZN!AWelDuh57*QA`kJMDBIp-nmVL3)#M@q&S@NxaN%%D(<;)`KYM&!zg4@u$~c=vHLOJ1F@!_fPURT|pXxx!5S!J>n{?b&MiW#AR5q zL?G%kwWfTdLIv{ z1WdCQHvE(oIFVkR)dG)es8@2~q4f8DuA9j9I(~vic|W2xAEMe(;|BVVzVr5CmNhid z%0W_HD3P4^ogW8(15QtxES5^0{G6GTr7f+2)U2|&O^%iZij<=&8E4=pp*1lJy>5CI zqraBN#5InXqK1Yx!dfw*M~xn^%NJrDgJGxm!BaG>@DWHEbbgb>1-u8&bNRF#{N{~A zTN7Cp!*F}9tItjQ-LmT;y+{)k=%bVMX{@+;IPeJWn{&sQkFQA;MF;IyCgu3$&XsKN z{&^)uk#_tk6Zs_zmnl<=8)l9a=r*HZf5m@0L|M=ivmF&+s>Gs*oOC_L+YNILMXuQQ zQ=D#yAi2W12%tT$V%++kl2Z1vj-P-q76mj>y~zLgxhA!K9*pz`Gp0qjf3>`!y!{)$ zuAt`vFaxX$#s{Jn=sbGz*6})GLHCW3Vw!-qlffj<~ zO?#Q8AR*!j?XZhoQ=4p8viR||TlD_p|Ifo+_iw`CzUykl!4dIW-5TU2%W~+c{@gpvI>f{Q7<|wz! zndn+_o_%HsZviVks84kerBht0sZ01EzoN>P>7qILLfnx2sAw<$9fLK*(%Femj4b0l z_g0a1V`Z+{0C|fsKX@*Aj_Wy{-{E~zCJz4Ne<3=gKW%GNLIFFemgB?kh0Gx{fV;1f zKP|6+$YcQq!XV-Pc&h-Pew)V+IW3jswhCs}(Obwt+ijYy=6C>Ut5atkxP3EXW zdQ-00!)wa|4U0;xX^zRH1%2t}kWw}3+MET50dZc^H~rx|s~WW8g zQ?)HXx!YKr*YSYYa6k8;Me{(#IalrgkP?NKqq?DjkhPVMfYNawY7(_TM<1w#K%AY? zQh{F?tfZUj#eND&G-;z5oD9l zkH3<0R{>UAHU-6|iOqjy4_ByR&u(ctAzM1YLWOI}uWwbVT>q#oHPN=&FgwV_Fv7?% z1=+@qWs$J&u%GM-aMxRJ87?Q`;w%Np#nfUL%3AFJaI_)UQojxHbUN;!e&h1#?gKUK z?`bTsbO(Uj>|VB&FGyG94VsO7{QO_%v`V-qS0T?4X2w|f?f85~5JqYy3bqQ|f*3CV z0V{EOKa4ct{y|YvHBuT}$rrZ>apmIbOKn{jpG#3(o{==|W90z@y{Y+PO@s9dCaVj- zQw#Ud@F$?Vm9y+hxR2FG#Ru1N3p8W1_yKcV&qZ}1MN;xSnc8)+i<)@9rg*--j-Apa zW&>#cy0S6ds0-N3^g>0^g__tS8GihAwTE^)#YVFFq=>$Bc4Q8c4_KPKt$(nsPk7Dx z+!gBpdq|e)PRbTS26U!o!6AEHZFdmu652GFFIUt1YdxoJFciY@K3OVvhZg-Rk7xCb zV9dp7D}4B|sKekb0BlrGasfStJ#h60yOb|RMQGbd?VVBAM%Q?X}oEi##Z^3(tv{pK<=DO9nhgWW9G0UzLi zDCVX{41c4Sr9n+Eu1RT2$4x6UKOQ5A&C-#Jiqj8M7xL`!HB~eVn-}L=!yRhbw`E7@ z56e|!cEkjM(?3v51x}ufVPoFnKBs2!^jA%+qXOxh(ZG)LLW5>WhlJv+s(r?LpUdv_ zbxNJdZ=Cj|fpFr&<6%#yO7UzxLC=T3;sx}|C$-Y3LR}{k0S`tvpX@@oMdsL?mU^qA0|(HRbYVvjhaZT<>^^D-2PJ|O zS$$j$GlYpgiZLy`ck}d}bo0j|yA`0t$A~Ipx_MDYzc?TT2E5?sIUjG<%>(&Y10(V% zSV)N6IBBa&WrrK8jM}!ViqBiWZC>mMTT&p6oFEm@EsoZ&esH`zi5(G=7cS5Y%L)K^ z%pih1oYx+?^3Zmo$4pP_CBzR%y>nM}Ys9leUAGq+L;BxitLW_w$2P}IuxNT508GCx_l4_ zAGhh-5g=(^$d9ZLx366U-Y<2X~r?^Upv_L z%!n_qb@5lllDDj5yfCS=jivPq4{w!9=m$RezBjE<$colgph^6%Y<}>R)wm1?mYGOA z8}1ah=rwInU#|BNF(vPyj;63rY8waOMqZ9tbDsZiec~fBEyi=QK((51h_wF5A)GqN z6-diR_Y~Kl#fc;L-pEhtXSaZ5Fbj#FuvVpo$yC;pGOkm45DB0gqR4F_C8vM%h-G1A z--`mR_>cXIwKQy*CD@4HFsqAS1A#m+;(1927s;8THGO7qJh;CC4`{V#H2XCo`cz6l+qtW7LcY%Ap}z)Xd`4SmmIs zz2A=)N)N?~KiU=0WDQ~=tfYY^k1~dF-MY=iQO`MDg~@pa^(g==xQjy8${eJNpDi#I zCmYOnr?imt;gAscbhbwTiZtWbrTyV7j@RZ*@7IK$YESw6!uWV$xfW(miuzyGO+rX5 zpzs?y`|+8+f>S?0SLkqw174HiT#=Oi$}~O&F~J)|T(fq;$b1b>U7Fz8f18l#j!ljE zZ!i;fD3YPqR6~q-OouR~TA6_de-J)ox7uR${CjXz{4_0n-98khU^hZ}!4u9Q&41>K zeLfQG=*8LCZ$QMpT;1n8Cu}36MN8IP+Sz3ul6~{NvQFV5eWlEyZ~?qPG;;a;si?&J z@dIIYm?3OlS1W3QeGsYvSraocC+~n~k496Iq_uBJ@83%@ISY^HA{a0&~iT;(7iP6K|^tC)GZ*)v}H2ffCD(V|2=JLO4hzRxjYHW7|- z9lu5tq__k%QD@KC0kE40K%r^7a3IgtkSl-;085#oX+Lx=SE?gK}oO;l<; zE073C@c2?a{vxF^OK5iO^f;E{g3lyULB$0`_|?yi8O4`+(oP3ZT`yKTdmpci{k@JQ z<*zA)bPvmVCY6RBTA^bTV!YoP`=DEFo5QORNjP1*uGerPMDPoLD zGm+{*5Ol#%qolzlT2;3ZLx^!2s| zv#9a?AXwi}6k=Gp-8(686=wNbTcZ~!rg}y8R9sP=FON=Li{18R&hsLvZ)>|3O0Y8= zH=k=TAVbsi?r^4JyMarNW1V8A>?@z*;vsv59V*~Hs>BX-cP;9()n4a|O{Z(cf1#;h zE@xQj7<>xKMSJMpLJ7_I^grY8>l?9ZvZ*I8`$|`vqy6Y zh^eqL>H^Q?k>p4sppS*Kx_A#gqb8UT6EI7azVJMbK4NX0$+fkLK05 zn_bXiUVjgxh=qeg(6rMu1YdV)DDPMv{F3(=g)Q87;j!G<#=;?i(brcTj#NUAys=Cm zhesVc`9R7E*FfrOD&Nr|_ZeSc!s+O3mjkJX3v} za3+D|lL0%V7p;)70vBXsQ>fTy5mZ6lS3%lj@Wak?;B zC;EJ3%E^Wk3u<15{w?`-v2ZAFRR_ihn$pHi9N^1G0ukq!fJwPzoAW3p6104nfb@3* z5s*2Dv_umulV~gfq)Hb?PN9$V#+IA+@a2U@6J+`dC@iHZbAe)?r-?9g2!}9@vWy~e z-_gbQ+6{kh#}Wp0s&fI=kkPgMTU=vRH;Q@p{=C2)%yfW(Hm(AhxE5+}QO}6*=lBr+ ziM_B;<@VrmR}0zj0ES2RuX$n-lLXw+Ce`6<*`IL5tq5@tT~V;Q1m2E@5%`K-=fx zA~V5J{?;hgefo^Glz(rIDf)`-KLWGB93$z?s={lkJDfnvlK{%oF_^U!oixe`ulfAv z-uLaUhr4V$T+B~UQ8P+bk9hdN#@$5%YNTtDYAN;6fa~Z&`7rk!D zV5n=gv$jvdC7Zp$p*Rdh&EWD{I{?HJWR$r=9vj=ZbZZvKf_1q$8E$6oVRzv6I<}<1 zTA6$#Zv6mOT~Z$4_CEbk;!+w)C9<=B!kcyLABCZ4z;W#Zs$R5)>h6YUyl!ykucX$D z5L)T!$7)S20jR2En(^nXPqy5kqK=?<3d=ql-;$ZK!shZG3*8%iC$8CuDq`e!#9*awk7p%DRja4UHtKK4qu z+RXk(!AxSd2)rOSkxB439}na_%R%_XUHC+b_3jrVlnEWnuvtWzePMRTR&bXJ)Z&DC zgi_gcKo#(c2GW0vkZho{PI^LmjVfOjzwm*|%E9lf>nxHi9Q zpI%H_F>inn16{RV7HZRB9gFlD_MZ)n)nN)-;lf4x18*5RvmsK^B ziwgZZ*w4MN8EP2)SDvQ-u>nUZ!FiSAag!wAq1gu&*Bl1AP)SdpUXmNCkuG@9 zUVx)lrXT=*PDyCJ5XQENP&nxv1uLmXuUHR+EENXKZ60qp&4jcqEBUji2HRhCf6uVG zqJfrn5`QF&?CY=p3OV*sjKy-H;Q$AXsQ^}qS~JN%=uD>=sB-+lc$eIxj6zU#E5hCJ z_|QSM^7;_=i<1# zA&<#y>vdX%bxB__&?Mjih!w*eF z`uFs836m6sGPQx?LF0DLK{`P*CQ8NsviSj*P*Cg2-rSu+S1S{ZUerUQ%vrkES6?qp zsq)GC<=ob-3$TVVKtRO1l-j z7Cfk#kx#W!$)fwm(vmr!btR58@W!LM`R8g(qAKYcu?W;b;kdQW>z;NG5dC#cKSkuF z6_FoXyRU8k^W(4L^@ZV#p0B&_katSq4V>5Yn-|xQUP1MxI4A{a#Wz&1GwBElOjI0( zk`Z1Ux)UY8Xs5|L^#CVCkTT0Xdrs``?~qN&WI6lYkKGmU-g{kIh(^N;<1Cv76wm(z z{~j0813w<^4zVhH=icNPHHO9pynnW?MRNmsnl9h_#oail7ut~oi}%$2YfOB5<7~%< zZsd^kiB&#HJTU;z`}N578zJLe7{%H+FN_~##POTyjyYw_&VOs@B< zB4n-Ct(%-=xOQ<6n~0bRgHvt9jeR)+X00lW!B>0v=Uaf{9+;)%nzf?{&-opZ`~a+x z#t0*Pab^!{2%iUEAlV;mr^yolm?S^_M<`eEh=#O;og^EF?h_te+3*V|eOaBdCJJsL zjt^(~?ul6ckmH94KSTOa3E`>(q)gwJ{sxrxaW68h2Ig;i2uM4521twYoU7lHK)oip zR`@%051t|D6B0RbPpa$Wg&dCln=^WH(z7g>3mDI0VOQ%MkhcCDxS{@P1*~i-;4FhL zSS)|{2e#S78PHoelB`piqheyxB>`hPJi@bOQ9Sq{O`h8oP!2pG`LVWk0?q2D5NA!g|)tUOd;8>V~{{`Ccy9 z7DQDEuWOq8KhVzQn$`~jZjQ^vZZ?0FZ>k{{W97h(6 literal 0 HcmV?d00001 From 8f912272c6efc1c0344ccf178fbc045941d6d152 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Sun, 17 Feb 2013 13:01:50 +0100 Subject: [PATCH 005/118] Add collection info support to Subsonic. --- subsonic/subsonic.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/subsonic/subsonic.js b/subsonic/subsonic.js index 36ab70e15..d789c6c81 100644 --- a/subsonic/subsonic.js +++ b/subsonic/subsonic.js @@ -404,6 +404,18 @@ var SubsonicResolver = Tomahawk.extend(TomahawkResolver, { "\"&album=\"" + encodeURIComponent(album) + "\"&count=200"; this.executeTracksQuery(qid, search_url, artist, album); + }, + + collection: function() + { + //strip http:// and trailing slash + var desc = this.subsonic_url.replace(/^http:\/\//,"") + .replace(/\/$/, "") + .replace(/\/remote.php\/submedia/, ""); + return { + prettyname: "Subsonic", + description: desc + }; } }); From 215967a57f68a9991c4eb4ca8dfa5ad09769c016 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Sun, 17 Feb 2013 13:07:54 +0100 Subject: [PATCH 006/118] Add collection info support to Ampache. --- ampache/ampache-resolver.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ampache/ampache-resolver.js b/ampache/ampache-resolver.js index 59b834ac0..1915da229 100644 --- a/ampache/ampache-resolver.js +++ b/ampache/ampache-resolver.js @@ -29,6 +29,7 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { timeout: 5, limit: 10 }, + getConfigUi: function () { var uiData = Tomahawk.readBase64("config.ui"); return { @@ -54,6 +55,7 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { }] }; }, + newConfigSaved: function () { var userConfig = this.getUserConfig(); if ((userConfig.username != this.username) || (userConfig.password != this.password) || (userConfig.ampache != this.ampache)) { @@ -67,6 +69,7 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { this.init(); } }, + init: function () { // check resolver is properly configured var userConfig = this.getUserConfig(); @@ -132,6 +135,7 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { this.element = document.createElement('div'); }, + generateUrl: function (action, auth, params) { var ampacheUrl = this.ampache + "/server/xml.server.php?"; if (params === undefined) params = []; @@ -164,11 +168,13 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { // this is called from window scope (setInterval), so we need to make methods and data accessible from there Tomahawk.log(AmpacheResolver.apiCall('ping', AmpacheResolver.auth, {}, function () {})); }, + decodeEntity : function(str) { this.element.innerHTML = str; return this.element.textContent; }, + parseSongResponse: function(responseString) { // parse xml var domParser = new DOMParser(); @@ -204,6 +210,7 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { } return results; }, + parseSearchResponse: function (qid, responseString) { var results = this.parseSongResponse(responseString); @@ -216,9 +223,11 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.addTrackResults(return1); //Tomahawk.dumpResult( return1 ); }, + resolve: function (qid, artist, album, title) { return this.search(qid, title); }, + search: function (qid, searchString) { if (!this.ready) return { qid: qid @@ -276,6 +285,7 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.addArtistResults( return_artists ); } ); }, + albums: function (qid, artist) { var artistId = this.artistIds[artist]; this.albumIdsForArtist = {}; @@ -322,6 +332,7 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.addAlbumResults( return_albums ); } ); }, + tracks: function (qid, artist, album) { var artistObject = this.albumIdsForArtist[artist]; var albumId = artistObject[album]; @@ -357,6 +368,18 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.log("Ampache tracks about to return: " + JSON.stringify( return_tracks )); Tomahawk.addAlbumTrackResults( return_tracks ); } ); + }, + + collection: function() + { + //strip http:// and trailing slash + var desc = this.ampache.replace(/^http:\/\//,"") + .replace(/\/$/, "") + .replace(/\/remote.php\/ampache/, ""); + return { + prettyname: "Ampache", + description: desc + }; } }); From 3a7188e1715a262c9de5834add49b551961da074 Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Sun, 17 Feb 2013 20:31:04 +0100 Subject: [PATCH 007/118] adding musicManager, on working version --- dropbox/musicManager.js | 135 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 dropbox/musicManager.js diff --git a/dropbox/musicManager.js b/dropbox/musicManager.js new file mode 100644 index 000000000..6946c254b --- /dev/null +++ b/dropbox/musicManager.js @@ -0,0 +1,135 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012, mack-t + * Copyright 2012, Peter Loron + * Copyright 2013, Teo Mrnjavac + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + + initDatabase : function(userAccountParameters) + { + // get db infos + parse = JSON.parse(userAccountParameters) ; + var token = parse.token ; + var username = parse.username; + + var db = openDatabase(username, '1.0', 'DropBox Muic Database', 2 * 1024 * 1024); + // tx.executeSql('CREATE TABLE IF NOT EXISTS track (id integer primary key autoincrement, title , artist, album, year, genre, url)'); + db.transaction(function (transaction) { + transaction.executeSql("CREATE TABLE IF NOT EXISTS track (" + + "title VARCHAR(20) NOT NULL ," + + "artist VARCHAR(20) NOT NULL ,"+ + "album VARCHAR(20) NOT NULL ,"+ + "year VARCHAR(4) , "+ + "genre VARCHAR(15) ,"+ + "url VARCHAR(50) NOT NULL ,"); + }); + + db.transaction(function (tx) { + tx.executeSql('CREATE TABLE IF NOT EXISTS dbinfo (token primary key, username )'); + }); + + }, + + // delete the database ( token & username required ) + deleteDatabase : function(userAccountParameters) + { + // TODO : erase dbinfo table ?? + }, + + + // Database content management + + addTrack : function(JsonTrackDetails) + { + parse = JSON.parse(JsonTrackDetails) ; + var title = parse.title ; + var artists = parse.arist ; var concatartists ; + var albums = parse.album ; var concatalbums ; + var years = parse.year ; var concatyears ; + var genres = parse.genre ; var concatgenres ; + var url = parse.url ; + + // Checking presence in the database before adding + // TODO : request :) + + // Multiple artist + if (artists.length > 1) { + var len = artists.length ; + for (var i = 0; i < len; i++) { + concatartists = artists[i].artist.trim().toLowerCase() + ";" + } + artists = concatartists ; + } + + // Miltiple Album + if (albums.length > 1) { + var len = albums.length ; + for (var i = 0; i < len; i++) { + concatalbums += albums[i].album.trim().toLowerCase() + ";" + } + albums = concatalbums ; + } + //Multiple Year + if (years.length > 1) { + var len = years.length + for (var i = 0; i < len; i++) { + concatyears += years[i].year.trim().toLowerCase() + ";" + } + years = concatyears ; + } + + //Multiple genre + if (var genres.length > 1) { + var len = genres.length ; + for (var i = 0; i < len; i++) { + concatgenres += genres[i].genre.trim().toLowerCase() + ";" + } + genres = concatgenres ; + } + + // Track Insertion + db.transaction(function (tx) { + tx.executeSql('INSERT INTO track (title, artist, album, year, genre, url) VALUES (?, ?, ?, ?, ?, ?)', + [title, artists, albums, years, genres, url]); + }); + }, + + + artistRequest : function(artist) + { + artist = artist.trim().toLowerCase() ; + db.transaction(function (tx) { + tx.executeSql('SELECT album FROM track WHERE artist LIKE % "'+ artist+ '"%' , [], function (tx, results ) { + // check : results.rows.length, i; + // TODO : if the track with the required artist has severals album : explode on the ";" + // TODO : create a Json as return or string : check script Collection needs ?! + }); + }); + }, + + // search for the artist' album + albumRequest : function() + { + + + }, + + // search for the artist + trackRequest : function() + { + + + }, \ No newline at end of file From 90a5572fbe1a858eb96fc618310519060948b5b4 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Tue, 19 Feb 2013 15:38:28 +0100 Subject: [PATCH 008/118] Add Oauth authentification to Dropbox resolver. --- dropbox/config.ui | 127 ++++++++++++++-------------- dropbox/dropbox.js | 156 +++++++++++++++++++++++++++++++---- dropbox/dropbox.png | Bin 45123 -> 12978 bytes dropbox/jsOAuth-1.3.6.min.js | 1 + 4 files changed, 206 insertions(+), 78 deletions(-) create mode 100644 dropbox/jsOAuth-1.3.6.min.js diff --git a/dropbox/config.ui b/dropbox/config.ui index 73d05cb09..d40819a8a 100644 --- a/dropbox/config.ui +++ b/dropbox/config.ui @@ -1,77 +1,78 @@ - DropboxConfig - + Form + 0 0 - 410 - 436 + 447 + 305 Form - - - - 20 - 150 - 361 - 251 - - - - - - - - - false - - - Delete - - - false - - - false - - - - - - - Nd - - - - - - - Associate - - - false - - - - - - - Account : - - - - - - - + + + + + + + + dropbox.png + + + Qt::AlignCenter + + + + + + + QFormLayout::FieldsStayAtSizeHint + + + Qt::AlignJustify|Qt::AlignVCenter + + + Qt::AlignJustify|Qt::AlignTop + + + + + Account : + + + + + + + nd + + + + + + + Associate + + + + + + + true + + + Delete + + + + + + - - - + diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index 9a373b528..391579f8c 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -1,9 +1,12 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { - + oauth: null, + uid: '', + cursor: '', + settings: { name: 'Dropbox', weight: 60, - icon : 'dropbox.png', + icon : 'dropbox.png', timeout: 15 }, @@ -12,15 +15,24 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { return { "widget": uiData, - fields: [/*{ - name: "username", - widget: "usernameLineEdit", - property: "text" - }, { - name: "password", - widget: "passwordLineEdit", - property: "text" - }, */], + fields: [{ + name: "associateButton", + widget: "associateButton", + property: "text", + connections : [ { + signal: "clicked()", + javascriptCallback: "resolver.associateClicked();" + }] + }, + { + name: "deleteButton", + widget: "deleteButton", + property: "text", + connections : [ { + signal: "clicked()", + javascriptCallback: "resolver.deleteClicked();" + }] + },], images: [{ "dropbox.png": Tomahawk.readBase64("dropbox.png") }, ] @@ -28,17 +40,131 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { }, newConfigSaved: function () { - //Tomahawk.log("Trying to open a webpage"); - //Tomahawk.openURL("http://google.fr"); - //window.open("http://google.fr"); - //Tomahawk.log("Page opened"); }, + associateClicked: function () { + Tomahawk.log("Associate was clicked"); + this.oauth.fetchRequestToken(this.openAcceptPage, this.queryFailure); + }, + + deleteClicked: function () { + Tomahawk.log("Delete was clicked"); + }, + + openAcceptPage: function(url) { + Tomahawk.requestWebView("acceptPage", url); + + //acceptPage.setWindowModality(2); + //acceptPage.resize(acceptPage.height(), 800); + + acceptPage.show(); + acceptPage.urlChanged.connect(Tomahawk.resolver.instance, function(url){ + this.onUrlChanged(url.toString()); + }); + }, + + onUrlChanged: function(url){ + Tomahawk.log("URL returned : \'" + url+"\'"); + + if(url === 'https://www.dropbox.com/1/oauth/authorize'){ + this.oauth.fetchAccessToken(this.onAccessTokenReceived, this.queryFailure); + } + + if(url === 'https://www.dropbox.com/home'){ + Tomahawk.log("Refused"); + //close webpage + } + }, + + onAccessTokenReceived: function(data){ + //parse response + var i = 0, arr = data.text.split('&'), len = arr.length, obj = {}; + for (; i < len; ++i) { + var pair = arr[i].split('='); + obj[OAuth.urlDecode(pair[0])] = OAuth.urlDecode(pair[1]); + } + + //TODO close webpage + Tomahawk.log("Setting DB"); + + window.localStorage.setItem('accessTokenKey',obj.oauth_token); + window.localStorage.setItem('accessTokenSecret',obj.oauth_token_secret); + window.localStorage.setItem('cursor',''); + + Tomahawk.log("DB setted"); + this.updateDatabase(); + }, + + queryFailure: function(data) { + Tomahawk.log("Request Failed : " + data); + }, + + init: function () { + Tomahawk.log("Beginnning INIT of Dropbox resovler"); + Tomahawk.log(this.db.setItem); + Tomahawk.addLocalJSFile('jsOAuth-1.3.6.min.js'); + //Tomahawk.addLocalJSFile("musicManager.js"); + + this.cursor = this.db.getItem('cursor',''); + + this.oauth = OAuth({ + consumerKey: '7scivkf1tstl8dl', + consumerSecret: 'lu05s08m19h0dib', + requestTokenUrl: 'https://api.dropbox.com/1/oauth/request_token', + authorizationUrl: 'https://www.dropbox.com/1/oauth/authorize', + accessTokenUrl: 'https://api.dropbox.com/1/oauth/access_token', + accessTokenKey: this.db.getItem('accessTokenKey',''), + accessTokenSecret: this.db.getItem('accessTokenSecret','') + }); + + //TODO updateDatabase every 30 min (and handle if a user asked for a DB refresh before) + this.updateDatabase(); + }, + + updateDatabase: function(){ + Tomahawk.log("Sending Delta Query : "); + this.oauth.postJSON('https://api.dropbox.com/1/delta', {'cursor': ''}, this.deltaCallback, this.queryFailure); + }, + + deltaCallback: function(response){ + //TODO set cursor in DB + Tomahawk.log("Delta results : "); + Tomahawk.log(response.text); + }, + + db: { + setItem: window.localStorage.setItem, + getItem: function (key, defaultResponse){ + var result = window.localStorage.getItem(key); + result = (result == null)? defaultResponse : result; + + Tomahawk.log("DB: loaded "+key+" : '"+ result+"' "); + + return result; + } + }, + resolve: function (qid, artist, album, title) { //this.doSearchOrResolve(qid, title, 1); }, + search: function (qid, searchString) { //this.doSearchOrResolve(qid, searchString, 15); + }, + + artists: function( qid ) + { + + }, + + albums: function( qid, artist ) + { + + }, + + tracks: function( qid, artist, album ) + { + } }); diff --git a/dropbox/dropbox.png b/dropbox/dropbox.png index f8810b451bb5b550e71029214ea8b73115dfbb66..98dde27d8694472aafd4427f9581c79d60c8d1ef 100755 GIT binary patch literal 12978 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 amC9s=2H5yKdH{b31t2G-ELkaT68Jxyx!>~u literal 45123 zcmeEtWm6nov^7qGLvVL@f?I%~ArPFw-7Vml zTT@-#)78^wy8HCrYwfl6uOCXX=qSV}FfcIa@^W8QVPIfy|64vFLHCRnu%z z?)m5>2XKLbVW;_Tfdv+eyZ^V--ATgo|BnTu*ia|}JtvI(R|$3C%2|#_wwbJ3Q|=#c z$H8IGUAqMvIs}{#Sdx@q08vwtcD)L+R?$Wzk(m;kWYPyBRe zaC_)%KKZxnI(dsAUp_zPsyylGCvKg8Sy9sVZ^5@*Dd&cKw^LRHS6U@`KgRwR2D*VO z?Roz@k0r8zQ2{kCsEQG~!4`nhRsh{-fMGs@evO=g`@aMJm-pdI%hY@KH*wdJ=}UQQ z2c!T3SPuAsfYZSCfGZhHMHLVtk`=PS2fdG^$XzHRD32%Ns1xg#7k0P*G&3U*30$Q; zQP|-(VDwPz;77oS5qbW^z@lk*_2ip9oV|@Mgx2Os&G&~KFhO8v40+znGxRZilfVXI zLOy{P0E-~x4l+-|F3d-rLgaGB$@tTNO$3nm>0NmM!XrH-4LlgwFdeL+Lm(=ph5rdv z5B5bAB0Kl1wd_sp!QT++g&z|9rDPgjE7>Iv=7kh;Ifi#bOy%tOP6Igw%UG;EN7gw( z$BUB2gqVWg;Ws|+opLDAgH(kMhxtCda6x#6dR0|2Q*z1c z5bUkhz~9r3U#vydr&2=cVGJ;QV3t#=tMoa)BuX*`1_l)i+osDMh&-;uPyKU*dyVnq ziR8vS4G>54!yj5OWGtP^;cbu(8^-O(b@4Zh{95q_(}J~L$$}bz(pDFbMvd8u3F}zI z?&^RZ-H#O-X0M-m8U}ArKf$fe8O@Lgr}tns3MY>K!dp`~?Wmw~(t^;+@s|M50Y|;I zkE@A?#zD%dw_-~;M5KyF$A2iX3jc!3t-KL-z|Djj0v+Io9_kAVL>TOJE^Q0;BrF4; z@QtRFqg890T49pC3QpQClJL0^Dtx4Mm}q_04Zx(9myMi}V@>RMa+HH(pyancp}OZ> zvuLeYjOPJe47mWRjlI+I35f<0k8`Vcowusv$^OyB_yvz#4+8(z>?i1ickO5+z6d}t zPC`h*gy|7fp9tBHnnaoj+9cy{w&KHe=|ipv9mFv(LC#xLpT?M0L}6ZtsV^ey<_Ndm zsUM6SU!(AliENjqFtS#tKF15Sk`n@^K#}OelfYQT04`8;j*Gu{k?T!$0-}_275uD_ zYcV}=Kl_YkVg5^p!d#);ox3xk zv=b9UnV6hB@R#<*r4U*o-Mf}t(dlBqAo1%!%6>RXo3j`iHBq}G^0S3ug#ag^fq>QW zG`xKvgBwn2wnkN$tmJt@=r^x?7Sq4*!VVOmID|tEy?x_!B&mQu{94@( z&X1zjth3@xk}V`1(^ys++;}R9bi=9hvwjjWmka6V$_QXmqa2+>$9xz;k#26DEBY(C z--pI14GWOEVZ8WOWrR#Be-0iu_T{ zaE5Sx2)uf#AcXIcY6pcd9Yl}v7M|*hxgL&I{C1aIcFe>w%nnLDtMznuVK6Nnn^WXE z4gzOHQKAV6tWV6oLl_oVkEmPfh2kRS%e5$v=Clo>(&sIuY^E(Ot5bNM%)c1VCD#ud z`)#{{2HZx#+X~Ce-`i%x%5>xNuT=)LfQys}{uhF23l0S`o$#u$13~Zu&tw&UC4IA- z8CsU`R;y_06tLE@Qq0Z5>>^VTvxsS$-%Xt7Ut?LQ#QLWFBr!+;)lm3IfN%R_#oWup zj(xJny5%uo5#5|TNy6x5I zvjiuHUtir!DG7QqBDeErV}m~>em5+)%pR{Ipow{-Ot~@5_eF3GubLa8F}D&A zHhWZ3K^4}4ClO{9ZbL7>0jZubd6tknM-6ND*EjaYH>YM{2)oC5nQ-hoxOE^d1%xR5 zT{yy2xAyA7dlaRmFpZ=Q1^4_ZF#i_L5N=A1)INlqywUp=jx6Eu+HdsaBhakR#bjnT zI(vI@`qzhN+j#wdmecFck+PFhc<~i?f2AZB)l3|)sH%&mQg}O@D7Wa~!@9FAE2#Ia zCht35GB|avDwu&)`i?DjV3X)GBa5G&cfK86-MM8mYaOW8HQZ8TrpPKER@=}B8oVV9 zW4^FWC)HVK!-KxtLlPxg@>b(f_Y9OR>35{TykK#z^-K*w_wT%FyGS{!*G=r3=&~6? zc*PPdo!$YA(fM*#U18FNsB~|OY*UVpT|y;I9}K!ioaULonb~53iS(i)o;~aUj47d%MZOVO;J7 zm;O8|3T+3GGs38T_$~)Mk_6h;sQB=QVI&NIHO2xJM)+ls!_`S(pOht1lLxUE^`sfK zTiQ3a174fIO?!Rj4sIK>wIh%rq9tJzOO~A?t8sP74#X;iCb;*|$DT{Ov7;23{GhJu zBZMx@vgUP7|87c4;L}h|l@-tdvmuoHGEd#x=Cj1ZfsO?y&|u2ZY83is_5_8thsSP* zE+n1dnqdEa5Lr2@WkKIXl*7E%`q6w*ZeEAEhnBUPPZM&rWU6?xc3OsfDAJDwTBKpq zxfK7%FoGqlJTbv(Nc@F(STF2rnOKh+2`@8S2+H%wj!lu_6R+IlPow926{Y-Yqvh#- zb)J+y`EgGk&^RpyJ;d%bnP(s?j*wh@cW46l4(4a-DS{tHOa1h&W@@$;wMu3NUAn== z`Q3RKub{QJkcz#)6oQUexQ@xmN>Hh=?UE-xIY~muw4Ole9YjOU^@JCk3lsO*>t$qT zHhR+9eES%FBWkXy3navaEEwE0;AGsqJp#Klb#P@cf%)p$X3U0&L}bWxSHaZ7vZ!F$ ztSVHUa=;S5m%qs8wKkGyj4hS=*OXiw5mRr;6p$7^B)~k`SK1;Wz%gCsv*l?JxBZ7| z^x6Ge;)HF-9J~+a4)+85oKM;QG?~|_3wj-oFI|0?aO-NrQS!85%4b zdqBhSzDZz}jyYpUDhcK<)Afp*w?nFew{p4Qv|*VzeZXfSEb&molB)1l*$V>Otpau_ zN6j%4oJ@~xArj?zlx5(;K|a4N@TFqETP^lVePZo278Py_WpBfuZs+Bn>y5Me#^!Wz#;1{u7{RI@GBG&&ww{gTqFH~S zVPjq`3?RX5D>G{~5~2|ZrbWb17cU(o5p^){Zo$RA)|xX&S75!FN~^bH^@*!W?9` z5gDv!wX|X1YBMyG7Ak;m$*SEYe6!qg()+K6ebSADm88vxI{|sK;^C3LsN=Bi=8;$7 z<|nVSftb`7UF~d5(|BF$cv7#L&OpNNr{Cuz@c(5H=W*iE5{%k{n8WAKW&sZ{6jJz2 zWHID_>o|YsH6vj|&gFowr3sJ~T=~W-AN{QDYrkGPQD;ActN5utfa7FPLt6kq?Y6_X zbAQH9KDB%d?{1NDds!=Y@=_%;teIMPl3?MlcG*2-eZ`uH{mWKAcgwuPlg`99z3*n{ z!(bLoBG4vsr)RI3(7CeVpiEK2xnp2jfmhAhG>6kuJ>FH}8-Jg+2}*Es0Uq~^*2}e+ zlp`(q*@U-_`e-S{z@1?o0DML29bH_q(R|6K=)`@bgcN?!EgY;Ap?OX~iTx{e(1Tn1 z>HP+^9nIE-iQTQfQcV{l_-w(pb0v4y)bq)PDSHj!`Ymlx?-!V@37#b}k?TMDuD}?^`Z;g$tbQfuqwr{ZNHI8s5r`6x}?t&yg z%PuWaH9l9vy`elx77kX6xTsI1F%VF<4__j!oN_3hkI?jniq_<#ON!^*YW~Yekr51J zgmnC-5TY4H4<{X@KUnIQ0b|lwMv7ySI^4FTFqos(!Td{oCg>!fA{ioCAfR-leHyQ= z>+?Ce`GU_c(WvO?hJ7K37#AlO!d}NCLPEWF(}8=ubwByr{JPGBZew>e$AilEuYU-@ z#*n{!7$S#GX< zit?uvxn!TitJsM77N0R&boP5k1~dqSL;)?%Fb16qGZ`uMcb*`0+kj2!L|emUXn;P9 zMR~s7HrdNQy~O%9c#P(5R%cPM{p1Tfc^VpYM_Z<7W}Z10RfBmT;<$lZSGX8CHTgPy z8Xr2#0y@6@fsYUHr#9~hFf zTCl`};gBNkeBt9Ey@@FQju^pK*P~_;e=4_jX6c?nEvvy0xDJS zhx&r1N@*u{@2uUGU6L4T1TALoxop|6xJ;e1>m4$%BBBJ zCeAao7WUZo{q>Gxp|6AAu_do}246tomll;cCJwSEDuX4IhiY@&LQfqn)i0@hK2xY8kFsUq34QIaK%(pHXOgW;DCqqjJo4qH2IY~+>`qu}%+|6ifw#hu zUvI%wJMBTS&*9I4x@W37x@Fkvw!JQ#yDNzgZ=eJIW}v`zC+U2Ae?i1vj8BLVS8k*d zk@hN*ZWKs$S!LQM0kJSyQul*aHD8BwrHG?V({z0S1Yov%^)QtEL#l-S3u5P$S$z0{ zA?#o2b%1AO*qq=`;r13}(5(3o(d2Su2!VzQeroN~Y|@?2zk>h*G;L}Yx7T_g7d78z z)K`t6cPA;-!!XH*@xYyYreVBSr+1)l4DJ2y5T- z9@Bu@$Wp>?Hxe{a!BKupZ>1E`ey0KUVuIl|@-GuW24c~B{5%4Au@~%<6>qPva&2`r z^p;kbq@VCg4g%{SKqJ;LC<^7a(pLM>a$00MNi=DOvg|ZaUm74XSoI~7%$G0+6I}wa zlWPwvs-HqKGsw)A0Bt@DM}562k~2O0^IfzCZATSmZGS)Ea@nC&FSMSqF4#+OFBlu` zy<%}OC>)>I~$Qy+G+cvxSSjcj}z3CSI?#QLLyr ze*X_YkFs!FxL~=_pl@H_-H%&|ejjU2nXd5RulOw-#GHEV8+Dz7TiD&XcN(sgcpu*b z?X>6q8h=!gFchNh+duJ-=jkcCW{`55DXJ-1ca~tVt6Xj>!SPx|UYaqD32`&MT%J4j zTulu?^+qdJcaL#PV))`!{!Rc9ay7_dA==9~{Kk#&=cZf22;DZ4Q!ifH9xysXJYu$U z1opIRN-2| zHI2Pa65*x7x5?%0*l`xM{KSX-H@-Dnp0fu5qsZv;Zm@i|aQb0Dus?-Y_MPiqK&~YD zGkhZf`ZeH?X4DB=(_G}I8#`g))vAo@Do~vi7j6<28EvtuUT?-UqBB2vY#HcEot5q{ z(`8$!YiOoEML-ao{n3x~@uS5Pl{aQmnX!Glxh{hpW6(F+nW%>Lva30F9S*+W z@Z()} z3_Ou)1It#6%6xuDLZ-=oyIBDbRGrvW4!29XMC;P5KZ8 z;Xb3LZWjy=Iw*X0W&g}jWrLlCE}C}Vn^~~kWEvK(EQ}VPv7FgRCK%fmZ!JZfLx386 zF+~8v0+K*H`v7)f>FqW{Hk^*FMNl;D@~D1dow6@+-rm-*c$1^cR=$F^J52h1N^R0{ zRXujSZJ3V$&PwpSQaS;NVq|Zdkn~`_{bPq}~LZ>T7fPO7zovcHm-D0JOdm znYGJG0Jn+agVEA7ZR$V?TSxQGU?lsBc-U{?Vc%UtkGvmQn0WGY)|u8F3((R+u+g^c zY@OR+kuzvML0xSB9`&^@3>q~wB@lg$ho~?sl;JmfEAUGj$@C4$L5rqD5h6++`=jJq z<%*0wx=jcjz#$WKo>-+nb`toWjt;l!BwvsoCHkC-+TVg$ozQ#jQ@bk|lt^nIm=8wN z8&)zK8BnWr9iLK-zZp)*H4d%)9)+11h7?BVT0qA9vbag`ZY{%ML8vb@kW28vb5vtj zZ~s(H<9c1^x=~JH;`5WF$_V#Y91_tSqDc}y!YY8}aLCO{f0g6}x_^91QoHKcXpgsu zwmtse6Hy9gGb-ey!^PrL`NRHvuSSkLEFkaIZPsBwZ8n3K63l7lJ;jSixxR!s zC3z)Jdq{p!*Dr4DH4*`4Af9~42ru{;9rN?FE zxvDw(V;ZYn@RtN)9}~ndFp608Kze5%TpHk^Mj%t!xOg#6%!d!A1=U7s%@%2vJc}r* zPSSNkN@7x3Gy&WToEZ~Y;;!g*^3SFxnKz7w0}3Bs*>H2@4z4}8m1lHMx`}(+sBbMr zLtzx=h0H|>^oZotP$&CE!z8VqcEkn?OAi}ad_Sq?{@Vq|#E?J083#DRzacDX`*(YO zV69-*7K)~+^r{ON;?P7OuT{Mm>EX3SJB2e|@E8F8)tXgOQRgPlOdLX+h z-j!GCdkzlO$9(^OJ1*HiAGP-4SuZGwD@|Ol`dOY5`n5uY-~rg>TfcwOn5xH^0jZ}3 zG%i$7z`T))>WVX{PvwHBRdueQB0>h< zO$M`mcE5Yk!-KbWR{==k8tx5OP&k+Rt`7BYUN25@tn-=E3X{F`ZifI|lQbx;I;h#c z*6xH;fD+W+V=G&ror|y$YO|nLKrxYIij~!a3I7+aqVn%i!p(JTw6S;l+!XzR__lfhVmmT1lTz*;?{RW}HTp64o_w30_YZxtRvV*SR zHo={8mX)dsfxoSvi<7N9Udtq2=c^J9MJ|GV>*UG;UZPB~_oY zOoZKl@qv5%exj2dBodGl45~10fgwQ&yQ-tP^TPiv!dsSx_IP*?7H$GGxqlmM0+>fr z)djqe6eSj9v|>C87li=_{w446_x@o`{v^vZ9a?ogH+RqjO@}$U#k{tLNWN2L zml6svnfG59=@MBV&a=>}bu4QYa~T%aRVO9BzOKvd{U$n+NZi~|)?cWVJ&;@I8Q}Yt z6*!$J;^!92IEfoR7QT(~I8g~(t!;ZeN*A0YQqB|P;~6mbY;4a^t%D`ZT$

I1o~QDv9PU-bvp?`* z;FHPBq7O6OQYR|5QN2Zx2S}G;sA+`p_6%OJ&17Hd!G-9A(0aDZV$|uNVf`iP5Rn&L z&BRZ>GGZp)`&|v4kfq@Pn{VO98XHcNA1A+ulZ7*glqFoGxY@zJVF7tnxvsxcI^23| zD`*zv8AjYP`3vJnW>Z&QjI7f18es^*#od8a=WTU*!$%}d5|C57Z+aw-#t6m!4m!Wf z%kqWjanev7>BhVC8p1m0_E2?U{K6QkDT^T^M72c;b3c{GnJmh}cVSys$49v|{v7D@ zL92?d!k&N42jN0=nMX9b~-$%j*u|@Py6}?V$Lesxi{LT2sPQ$^>*}y`XXi2l%bSY1&75? z>5%Nrcji0LiouvTobA$&kb*nKjUk3e zN*r69eAI{gj(^@`CW3FmE?CjbMDib^2Qr7NSlJqNE6=`mXcF}6c)De6#}-0{td+Sk z6F8Bn_r#G!Ft3yzKdUh@S4y*>KGO}QJ<=a65BD+Q()9ij!L>oB!FfvM?W_76nfcqY z@-XETP4p>1`O=+~H0{FIZ3h7JrhGSPh=9QXuJ$LdK5Ng zfXMZIYZ|>_wyUhCH}U+jv?-7_oo427$w~%r@hjv4wcn`l%p$uqm=?yDz&Y8q+w&#U z%K)mVn^^EjjddnG%}{ua;3*diskl}##*{2T81JSG1GK7}J5008T}q8bGWdthupU2d z`3E-hdcB~2FaP-Lk}$vMNC}AL*~q<#M@7?JL0ix7^^(p0V_!a#O^cC;yU^VIU|{Cy zkV_|j7||we<0KwIXq%0>iTFaJdMOqvJMwuEk9B>)rD@MXcb-{6ZL4D}1q|-*G^u{c zbi=nT8Mitag5i+RA^4jMh-pscsiZ#gr0sY!@5A8K^`E9`O7@+%z)tX>{k0gLG;<52 zMeU*qcsQ%+aMk}}ba>b7$2HTiLlFPu#O_Lk+2Aih+HCQ%5gpoyXw}Q5>I|%IcP?%% zBMNde+nPT`-}E*Hw>5bRx4^nmYAEwl;*pKMeeh~UZIc*#5|7S)9f#ah0-6utm$W(2 z%wE;SE#{rg1rvb7XTGNvz;iDt-98`G8S*U;EboQb(kJCA8CD+uXuvuG*%bcpgouJs z!wy}P{=6Q5zU5@cMGDzx6QeecEu>E1-sNzd9;&-tX6!fDtZ7dKZG;P0`Vw=kr++fQ ztjre<8b_3h7aFM@X{i$_OKB=5heA=$o78~7j)a@D3`i)|15;T%$ukW0w%U6f!m=i}Qw%`IRd>M$3J&h2V!|Ro-wF zO{9I?6&m0w-#7maNbzfIeTwy`%#+?SWWkcm9vVNiPC+S0nK7aXO;^~81~GEzG(m7W z7wSET4X7q}TJu*xOLFExPeQ{vUWru?_Q4WZK6-$deQwYDi~q6qZ!%yI-g@4$Q#2%y zHDuzG7P`q?od!T&Zqus8eQ7GI+2`e>HODgk1jiJH9NFz5`YV7jMPy(7Fs81KQCKd< z(w3mYp?=LBt!nd7fbaNYWyoPUstNqr7v?eploxs@kHSH5igD(n(|}yr39f_Wf~OUL z=fIB!@-%@F-Unu1Mkbbc1!mE?YHjnQVZhsAZSuNhk=g7VTc|DSc79Mk$8EF{(1Zbr zTgWXrMP|oX1Y5M#3*GLxM$aGY^6+!ejN16I%@doNUMUS4=^pB9d~rd%;JZX1~$1Go`DbwB$(LKQRPOWo2x zNkTS_em&^rNtUfY<1r*u@!CTsP|+MW>;Rh%5wn8BB}jruZ@f_8f|F^*wx$@=g~-+R z=+Vb&F%X`tX|EgZ%!w8BO{CanQ^tP%H)GHZCwcFmf^Gd(_$oc~j}_TO_)<_^X-_m8 z_3raN9a( z?ZVdK5Ir||P+4kZByzu`Gm|Aducu;@eq5AW#oA$BUM!5`^(EEr5E#l*Kv*K~u5)1*;eQqmYz~omMKlP!&YmD&iJW|H z)1=5kMTZ9*VRX}jYX79OL|*R!jkp6D1Df@)u1zOLx#M}GlSymYgYfptu6FL?y?{@| zy-@sIWnep`jr|W0_L(XX{F*!D;7fx(vmkRmC5*i~Oku9MDr+c;`7qDA7W6ZOT)})< z<99mCh}v%8oF{i+K0ifW6^ofKva1;y{{?!>xl!nqc2)Se>rn~g_ps`V1ueX7wk)K`d(>?~&NN%L?Gm@`43=?(ZIjbiaBo>z-YP?E5Gj&`;p3T$*{IZ9A#evC z*7^0W6zqougLGrT(;t;}Y5lO=QXGT>{z`s^R0nz!xI{;>9U*Rc2N=RFjCBzT*V^0H zgQ`C0oye04INnz1seq72pRm^)g;jqJU_{Fr?{ zH($o8)IKgxC88gkZ$ME>aa|~qj}w6?%G_%cw>x3mZeB(x+T~drhzzG zDJ#lP>Pku;K2Z@;YRT*Ug#2|(yp3>I2Th_`uFn{GM%_Ftoq@b=Vd|6QG%)(6ud%?_ z*AM#GcSHmZk1J6;wb&^+=TG7-TMDZ}u~?W8@cGJ+$<&Q*O(d(_(Nc+*-RhC?lw^KX|E7la6qAO*ZsByDgG!h|>T`dpR@ zpr+^v4QWsA?6lBYUMJ%?W4CT6OH3b&>RnfWB*ZOi-ZlVsYfCcDlndb%afto3;F+I9 z2g-g!Hnv%2zf(gEwl+4gzh3(T=Ecx`Vb?*od0$Lwu~YLXl%> zLtu5Fw^KRrrVipT*)x9%CFpF1Yo{&mA-!X_Dy>*@0sjcDA2`DDC}cq&X&MQl1LwSh zz*8jJN-@H2b{fepU{7WChKlp(qfumS;q#&v?VD2iGuWEWMeenX-KJo!T>pYGx#3S5 zxe7x5c;@UTX9!PNkwgM&_LQkPg2po1Azdd?R7c41hus@1sErRlt;UjYS<8i38D!Vz z9KNU|X9!S!p4!B(Euo<$Ar@pX?BN2^CZ?iq?~`!rEfHLW>YHB(lB&sr5&k& zh!e`&&2%!&u3yt&uRsljK;70~Z|n`_$Y@^>v+=}>C1jm7E4EIF`|8T$Ya+AE6^RS*BWZfm9#@Ht&=bI_swLWXINfVkPB^}P5O|qTJF^|PZ`lX zRQ1$29upnDKVIV;HUk_lCN27;YLb3Y?$^J9MsOSEW9|{UiaC&-d8>xWGajX)Nj>m| zK46xv_wZf_sxvzQon89ZpmYg?V?Y4E9%CK$J)|M+AK-*^hZ=SFm*r%-<@f0+jhgHX zCt3sHGA5QN9YWEDDYXyU>*UiZjYS)|YTrF+2+M&hJYmgx$-6yo@g(kpB0!OnY&nqP z@BPvdl>fnFJ>5SahbEHSV}&F01qQ}(ZtB6_fpHuQK>SrE2ee1~t)E*2@jYHo{W3jK z-V9Z=C@t~`u@J)q>@VQBfzo z3~^I?MmrIFuv$+4EAND*42 zZ2cij&s-VI`y*mYartIgKb8bj5C@s8RdBfclbqqLcwSYsHy7Z<5Bg?I{rkB!7(lK5 z2_@hv(oz}jG%EF?<8Z8qX2DFb81c887>fm3usv+~3XOAqx2JN)6b2VM*qe~e)0wKn z%D&GjZNJ2qtC=)HkZ*fPM~dF+mJx6NrEI@#556~$>+xup$%FL94306xr4MTOm6Z!` zly=P0F)c$Rqt$=sPv8lCfSZH|54C#j7%%>|gy#M|w3J9o?rBJSosWDDLqqC@BzR>a zJ~q2s-O%t&RV;?<#~)DT0|8vu9o%SaS3Jk%9|&YP{R$y6U&+ke69@1iX1i(^G{v*eV7CM$*11g_tw<0N)??k&g}MQB%cG5@t|7^kXp zo0?WC-bR$Ex}}(ro41@l73H5MI{U!yPaWwe|3Hd;Dh|5Uw^o18jWV(@`_9PZhr_S{ zqPkkCm@X2ez-oUTT?Grj#Uv7}33l4+0kg%!m6bZX|jP2kimkuy1%w z^A3dLlt+|@Cx2nrV&_gok@o_P{*>p57J?e>!|r{)=>1e2Fp)GRAv67fYqppp#P~I_ zQ)~%8F$yevC1rU0XyZLR1vKcOH*rbZPle~=zbNNaz21W>%vnn=>DC;bxe&T|n(>?b zL=(IAV&f^Ac;qWvIEXe*bHpo#N-A9kZ>Zv3tNGX4XlynoxVs{sCB6<8>Yk73ga36C zf~4sYQelk=g&@bAN1783FM9H#kA1U-Xe|!q=C+PQi|$%Lh?OE!sG`+pSWW8>Ctz=bc)7_uHu1HL`Fxhb6V`sq|jrp)eT& zsgXpL*?2ve{W(Y(11S__sFRu#@SIf^g}MmT#PpcJO;mAD#7~WIc+I z+~ktDOya&DatqLAN@il$J;o~xC9JE0E|%=m$3(%^BPiYfrsL*y$`Mv^igq*}P6*F_ z2kd+RVK+|x*`b7R&f!B+qu`q!5Z4;2duSLwnV>yc_$e@r633l^T>`f^c0tPLKhFer zhqaH%1x{rhzfO!gTHm(hM(=ZKh<(hK?0c0~gKx&U77^GcibI12rU@{YDpKKVMhfBp zO|cajU^MeSKL0-6$H?ii%vquHaDw76KidlqHLd#B(iD-?O<;N!G~W>_56gNrRk4b+ z!c_43><8@Ddy`s@P($i3crks*f8mSI9C3-`K`A(_1Dqesqu^G%4F}RZ+G9dpX(BOS zqi&lEsNTFATj3(|IaumKVIkhT%4- zm&>{_T22K&Nbkd^+U;-u$oS9FZmvBGBzD1@H278RP?4QoOOZ#w&rdn4r5VIE9R%F#1 zUbA`s&*3Q^Mr;W#&G&S*35wveG0d3W(uX1upsIz7SoSQFJx5~yn@W+b&TM@)0$Gv7 zOD;Te0tVk{=|)6~%bl-j>_vsK{RX$nRo`e4S@Db>5R)$;CWp#)g(ecv8r4wZbL=#~ za%W-&oX(8ct_sL{&}g~)p?Fq;E{40GfrSV;`tWkO8@rpdV~MjQXyV5K;gQREs>`^8 zmTq8GX?r1`A*JBhl~C}I)Rx&YPXaOfSxs~rsX3n8KIv7!Ls(U|xthmU4+EQ#92sw7 znUj8AXSeC=fpfv82U(x1U)NwuUPLdRNsT_?8| zc{H}#n?$uuJlTGo)4OUQoI|SbqFHV53vT<52OA-)7@7h?+YqHt{REdQ7~l)5k6G#A zQ47td3E^gFeH`V{q;T-X&Kgmo`sy+Q^Tj)mCBr?64hADekh#oUEvtVZ*113o!jgF6 z+42w{_a7c0X{TPP4~sM8+^NHng?s9AxG zN4jBWd9gO1#kIZ~^<2rzT19_ep1N$MyOJC5Vh;%Z1ZfpzddT_RBoT8!+jJq@p(r+W z^poRrCF2n#OO-f+4A$kkar*r^TQNw~G)xsEEDB%OU9rUZpbGPTp~w5D>nK8)#yRyt zr{{4CXU5S@X9{No_EZMW4b0{g~0a1%~!20AcOCG!y__QGFea%t`@L-hHSY{WxRWO~YbO-aZvsD&VV zQL~~l0CoqL69m!&hh0R>Ln*`$0}q4Fk2?66yLi?$KP4Q&f0{%*9tPID@_IHBl9vdt zRSJ>ISP>?qxPq3ta|T7A%uawC)_&S`-7|%7*ytU#&%S}q+FSw|(4mhh0t@YvbD)I7 zKK~#fbR3am{=IuD^-fWfbRV~8>&3rpMw=9i0VGLp^j#M0WcgKgVyp9Z`<~Sh9%+A# zGh$TlOeA#3Y5qB4TtC(EBChpPyQfTEmWn&1P1i8>@z1NX>;SZ9V$EsDNAxX<_=@{fi{cMLL!QrIczU0py3l4nIgxVjWas3&J zx~5)d53Mn>a1)F;p_O_s7gpqw#7)WG3G7MB2O;;|s}M~zGmD=Ds)_g3w0j%Z6|@q_ z)}arW;2fwJ$YM)iBL+bpEDEvq?S^_Q=}mr}|0ev*@#|AzUd%f7sSunODiyx6&bXZx zF1%Wa#0Idt2fMfm{hjS;^z{`!}|-Ww>T?H=nz_-N%*>PZb@dxQ`sP zNu9^KAa+`o?^CvGAAKlrBA=8_CgwZCcRzuKaTf^C$pF2;et8!Ryt|Sf&yTep`|wTo zU(xX33%=lN%*bFWS?gpYAATilx<#mPKwX;2aoX+T4j&*5ojPh&{FI1^o`PE?zSVN~ zyD<67=fx*`IA|-`LxR)4NRwg|AuxH7=!P}40EK}y-Gns23<@`0S~DgZ0}PDBer1!$ zf{P3JL1VkL@`-y5ZwAz;Cd@f?DevheQb##vzJ+Kj$>;j*{MjDabfk>o6Y+PD9UQ9( zntK~s?&@yKWk^!dL95}!N7|?J$pC1(K|6MZnFMkxtRFU$>7(19yOXeEtd~NXScPzN zjRjSCk=j}3Qkg`dC%_p}I}kCecGYU8xh@oOK4>m^@X@*5 zfX11>eYM&Hyz~M7vnIOd{M-xj{1)XX4caygN+HS9Jr2V70VnohEqn>aK%?C##^;Oo zgb+Py7_aBIZXx>eVrAyDZ^8M*^mm}9p}JaO6DbclKF*>I+iK^10F6TsH95guIGP9I znsZ){Ju-84rCe&qa}NhwBiSR_ps1nXmVkaD>pj3l6j2Q6g;jODp-xm~|>!VJT``xrT(ux(FcUl@XcU8497z z=+DW7^i_<0QjshifE4`?sm%U7O&Om*c8@0#gJgrWeV~l?aG?OGb(>DLvnVe}jA9U) zvYROZkX55L(==pq!Skg#>*GmnA7*qh^;v@0%y%#L&vr*B%S&X_35`VtLJWanODX+> z-pBv2bXrV&!(!H9o5`YE59P+b_9w+elXtRV@jeVF8ZCJaxXe;bnwFAxb6fQF^L`-kXZ?&0~Xy``FbamjT16 ztTet>Z;GV0iiehhXhuDIr#S7mjt+Xq!*n3+!hX+pW9E5JxPJckSuV*zxmHJz{&r)+O(8B@9<&e z^Kow89gvC@NTJ;WoWc6R3_GfF`J=do`#EGwAiPTSkpOMaC5`&Bccy1!f4Prl>IJyO zI`8lTF06k`Pq({-oxc(-xFTqmByHms6P2a308RnWevnu)L2`jq$ha>T13ej2o36i5 zG}Q6bS?Kf%b%U!6Yos48U0ZAs1dx!39_$C8JhvvnQ6OPZDShSmt^eUqYOS{nSz)cQ zZB{X%AietBVe!GO=9u<^JCfaH43x*-rv9GIs#A0#-%<`%i$$lbeaaK7yL)WSH>yB z_V`*TdbkjR74~8!%kLG=Sn>;{@AcZtUfVt%(cyCswL6aae;l1?X{jWh!CNp^qNZ8MW@;# zd~1K6ptDTkJkXu_l)#jm=^QqPotf4env5+*o*$Nz(32-8o|Lw~TXs9Hvf&vVD5H)G z;bA@42ctA!-ceKbkQs{>r3ypgnM|ZxEj-pzfJ8&lBRrdYx9!VdZLmobojK5r8}rb+ zKt77=rx6w<`+OtmWfQVmT)=Z42o4)iVNhm-*c%UKrq$bEmE~qgx)62*OjIAA)KNW^ zK{q*z8v8SJb*Uyp3PN5_qJpt#EcrXJKqX&k>eSTRkISss8|+WH>#RWA7S(L^932|> zgN}dU{Qm|yhy&vI2i{=Ng?j^QxpMCCj{smIlPx&XF2~_Xp&-nEB%k-rcO<`3+o86c zXC-j>diMn~%>bq`zWcBSZzT7;aBh85mB9zNVSBBDd%L*conUIZG@?!i!_0UEzARW+ zLqCYzO}+bpD6^^o#lSmfk&PHz#aZ@&Z@GevzD`wJO=V+)KR02Iu($qitHD@>^(6o1 zyLmjLqMNB$M?gTFmdg%dyfwK-`LR@ttdTjb2{~R7;;RTWOAVU zeCMJ7LmtT>a_v{Lt?^Qj65zW|#{qN^m<#=`-%H{4Fe%kH+Eg4pb6=%%Zez8(bkgg8 zlNE6axj@!JEbPF8KOuEE<(-P0~-8Xs5e+OP(P zVe|nFh-Dtf?mvb?{0kvnz(8@%*B8Iq`9-;KU`6rQcP^-r%sp`?&Wk z;S{Us@nvRpde05)h|m!r^WKB#PqXYx_lQd9)W_$GM~_w;@qo%=gQOk`UAqCW%qWsXJyky&812(bxn{%)rX zvfdB@p|*ay{XN%;vr=IwVqSVhtQF{PgcWv;nuBqBruL_}v9Hl!c6^Y%bx~G0{6sRp zOz8l18r7}_1kp|m&L>7~*n2+-)mKjKDwsycvi0^0^~;Ep#98xprd8S2Q1~z`N} ztKC2ha)+BteH>ujVnVGYqnFxuyrq1wv8kKE>JSfys%mSJ1d0HW(XFG3wnUyUyqP9u zp7K_6TS>SAow-_!-=?V5kjLdsSKN@`wd$?BFLZ|UBH5JbA%1nBqvaad+*0C>n)Pbm z8N8CHOg^)R$l!aL+udE@T+sw_1%4{-p;!npv zjT39TW_$(Rk-zXK7FQah#OgHvj%OR@E3|Cc!MGt{*Dh-;JFZ&^sOo`Cml99$yD-`q zZw?mix;^2lC=c7Ia=)zoK0yqid|*!G_ZcmZMSYz54EKt;5I*xqvhgboH*K<_S!=EPsUTbyf)|(=O38Rr(7-I5|_hyyNB-r!!|D=>Yr8y zyp^WLodPER;x7scAPko@#k{hImh1HWif=$GZ*t)Uy%IjwPPI@RBWUh4_I{Zo$I6dw ze)&8)Skx=Rf@OzLAdsrw^!nXwo+QC+Exm*e2#l?(&37s4`e{s%^)kEm=1aB3lw`Ng z#4-c*PNqD&m?*rWi(*Sy!+wR2ieW5!PKz`|ERiOkhu#o6L}0;^eP z@fD&>QYrj{p)NsSkk*tw0(#~_o|oyVjd{VH%yzRL_j;m5%X$z;hxCfyL;*}~iZv3X zly8k%$AyPWH-DT3O%(SzUi!9bsDbf`=RCteC6cC}yy6y;1APV-fUq1Qp+;( z^DMO$sN={z)UQ1zfBwv%7s5Ib1&9Ett}XPMqP4$ZsE`8Sz1k-87ZqiI+|x?bOlc>U z7t`!{A2r_LMw1n-i~V`sjiq?n3^>n*i+HxLq0iUnD&o|i1Q3vR{+xaiXaW3bOdhWN z9raA+9==^Ka%N|egl@J|cqF0KXo370XvKm5446Qklz5VN-hFNVqmWZPkljxf?Pnmvx<4IXo<_Un$LL>*JRCY{vA76R2Kx$ zg+N~4bA7I8zEpGeK2`*^Vhx;tveXnUD3=kjJ<%iu$+z zi^{hb$nH_9z;;I5Xuo+Idz^kSr@8yDYA`oln1jWkJ$lupA01l1FSA8!GUqmx)|SF2 zWsQcUu_^N5X%lVPEx|vcM#LG!w_*;EQz-GQVI%HK2ExOez(g`__V>mc(3x(Mj+eKT zQV<0YmUB6w0-r91XM-#FDJj}j23U;x@AX2I6>r+>(cg)f2MK9aa654~KHW(CYg7y} zt!Pceg7gg+A}y}q~v67M)V(huk*u0S_)HAn*VYWoji zI!#N>rmvmAa~T@8#K{5p)r)?0}Lj;y#BX1~!Ls*l?m2 z_3V!0L0S{M6;(h>`#9H~?`=o11RvYk`2Nd7QX;%^IpaPABq{&~8Co*}C(WKc)Erq!UzK@oZqYKpzN*+<`J^};+0ua;xlv-_6U$yU5_-AsY*Ji z!24>|XDq@8#Iy2s)a4BYY)zwI?oo+%%{Qp~&xlqoOfjV(WNn2UCIGGp??KZTV^9Ue z&l`O%vG?mn2QbPe-P4yoe3;*>Kn83kP#wXqkzaVRd1nYeyFe6KB@0a}n9GB&H9U7O zLIg;(JR?>-=`GK*!iE-7%4-vEHJ~FLbMaI{)FoPLzY_)(Yr_jbjUPz1n^^0d$o$ zrD>N8AEX%A$|ZB}lcL>jGZeXgwX)zYVp_H_O-hQ(6%RNSWyQPalQ;4UmJRJ7WYU+l z)Dl@l|9=+(^f#}qU4Me%xHT1Bjc0iDc)rY7kPLe>;(@K^s*0J+K}b`K}_ z*hgX_vGKC8xc`(m_xH#Txr|h&GRc~JxAy+$9HH$nJfY65+;8|YPhf$#mFuN_L&U+g zp14gw#_PV%Aw+TK_mW8Wb!ysgZhMniP4+4DS0)#kI{=+{7lamkJNkG=Ke7stmx?eu zys3BX5o-!e9IT{hLZTOhiiTo-Fvl^VqL)UhYEnTnbPX?l;$sqjR2Kj;h_$eErAlV9J(T(voC$~$#C zH+;e9Ev;fxR8s%*Z74jV`rCfAI*KP1tD8M74G}3P6}rwW(md4-IRwy-M6WYx)hw<_ zce1YECd`|D0%e}}M0B0r3yb+KdQ?<~`d}otMqSx>sHZ80?kKVB$VFFmsw4%)zC|yN zQw#L~VmqucarvO5fro*r9#+CT5#qaig{CL@EG88O4P2LCw78E~z#}YQBoVdLDk#8uFb1{V@C-Wt`1LU8-K9CIfe10D&XTlq=}b16`3EaF zX~v*h3+O&&g7?A4VX{VZuibujJ5lx$Mo{!U!tbMRQ@CFAJio=wge5k;cFcR=BiV8} zW5Di$*lfaB^pt+6FWz3WdP-o-Gm*_q`R~}{*taxAm&2qR2}!{C83;8x8M5P^`A}VK zk!ZI?c^j=&HTU9@fU{L17i^c$mfoO|5q-U9NvVNtC4H-MYHM}kBQbNb!W;GqG6t&Y zV&l>@yuw&m6yT=)&*ANbDACvEW!>X$<63-0hfy2fU;)n|&?^b6hcsBr##PJFccQ;`mJ8J%qZW|bU+2f0hxxU$okKk zNnZZgH2*RSx+w4ZE3Z8WE&Q>jVZEq#jYAu+9N5Lq118ro1IR-poIV$jg*@NRtL(pK zj6vIY@d*-Yd;UgL+v*8vL%Pxu+@fLx79^@-dT1CcE>%4Pl#q=xX@Y*XsocL3p`ffj zrRe1dL1-g78Nk@;Q>oduswUxS_3Ef6C5ljuCBUrIVKBM;i4?FCBqHJ{u+ zoN-VyB?G>~%dT-emOv5SZVqI#wE&lRKz>!M=lJu3c`T-MsezL6Q?o^2csm_Wb;_!b z7X+meQ=#k>+HE)Y!D-xio(Fu?r&$qy+hwHj_8cl3Ncio0$Qq~(b%?P&QP*wK+d2V# zSrmf=wCis2VVjT}HkIPPNg@1zS;uw{Xx@HU4PE9!bAh0^nR{@BgTeWJlGl^6j5|vs zVfLgpP;dr!50$3PFRehxs(CXpWu50*axG!!;S1_BZB@x+{+Oa1V!MbJ-bKLgF>Tu! zUM*zQst)E=9mPYwWB*r;8PR+tkC;t+l-J7&1xFF=>-hbh<|-lTnpw?O)Yc#TsYm<_ zh+p$n{_VZ;BFm}cT*)xM_n;()?B9~M)W8~vG4CJsj|%@8gLi`G{GcbXK6L=KVJNgZ zh+}{Wz<(gJjBb|JS~*_k==F|K5|7pw=E=vhD`L8O8Ngk;uji3?{u~`@MPVXPSHkJ` zt>%VU-66+*qwnJ|M(c>*O#upK+|Q3_Rdj)(iY)fFkpLL0!GnZ-)UzUh=Ypz>jP%93 z9LTzo4OnjE2T4jReh9M7BpXBq!nWM01cjN!C#A_K=xe>mXL&nVj+FZm{sjGI;JJ`l zF%iwEl#XgA+zas1x*twNw>ccVNbm8SK19+u3LyTJ4NNf>LHnR^ z4sov!TC}9DPUzaSGzTkHjqgh< zLvMTsHlBQcyP%_b>fde+eL7#PRyo`=3BA2wIutMFk2Sw5D6%+ay%bflr3`B4rf@_Y zCALUnEGAX8x7N^}aV}_!c8|>BUfH#ASr3$A5ZB&4OE|xO37;7eS&&-eO}xd2BW7u3 z&<}@3%8fFZT0Qg?5&$BP^J+SKhOk z^uxyMX-|N-kEZZqP-y_}VC{Kj;`ZN87!^R2`mYDuy8h7TwRyCJre45?PC>HpnI9hx z%#ziy7VA}1>1svopC);ylNG5#?|0ll&Sgk8nI)jyw*=8t9S>is01+u#^+hIVHvN+d z?=3{pVU`6uEiPHJvea2^02xTrgXY6TGukw*vac-!$E*MbqNw>E4*cKBKt^!u3TdM; zF#;(l%44gGjF^=;!Zp!EZ!`yT1Z&8{OTTt~5uFNOn6l!=zZbV$V}FWL{N}oaLMpB$ zW20t!`bixNoT~`zO3{&EdJQ!f7xavwZwqukC=s1^S*5ktu5Lpiy=H0zc*>C*@I_|k zlC)=@Ksd2H3Rrjo`I-2lw@d0Jybl&hutEQkE-J4?`TA@)|Jwv{$UDW-{gGBSkRR`+ zM-GEcMWu08EX{3zZikSJF1oq4<6yY6>y*oU0V=TVJGbmq%_U+Kc&m&+^A;59Hn$w5 zo%%28L*tRb-n{ZPUkKpaNNrGF3^xknC_VoGEUF88gjehbK}-LR(u~=A=bYk_Y~?-O zwFr)WDf2F}-fmSW@_EiqhZ)Oy4MXqlA6nO76WYl~K^a&Zi(JvBC+Bc|to{>G3i$mw zobp8l@x-1ZL9cBjCAogL0Uo(6%P7&o=0{2R3_1qK|0ZJpPf>eIs3m{>^b$jPXgZU| zSH>bW`7Kin>!(btURjbkG53m3RnNFOO65Z0=B++&*?CnTiw6IIrfxyloCaAb{YsnU zUPmF18G#%lZy5WzjKBC=%zz(H$b5y6yA_8Jl}m0MjomLSnXj;t3Bu+bM7P04*nmzH z0VBfo=3ss+5?*OpQ_0!$dCl0*?qoFoCX{=EkYqevoGP%W&tDFAt%+k`WG-@tFR^IW z3|U4O7J-n~E;CB}KS4bG#Uegl^n=}C_y|wa>kV-J?ma!~i z0^(YD>g6k{Ghh|!SOMhmJ9KKcF{+;xyQL*Z&q(&xeCT`VE?a=n%A#C2$?lwtnn?cL z+2u4!VBkH1Ck2Yv^d0%K4_r+_L79nH@!z2cqy($|p)j($RPPgWKqWjjiTSt(L5J_7 zq}}LIkp|BJ*$haeipURRmHCEwYPqy?>G9c-ILbFy8N`=G9`t9Vi?c_7o5M2_8Bq`T z3P}~C^Kl>2q&WVSaKJO{Hy=v%m@zQ{eSXxR2;j%i8^&Z+N!d%CE3oXtM~c|qju*q! zYVr;YpRA#)N?vp%J-BN~of&qcP@BB|`Dubu_e^xNR2Xcz_rsFy;=M64V7oY!O$ZeE z5fbnUqS93zKj7SHFH`n)OP>{CMwnXY`jl3qk%W`< zolOEgdFhjf#iH4FVp2xa0r&w^z_w&^eu(cxjW=HB;NZbiIpC{1LnPe zz)KLFQla`Ji)Sd1yO~DD3%t#lQ3WT@-(GW5cNNB*S;)E|(=3e?>~2p5nXc?s2laUe ziiUNhSQcE-wc6zo!6BO?PoSs%@7QBr5~Le)iBk>h@Q!vj3mJH<2hdoM>9-5MnY;{m zb&}&=5g=~YSDJrB(w3~X4VF7Sajrwp_bTg=9>A+uP2L=?CuyloPpUB=J+%7Cj)o4T z5a?3k_3sA!%#6aNttjS(+a0w5UeyYD}IJZTzXpeoj_Ym-D~%j}*bIKKhL5$&4z z*7&E=_!JL&0vKOhk{8jR-f~Y*@?TDnkOO{;Sd2@`ynp|WR^6`pTwl&8szz_x_jfHJb+KJi};7s{%i9_ zuo@}_iPvhCMb*K-qksW(Q6~5fcm)vU2S~T=him*_-z5c*9s)Kpf-!2jM89*{Ei5?x z>ccGW6P2V#cM=AydxLZYXJQZ_YGB^%&fVi(iupNJR&6A-dN#IU8B6nF7{ZG@u9&QB zu0O49S{?m|Lz|0=8-0g8e_@xnbQHk11mz=e!Un+J1_!F~vp(?G^I;0?5SB&(|ocDn3b!=_Y8vx1l~Ds4QQG5RTaBa6T^bkVcb`3YOe=kBQamdmt(t0b;gvvo#+s{^8ew5-s;)*%eWYvW?SjEorhapP>s7nzSngZV2Ec+DBY!cA`(nsUGr?IHi;K zI^xTawfI>NKHxmOr~g;pc=tnY+!NSUnYMLvhtkt4T^6@tu6k`e@kN+!*_VawQAJs z~rx)W6utqEA&DWV`yjcyg<>U8pT~A5a&+FA8&{^%4@13N& zi|x5B|Bil-X^PS=EFdMhr2amZAh_<|{N0ZyF4L=np6^pOO2>q2*vbMlupiy`(W|dD zas$A_)7wd_hUOSdOrS=pGUt~wUf=Pe9cgK+xdXUrluUUb2s)O70WUL>arZN~T#6^x zC6;uR(N!csP~S#Q10J|tC+}v1%%XBs026Q zloo!JibjrS_|hm~>gFl0-_NajN%~23ulQ@M`e>B*WG~Q?U3f(!ClsgRg5~Dq&mz{O zKJ|X29dey7<(Zp%4A=b?s{SqDwuc}`C%ncZgbpEy-x=7LR3vXOxZkr`&d+liS z)aST;nWCD=53&l?7QhY}?SU^MV^vC3L4Q8(Qmij0`}wsD;6q+&Z};0Fhg z+4A(^JH8IOY`+H>q|oygy5yKd(OZwMPMBig_+`;i2nj$my?EPtBocQuT!RE}{)qbb zQD$mkOwsO3n{p}1)DE5W$;Rt83-Y+i#Z)~`Cr7BnB81FR@-jM-INPVi{{mv#p@TKJ=$BMW?0YD zt2F-+IQj~G8ahmW`9lpvMh=s=(OQT796W(j5RW@T*|@I#khf3cO;f?5qtmp!n9c0r zSz;gw1^o4AWdNlYmfF%??SJ;ZH`A%35QvOlU|_Uvz)AhYlJn%0qj>OjYHs%5I=Fs$ z&anHcC->pN*fe17Hf$#(V}Fhjtv(j! zc%-1p<0McPtZe;DxM|mTbh`wvLXXI0ECSs?L@8Gh%d)usU0LS)yi8}mvufUT;m>EB^=sy?R1!;Be0e7x9??=5UjH!x`oOfI}oE~>hlU5xzIQ}2V+ z2lSbGQ-LnK;6V5Q*auXOiLPqRvwJ`{qAN%hF@;oD6^u;~c@GmXwR%{{;AxV%kW*g! zU3BnLwN&=?GEE(c{F#Itj|BNyzhhtVVBT|b%-_gAhwMBw(UED1{hWjYTkp034vmj~ zGHcDNS6j2N)hQIu?40ngXp5zuK-&pT*IFnrf_WynXjvpuLq65*H6~o*P(Et-QmXdH zAOT(2sp;0ar-Cp3&wON?xdT9s2iP-HU-)o!m_MeA)1erxYVJL*5~yU5H%s*#dktkx zly=m(0BxQ&(ptmci4>HkO=D4`b{{HNWnUiLO>ux6oX<6)JAvVhG1d8uSj*Lq31IqH zlW1-r(S3G=t-Q#gVVgal$@?VkbiyOSMZk|3v5z5RURIJU=#z>%=$VFrL9qXCYMVi# zv39hO2`{885e?&gA@VPNinXZLFXo#q7!e(9yKGM&xf_aMTY(`0FL2OHsQrj zry^tx5x4;%Fp*PCUD({Jqho9Wk92EBbuzBm71Nwu7#$0uEW)j~^}3BR?>G$T^@%=} zasn7V)M=-hd%d_)P53CT4Gi zZ=MFztrOiZ-a@OggB;PHpoT3_$YVXc@|CTMd&Th(U3?dC{d**{?SB*4!jMezaumg` zwWHrX+Ca9v!_O0Fa4THh={!*^*9L^cGX9M)s6T@xOv z?=3K-b>YWV6?bDMMJhpLvBCc(9nT~oHRmV7+Lch}*_J3%^R5tmE!bv@pvq=nZxt0E ziCgRN$`e*TLSLZMJ$m1K#eNAqQG!9of(Yn@^az3GD=AqvBsnti9+8QhdA>kbUt%Wm z&WB8m=|Nqp8bHtAG>bYB4}TE(YPz{}fWyWSUjB8BjIFnX60f9r-eIV!UW}S*u=l;k z%c5DZ^1DKUrhECGNUB`(dwE4`4At-ZJHtK6!qIT;UW42^Ren1z1LHVg>WFAvgc6h43T19Iq>H0=u11l&6u&mo>yA12}CA*fZM;_*mftNMf%~Cy^+q0S?po2 zJJWy;h07qr^)IPQHd@;|U%G*JvubVc6ruZNZq57|86m8eU+d1XN*RreN} z3fZg}4nKi8Q<02=qw#A9D~Ne-_TVM1yoSw6#K$#q#D)@(fVsC)62;R%P}AggCR_l$V?P z{4FD((QvwtIdSyD&wMZ(GMxgct!8q81Qo~F1IQM`SahZV3Zc`Oe-CsFlp;x{?0}D? zf6yhHb0SR^huSB_XJHBByn}lq1zfb^y~3CEfhIEvrj_D>jUMgw+$O}l*%IdlEyxIV z4b}rQp3)R6Pq+6sIl@{BeX<|^L78@Tm>yk5LoAI7C;_4zq>)9aL&f=R95VHaVLc|*)&^(oMY^wMv$x)8bEqrG;9*bvSAOT-NAwhMb zL9A~R01)~d<|k2riSEA79zMaX_BA#YWTRIO=!rbdNBfgmd?%u57qjg=`QCMX-8_-7 zqHZ+{&W3Krse9(^5##7zTD!SFSNZv6Y;XK3p`&wa`h83xpZ6%(_i(Z&8`qc=;s~_Z zMl!hQKMj@15$3oPZ*Qys@Dd02d~_v0Uwyc*1b-1GW~`{h>jHg39;)|0;2wfIL}5CU zhw!$vcA^rtL*cs{55vU?ZfqocX=tg!fX-jDlO7I!a@vJ)5}=eFWuoM8ncqwmz6EH9 zI^t~i2f13=M8K5w!U9muhb=>w*hhX*=>j)un3Qj|!6nu#n? zwt10qc6fBx3QE$2HTd)9iL1r-czw*LQu6E;&^U#>*g53}RfbPl95(R4t;2K>RJ-Rr zP7JFgTSlNErHCeLXaj{8Qw^?`gyEH+H#mGi4!1%tV-xWYZSJ+kc&+2AZ`22A#;P#r zk0m-hDX?MB1=C3UWb!__;J<6NQDW2mf9uFfes?@JPDeZ+wO;1ac0V0;GgLKLdmYaO zb^q9RYXyP~(6h=8%)`nK*a!dgs^$?jv`3Gwd}@T z%CC^G=9oqH^Zi=72KrXOX(koh#W?#2adlv*wNTw zBv67M?w^>NpR9+y7V$`>v8{V@rbxZaw-+h9kLSpc+|u6`4~fek7X6W0ursEKwBOns zSo#|^LL7t6WwqF(Z;8m0NrW`GZ!EhQj_Qi*IOpW$eQ57iT$oLugTmV7ae&5<-sST= zU1udg%sZDDH~Pc8B$5yaA$%Zq{=Flter4=;>j`Dxrrj%ExX#B?xoRFTi`VWw-c-)u zkg*}bWx9Vsi$q^-4ti^xuHG-B%gu^34brAfua=Cy(KgaZH|^L>V!zXCU&9|CY3^(J zQOp!Zuf?OSM+J57&A`KhfF%t#L+`;g=VdvpA~^{#(lj+Yd@*!;x8@&++4ZzMba-Yi z_+AXrle^D?Te1E=Pigl*+#?T@=eVmk!vokPJ(7I}^v-s&j&s_P-B7~)EO2iF>>GMp zq|Dk!uDk!hW1KajSv~6FZ?#p`W7s}m5rc&?BN>~o=(H!%k;n;5C*mnrHMclih6IyI zNiC-{fNK#Iy_w+*-Z55qlb|PYnqeTThRI_}9uXurpeAwkIU3kgxwE2VEUja|%BX80 z)T_-ZqJ|=R?T4p#|JaQ2o&J~IS_UT(L?8Ah5Hs`Lg$Gd_W)0(6{w1b9d)gEMxVhsP zn`eHpvg|Ya)Q|%x;=e5#7_4YJ3|6%Zeb21cu{&B8;S?zde+?-XXNyaWPY`ijAiFjK z&b2M`4}!cOwNkXx(v-HSsd^e6cyD&$Bs!Epls(PG-#al+kR;lPw{?`?cM`LF8UgMn z0FW^sz}6R~C8@R<{4zZ9nWCuZttw)7`5Z3)j-u>@EOe$RLC0^e9}>~n6LJ+EmY10x zp0_P>h45(|fO8qf#sm8Dt$qvs?UG6DYkbr%xoJjz@h&KwCp~}2(526QbUEFhIf4FD)AI^6lc}c_n5xlm6uq=p*9#??<5WhK*5#C#l6ms z{%ABeVfj~D54wPFK^h7|$7Kpcl5N|(hq(A{yz<_YD|v0Fv+Mh&H%!g=J}f~{&pRDL z^f3qfPRBo4wb^)-{uu4^K3r-j#artby=w=y49iS7tWDYCbcJ8Ht2CLdI3LabAhRIm( z)DVYsG(L7v!sFT|Az^K!C>KH2$_khewn3DIP&kXfTW!j?+TwvZ6!lls9{VK1x~_gc zR#}npOl>Yo@i9nnyfL3Uzcy?EEeXL|;IVK5M1=>_$JJD3e?O~C{l_ak;Ls^f#Guzc zDM+~}9Z;tfJ+0P?&p8&xJOOwUH|Iv^?<+qYA_rs9aj167ldpLTtKP*jMRcI!mv?WL zP+EVRI+_uzi}tm}%Ob7cF4gPJ7?4wYJzGPm(4lZS-D8*j8@^aBcK)9U#b|}MTl=d5 zi=G63*yc@9!0+AA0!N~)Tb)n3BwqB3V(1(0C><^9ZoRMri;DHB)8i<{{xA!j#Adpq z@Xgy%`KPuUM@upF>2840bzS&ozkrV0yo~9#rAJ#Ye`bjF)enKI%9LAOW%JRW2PGmY&CuObr5{JWwJ) z0v7&{mLQlpX>~@`E4B6?FiXpm zA$hOcRv zz)lF_RpflFM{zhxT-a2CN)HAyg^}3Ce`Xt%4A;5U*ObBW=X>3vRT1{Mj3=|G=27ve z{3pSqF!3r=_F5-$pW29ui4-*SYQ`}Zj*og7H+S}b+aeY!L+&G-D5JbjG%!q=WU`6eS9ByMby%zb>yQB!e5w_{m2ZCgD;m~J` z8nZKNg~#yh1wjA3#FAKPUKd_Hz{u>&3e~uNEAY3=a3}*MdP7R zlY}E3C(U4uW=w4tl~{W_Q(9j%^*qDqF&4S%y;z`<=EXtVJdxBLYQ5ypO+rc6JPz~@40ov(=LR4$jL9FUr>O2q5?3EJh#Cfi+#oo}yZA^~5#&>L z4bSw&;@_s&XGpP%XJ%8mHqS9R+$}Nis`sy3O(`Xku8uHt=jxID9;*SB#433}Mf4lV z0mste(mex2L*1KS>B){@mt-?I7m=*%tQJy9b+h8v)WU}KXL2`7=+cn>^7N$(QcUSY zhtS?HJ-GO|kK?pVG|#zU8@(KMO`aXr7C!4uw`$kMq%zB^Wg}sW#1qH9_&dD*I*CSQ z6UgT%e=hhE{MJ_42QaOix^a>AwRjsB4*0dQla`(xpk3C8XJSYHP7DV&T@Hm8a5MuQ z_sAbRv4iQTF^r=~Ni>kt#M`o8zu+Qd#F zcv-h3k1Wjk2Kw;&};EHa^FHA9ZJ^)g*QSBKorqO{z)ZTjDT4Z-|!Bp*0d(62-2sN z9P)!d1VGodQ`pk+$fr`fIKR)>^oCELb%@Ag!T?x5;5F9^`{8H>kxpAeRc&CrCH8tr z*;2zz*gKCY+)=mg=Df0u;;J=#KgZ0&|}MT z$NQ(oeu`}$#-SI4svT+00AktgG+&dhW2Yi&KQUw;8G6`=|KTv_^PfO2*{W(WYShhz zUpcl2h0JUuksrgBYpdM)u6O<8eZfAA+rP7>S6u7-fjN`dHDaT)xKXykgx$$|El?wD zC&CwnTW{UvPa5RpY|+bK0_Tzwz9&DFk{ZeAD*G9bENMi`;$iy^^|iZq0Uws8u0}oK z$aXh3-^>aofWP{WQcA*J-_89y-_;jeM+BS z1P~TA`fu#cL>KKqHs`3aT;H>7d^n#57=>#?@_a=CUOHDY{5(c;MOTm~ml8lnS9B{OZvxKKva zynK7Ar=f&7$>7KvGQ_p2{@_F4S|SSE9pn?s-wu}b{2%N{1xeQDx4uPL!&$tr-V)#*_hDj+c^aEGQ6_(0(g&*aZ#Ig7 zx;un0#o<6mDGc9+^}s|}S}+Wp(Xv<@B+jIO>`^~R(jUu|AlH#dhZnz!hfStre5-6A z5@@??J;v-pDRRFy<A*WAVdsS@!=0wDe&XnTmNj_#S%V|)4?rB_gK;Bk?=i?mz?wO*E zitPu8ph;MXV1pkF(Y+pUlO+l_TFpUKe^mjW@vl`}f#}Q8luhf7b6J}YzoVy2W+zXR zaG-%_?tWfYq8?fj_fF0*51Jc!U8`{cXwa}-Y}fpRS^#n|5M%^zi2SiWM!@LdWjnrM zf;&}c2flL5FqNseVZ%*1KTT+vcEVR=^mvGr^N`Q}jJMCxWWXk9b3Dk;SlDY$buRg{ zMV2YH-P}ai5bjFAjN8j=YBjMa-!CXxPNkCX}A9Ptqk>kYYitzsVuN}B{FEBBHZX|h^ z^8ki!kmyo?-sEh#R4E%R4up;c_L8L|9wkK$?o-PVDf-3ESs(ePkwL%yMPT=qUIj^T z1vBGTzvX&%p3tUD0Q^{?hxDA4I-NqfO^?>3Ym*w-G4*9eFPD<5dn^(_|GMUKNb6g! zMMxEP1;PZPgC+ryPG9dmkj)0{O{RbE`MTU}iDH5Aq!;=Vd0k``t5tL?)9q_pN_6V3 z(%7C0;5Q5t3X%&GG374|edOF#V2W>0!jbUAouN-{;@N zPLt`Uemy2YzR$by`xgY<)snSy>Lz_c*+hVI1+7+2UW3GI;kqZ{hGNk~@V^l)mV1KR zb=k^w!P?(<=+W05sm-Y8P9MJ&Fz$W&wb^yk#L9yIp;x9oonkc+g<2)U@p3bmK24T@ ztQEedV0-Wvoy&Fl13#jAQid(BMs2{raL;B?8G&{q9iH>F$w0YWQAHc}aERC3^b0X? z^MRe7v9=-j4~kFRQ&M`F(fb+#uHOc~>Miq>K~Dp~U4646m&bpVJR2=n%308)KaJ*$ z9hOsCeQav2xoCs!{fS9(Y?_xPNl?%H-Wuar3?4Pfzjn?g_u4hmE`6A8r;#Avu z!d3@Y!;sF_=uJ-)a{u`v+BY(D9`+sV0;Pehu^H zQ@acNnztNnF5Ehw0`zAY-#RVlmzdSKuwuG@ zEc`vAP{?8yvJrvdbE7|c)6j!IXV}Wd*yzgK&yfQ%EVn?WYeGxNnok4U7J>~Rsy8K zhP1NdLIWzom)ODw<0L;ILBI%BmQlQ6D2F!dcea?h>P(+B0Hsd|n_|Li+7H|QgA78J z6Aw-^W8u3Wa6$?|Yog?dwb9iI`5rn$^oo^?a7ov7|9Q21UXXaLYpBKw6x@+pz-9JM z?K0eHZ`5$NRF_k%7U+6S?J_n2>f#4xlY7g;uN7-aJoaap!q~#`31YcMloZQ;{&_hy zC-25?DxM>x<9!o+hbvfj+&ZU22jicqk~*k4po%y*q`uhF*~>Ua4@7ek@S!X0yBdz^ z(PagaR?Mjw!{1>%cCGpEYg_l8)6tCO68^*K3nnVBTB;m9zMZam=h81~Ec?1UDN4)6r?TP; z6)!m~_=0_h^)Z!p^I5r!?!i%f(*h)Fd%mZO=*AKmAV&xSeI38vaNZcT|9;@!`41Ii zBVfazOqCG?71WnP2AIh-8#EiI2iE>_KHOtbxz-3j^{Z;-;9I@GC$&5ttyvZ{QCyOX zT2ps7^&^4{0Z2VxPQ-u!c_8zY`jx0+mQNPu@j?4V>04(O(vJXv$Q=3d1- zsSx&|JKdUVsK2d9EmpwKpZT^vN7v>UX{KFiEzsn_x$9Giko+COPH<9&@|St5Ph<3p z+gMRiMIG@%vDg*@p+K#3axf)yvnoi|GjEhV z^qmH`w+MMXYig6<16+A6YYMO!bu&Z2p`zBO=j^YTS07v7f~AE)yWYk+^TRk8JC3&< zSK9|s&;DIHCD6_kL0>6wp3MB5WCCH)Kf&Z39h|(gXz7iUFUGXEj=w*YQ+rh++O$;n z-&!V?9^USNmJOZc8?i(U>opJ9j_e9z=0_@bTBbxFUMx1p%W+D6iqpC2h4Y}jr$}x? z!|JxU_e}B#nbXU+?#ke_U7RcZd56o)PtK_AU%0q)Zg@&{(CK!IO679 zcNAoh50sLJ{%}L;$E%MU%~9@<8kD}zNfcf(07^(ez>GWc7bqX=Fx3bket@}C zQ?fWYt+!Ur3$u)-Qyfoid=TOE8g74PU;K86FQ{SE4Kcs@R&lj7iBQWy zP;fxbR086=m6|DzGvFLx3Uo`x&#LL_;PfFM9k}?12Z5)99BT2h8olfZ21_CZAm-T$ zWtgDkY46!=AO};ysBlScOmIE=p$}Mr2KM1qcbJ!iULT{)MQ_4k8nJ{8J9~LPPpR4s z>M6c@$OpPfNEs9j?_G zWI|Ydbw4NEybCCQ-s@F64;o{JNsIbx-pt1*QA@Wf{Lf%%?E2^(Y1O`7kF*sWGG~KL z|D%C!p<_3_9?S_*a7v!UeOVQBXBOoEZ#!qA{?-WLE@`D?`u5h6To^>Kp!fCUn82^> z_$Z4!%f1dKd6GViU%EvtNZS$bZgyoWowM*SDtYBeS6Xs-w>*U@!-o_(+!j z;8^Sn^BiW`9&CdNmvbT#?OpK5%1b_er~jO=d7!)z>=wMO9;~N&pH}&9k7Gl(?(gA1 zcZbCMFx=y&CyN6?+YTSk|Z54QuSv*Q}yB);Qs)a7p*AHG{iH~lq+)aQ8prZ}$K z9D9k^b|kPxTs4Bs-fqU>hRit-|9&T~+Bd|~)U-h~U&4347H(e0nd4i>`D26?lh_7< zvKjkfO2$EY)u`p<*E3e|I?}ku<8$pe+~cDNY#aRP*4=iOcFjp}`^on;O!6GeQLXSi zivx~>hDKrd)%rPopXu={kH!>fGfI3#Ows@wr9y8Tnu8YGdIV30IA(C~B1z?X zBy-NWiKt$r{kY&4ET$#kk}NcEf)8cqfruc+Y{=U29C4at5YiRcxbVuu1lHeQVB#ei zt9B;4p6aIef8|~GKh^L1cW|s@X792kE6SdknMJZwWN#;1&M}g86vfGwLWzTO>~Ij? z$~t79!$I~sWsms2`urQ;^NSzOaX+s6zOV7T#(iCm!K&loK&Ew^`Ox~YiHhH0CR^>= zK0Dsi-^=H&4eC~LDd|E8-`W%8)8Tp3jZvzD;0gM>m6J(-94wMw_(yTE#0r0c$4 zR8Za$2*u|0EHMNPPa2M5OpoA^r+;IMuc{l6u%BOw@f2i0o8Ks&=Q6~(HB;mMX3f(W z>sr<|{Pd(YAMCU?nR3FlkTfZIf1t7jYFWu$NQO}&B)!{JGnMReo$OrOB;7C1GQ%+q_f@YsR z=lh!26QY%;!rS2zimPY@K!q}TP4j!aCv{^i$k#**zid=KE4~Sz7Tek!i`g81Z#jGq z&1t+cv3F(Q&PcENkw1IG0gZHr^@<{O&eXkaw-j$fl%x1hPpoN`lhE@OFmun2o z+tjt4k(aX##n*#@xk}27Z$L#4eoRh`CG>xBHrM857`(k;;tDq$>N8c`kNezzvp>b< zf`zEz`TSnn*lLjn$B0rdJEEf9RRq_3I@>=VIt28N9CEKMiV^iVeyk+E+WvHZSrt5^i=M>_!V=DK1}p&iUrY3>f_K6KRG*OC!N4`{Xv&l7iH2hc-Z<*2X)W5v^hxg z<=kfBx0_Q+Y2f{I&QdFj`K0Q~OOZeT3NpaPq?OhAr<~z=*Ad>7kgAb-(0%4M`Dg1V zPK5f3?4-`Rz~NUl=+7tz&bIWoLx`>Iuzfa6~F-GIA#SOt&o?|m;ZcN$OYWuXU_HMp0RCR+Eb8Axx^uXwD-}|u^k5%%q zL8QimK1*ZIK6q%($9~norG6FSFz$k5IP?^+RQbiidAV~5 zdsO_6l!Ku*bwCech$PJFT3Y+7x&KrJCiMf&4Oa-ktS!#+JR?Wr#0Rqpoxz!expmgr zU!&BYI|UXB{lK9%{Bx@n3-?AuUrdEvpvBe{Bjw|)&|QXzh#f6X1;Wpyid%8L*D#ca zOfH>YOMMgO_&H$nhFL3fw9ybb8k2NqT^IyXINeZ#dN_5TE*#Zkdb@7Gv!&cIQ@b!r znQ^T`{Yulv`Jle5Y!DNWu*Kv%JL8D)IU#)8gS^)KqJx%+!mN^HYBxLD>GX3VSh2b4 zmrI$nx(d(nXoXA=8zFc1Hx1C?7xkWh)HKOXdsoJycyl8_XR~X*P~erDs(%T8`16~A zRw#}SlAO>Mf8mKx@Sx)(zPGDJv*LE+f4c@_ZZxzG;(p!n_pHkg?0dygqN1?m)pJct zN8=p}o$;t6MrU%I70$UZMXwI+3<+jye3D#Nx0G(6Q!r$bTFw?0f2J|ukulZu;slEqJ7Q2R_+E+qel@xgd!QRuH zQ43!e9sZqs8&XA|lj?NM>3%B3E1SGlogzc(H;^uC;lM!C#`lBubdmv z@2v>%{tnv+T}Z$kg~fRgzCggVd|}g1`6fFupc_#)@`#xy=<1gxA;+uhg>TeNe?69( z`QwwS;fwN?o4@b;xw9av)7hVPy#a+CaxM|S9_TCNUbhgEbtC6)e2dJps-;WiHPfUJ z65fsY>7HMZeHt_}CVlrLYt06eK{jaKA?tn%vPSR|@N*%7iRCaQ5WB6-SFo}YFS3H# z|Fi1hctWUaOkEQtKliUd%l4+*?d4*46^VTgzczKB(R*L0Uu3#9vu61jtp0scZ76U< zunx6)L4hKkiw>BT?oMFV zG&T$**cTTeW~)71XtkDmdPJ5XqxA|QH!E=WbxkFYyk)5DEaE{qky2du+V|ZgAx71d z*059=vzOpKd~%k%iV~9^zO738qlkTa)tGpwaP|0Rn1=Zo>e0&T=U1_L%> z&)ya@Gn>ofRrs#n535I8`_FQvawem~=EiZKP3P0yzsUyt!b}mnXniFiYS$6LHxHU7 za^{km^?4gL+)Jga(b)@c9r)BLBjX*0f9Z^AMBltVKQ12K)9?~rx8|erH>OWurgp;N zk)#=EOBNF5pFTCa%b}+HedAV{7)cAZ3)ZB-sK)rMZ2a2iX!oKoO}^eIb3_3mWY(cK zxFj}nR0<+P5Ix$3-P6xpykt*yJ}-?s@KY>Dn|J4$oP78*lbu3J*=CvbsXLAoh=86w zJ)J)6ug`{b6>9cr%nErwwc{In1Y|8_T?%kFe`GG!p$2}aBf(Hid;JY-;XbHUR8_g% zp9qE(`If)#0jR*U;_LyxvvbkYcjFwqTi-0DXpj6;mF1UJv`XJDJNt8A_ZfAP-Tn~i zCOVq*j_{X-LPIt3NVbC?O|}m`wI8TQ!`h8M%sQXm?b6P0E#pS|Q}Ss3x|yfJIAZnl zW_485EgWju@2)r6sL@>oTGhlx8|I7q9$a3IVel!8i<}{f7LRQLfri$s(2m;S-8-$# zZ@~LzLWJ!5MkxkwDs=MV31crWy&rDf0Iidnf84al>a55R&uQEM)B&;KcPk7 z^4W-#{sO6j&>d-A3!U->ah^g0hs*fQ>G>IBFNQ7Yrwa(3#}zj)-J@m%UuT5dhwC-v zk9b@8_>Tq@$z>|XnX)7gugckS93H8K9;v0UeEVHzaJSzz@>PD>S)M+}$li5HMynL4 z^^TrQ#9fQ>H9E!yn*?v1yz}HKX&d`Q%-80dvCSnyV4(qI7;9`O?snkrH&IZ`6ywJ< zD}@*hU0Bl_nEFc9^4?8+4y>qETu!Dm&UZ!)ESNR<@cA!&Z9Si%>B(yyz3#A{It(aLvETTmj$1=H@<$L=vu+%@~8+1xJVeNlB4f6 zN2tu)eAwiZYAH!+Zu&w5UOnc~&;Ye|mc{~H+pYubpY$Hp{dPH-M%66fw|XqFr>XJh zk7I875v-U)Z4$k43Ujb#_Yuis8M@5%!Ky~e#sjrb>w3c|-%h+^Vnfms%0_zqeYV8X zCHaHfZ(46uoRJ05_@WH91k(m)-_(STDDk*!VO4bMCU3E`vcGKR>l|`6tm5K&1ZxgmEhFa0GWnvE{nt6YKYrBqKe`=K zH9Gyt??DNdJ|Axew-XJUgD%cW| zsnRCf#HRg71Q7;&ln)~2ukQ481^!DB=0&G=28n%E7-7+ypGT|eQ{O3A7YeJ3SECXN zJumRscfFqN^tNvP(r0ElTlKVTovJ5E`bikI7M=k6x z5Xd&R{j}h@f~otz#Y73K&dgKOQa@AV?laxMWKUe1JR9DS#a@8=EbV;T@V;D3M$Cr? zo55qRYmw77wnu4yl%+}5&+rYRPfVVEQgGz_Rh&y-3-hlwCKJ()HLl=DsEu@a&+RFC zYYcVtJZEm8;gCk@h_*hiT5zTU?~9r0MtrtR5kjO#^>V12S8GkZDE3*75q-Q1TgryN z)P1vmt8uuwnTlg%@Y!!2L(bO7#P;`c_Dln}DGGgtUsxC}w0h5+V)#Tm`L+x^ZaZpI z?2bICBl`-_6qzX4!^Ci?waSv*)tk?saos?$4#)wvZz2%%# zYfy|ckF0*QU}iCbbz+-xU=2O+{^KxPCSb)Bb8aJ;{cJoY^AcC2 zXf>@ylrYfE$H+Gr`Bx`_p=kfb51)Qie;#=l2Z6{DXi~XbWS^n#HvY1P)S$$+)?W8q zmYbpT{Beh;*oak2J<%%&vv8guZTyeEMa(*`Fn4J}r_UvWITPV^$fC5_3Gneld2N{e zJwSTZjdOjzew&GGc~Fj`JUioyH~y0+PY^5655^8su)K|1`cE(K-3yz0j++Z(;?o6x zHM*+e5qaK-`!gZfvcdt?I+*{2Q_BihvKZ_5-N1j|wqqONM*6Hn6f`3uz}S}`2h|Y7 zu>C)qZzW^ZQN#R7N1u$0y6@Nuo_qn4br zMMG14_Y+G_m#7C*lj8mMi=&&p&`KcUqb>ELE!glipaQzl0vSLVn@h!wfAUX24aUzH zr;Z)q=e$h42^6QDN=(qx+}m#_|1MaUTP%ov99w63|6t{AS7O94)G7-WdY~Hm0Bo%K zaXNj-&6wu2S=tbYOr|8D$7*-ZD^&csp+7V4MdZJJD$<(dk&`}x9R^8If`E5RVx$DhmlG~0nxKk@5i!@Sl-jn;aiK9UL+sw+J0m+nJWZN!AWelDuh57*QA`kJMDBIp-nmVL3)#M@q&S@NxaN%%D(<;)`KYM&!zg4@u$~c=vHLOJ1F@!_fPURT|pXxx!5S!J>n{?b&MiW#AR5q zL?G%kwWfTdLIv{ z1WdCQHvE(oIFVkR)dG)es8@2~q4f8DuA9j9I(~vic|W2xAEMe(;|BVVzVr5CmNhid z%0W_HD3P4^ogW8(15QtxES5^0{G6GTr7f+2)U2|&O^%iZij<=&8E4=pp*1lJy>5CI zqraBN#5InXqK1Yx!dfw*M~xn^%NJrDgJGxm!BaG>@DWHEbbgb>1-u8&bNRF#{N{~A zTN7Cp!*F}9tItjQ-LmT;y+{)k=%bVMX{@+;IPeJWn{&sQkFQA;MF;IyCgu3$&XsKN z{&^)uk#_tk6Zs_zmnl<=8)l9a=r*HZf5m@0L|M=ivmF&+s>Gs*oOC_L+YNILMXuQQ zQ=D#yAi2W12%tT$V%++kl2Z1vj-P-q76mj>y~zLgxhA!K9*pz`Gp0qjf3>`!y!{)$ zuAt`vFaxX$#s{Jn=sbGz*6})GLHCW3Vw!-qlffj<~ zO?#Q8AR*!j?XZhoQ=4p8viR||TlD_p|Ifo+_iw`CzUykl!4dIW-5TU2%W~+c{@gpvI>f{Q7<|wz! zndn+_o_%HsZviVks84kerBht0sZ01EzoN>P>7qILLfnx2sAw<$9fLK*(%Femj4b0l z_g0a1V`Z+{0C|fsKX@*Aj_Wy{-{E~zCJz4Ne<3=gKW%GNLIFFemgB?kh0Gx{fV;1f zKP|6+$YcQq!XV-Pc&h-Pew)V+IW3jswhCs}(Obwt+ijYy=6C>Ut5atkxP3EXW zdQ-00!)wa|4U0;xX^zRH1%2t}kWw}3+MET50dZc^H~rx|s~WW8g zQ?)HXx!YKr*YSYYa6k8;Me{(#IalrgkP?NKqq?DjkhPVMfYNawY7(_TM<1w#K%AY? zQh{F?tfZUj#eND&G-;z5oD9l zkH3<0R{>UAHU-6|iOqjy4_ByR&u(ctAzM1YLWOI}uWwbVT>q#oHPN=&FgwV_Fv7?% z1=+@qWs$J&u%GM-aMxRJ87?Q`;w%Np#nfUL%3AFJaI_)UQojxHbUN;!e&h1#?gKUK z?`bTsbO(Uj>|VB&FGyG94VsO7{QO_%v`V-qS0T?4X2w|f?f85~5JqYy3bqQ|f*3CV z0V{EOKa4ct{y|YvHBuT}$rrZ>apmIbOKn{jpG#3(o{==|W90z@y{Y+PO@s9dCaVj- zQw#Ud@F$?Vm9y+hxR2FG#Ru1N3p8W1_yKcV&qZ}1MN;xSnc8)+i<)@9rg*--j-Apa zW&>#cy0S6ds0-N3^g>0^g__tS8GihAwTE^)#YVFFq=>$Bc4Q8c4_KPKt$(nsPk7Dx z+!gBpdq|e)PRbTS26U!o!6AEHZFdmu652GFFIUt1YdxoJFciY@K3OVvhZg-Rk7xCb zV9dp7D}4B|sKekb0BlrGasfStJ#h60yOb|RMQGbd?VVBAM%Q?X}oEi##Z^3(tv{pK<=DO9nhgWW9G0UzLi zDCVX{41c4Sr9n+Eu1RT2$4x6UKOQ5A&C-#Jiqj8M7xL`!HB~eVn-}L=!yRhbw`E7@ z56e|!cEkjM(?3v51x}ufVPoFnKBs2!^jA%+qXOxh(ZG)LLW5>WhlJv+s(r?LpUdv_ zbxNJdZ=Cj|fpFr&<6%#yO7UzxLC=T3;sx}|C$-Y3LR}{k0S`tvpX@@oMdsL?mU^qA0|(HRbYVvjhaZT<>^^D-2PJ|O zS$$j$GlYpgiZLy`ck}d}bo0j|yA`0t$A~Ipx_MDYzc?TT2E5?sIUjG<%>(&Y10(V% zSV)N6IBBa&WrrK8jM}!ViqBiWZC>mMTT&p6oFEm@EsoZ&esH`zi5(G=7cS5Y%L)K^ z%pih1oYx+?^3Zmo$4pP_CBzR%y>nM}Ys9leUAGq+L;BxitLW_w$2P}IuxNT508GCx_l4_ zAGhh-5g=(^$d9ZLx366U-Y<2X~r?^Upv_L z%!n_qb@5lllDDj5yfCS=jivPq4{w!9=m$RezBjE<$colgph^6%Y<}>R)wm1?mYGOA z8}1ah=rwInU#|BNF(vPyj;63rY8waOMqZ9tbDsZiec~fBEyi=QK((51h_wF5A)GqN z6-diR_Y~Kl#fc;L-pEhtXSaZ5Fbj#FuvVpo$yC;pGOkm45DB0gqR4F_C8vM%h-G1A z--`mR_>cXIwKQy*CD@4HFsqAS1A#m+;(1927s;8THGO7qJh;CC4`{V#H2XCo`cz6l+qtW7LcY%Ap}z)Xd`4SmmIs zz2A=)N)N?~KiU=0WDQ~=tfYY^k1~dF-MY=iQO`MDg~@pa^(g==xQjy8${eJNpDi#I zCmYOnr?imt;gAscbhbwTiZtWbrTyV7j@RZ*@7IK$YESw6!uWV$xfW(miuzyGO+rX5 zpzs?y`|+8+f>S?0SLkqw174HiT#=Oi$}~O&F~J)|T(fq;$b1b>U7Fz8f18l#j!ljE zZ!i;fD3YPqR6~q-OouR~TA6_de-J)ox7uR${CjXz{4_0n-98khU^hZ}!4u9Q&41>K zeLfQG=*8LCZ$QMpT;1n8Cu}36MN8IP+Sz3ul6~{NvQFV5eWlEyZ~?qPG;;a;si?&J z@dIIYm?3OlS1W3QeGsYvSraocC+~n~k496Iq_uBJ@83%@ISY^HA{a0&~iT;(7iP6K|^tC)GZ*)v}H2ffCD(V|2=JLO4hzRxjYHW7|- z9lu5tq__k%QD@KC0kE40K%r^7a3IgtkSl-;085#oX+Lx=SE?gK}oO;l<; zE073C@c2?a{vxF^OK5iO^f;E{g3lyULB$0`_|?yi8O4`+(oP3ZT`yKTdmpci{k@JQ z<*zA)bPvmVCY6RBTA^bTV!YoP`=DEFo5QORNjP1*uGerPMDPoLD zGm+{*5Ol#%qolzlT2;3ZLx^!2s| zv#9a?AXwi}6k=Gp-8(686=wNbTcZ~!rg}y8R9sP=FON=Li{18R&hsLvZ)>|3O0Y8= zH=k=TAVbsi?r^4JyMarNW1V8A>?@z*;vsv59V*~Hs>BX-cP;9()n4a|O{Z(cf1#;h zE@xQj7<>xKMSJMpLJ7_I^grY8>l?9ZvZ*I8`$|`vqy6Y zh^eqL>H^Q?k>p4sppS*Kx_A#gqb8UT6EI7azVJMbK4NX0$+fkLK05 zn_bXiUVjgxh=qeg(6rMu1YdV)DDPMv{F3(=g)Q87;j!G<#=;?i(brcTj#NUAys=Cm zhesVc`9R7E*FfrOD&Nr|_ZeSc!s+O3mjkJX3v} za3+D|lL0%V7p;)70vBXsQ>fTy5mZ6lS3%lj@Wak?;B zC;EJ3%E^Wk3u<15{w?`-v2ZAFRR_ihn$pHi9N^1G0ukq!fJwPzoAW3p6104nfb@3* z5s*2Dv_umulV~gfq)Hb?PN9$V#+IA+@a2U@6J+`dC@iHZbAe)?r-?9g2!}9@vWy~e z-_gbQ+6{kh#}Wp0s&fI=kkPgMTU=vRH;Q@p{=C2)%yfW(Hm(AhxE5+}QO}6*=lBr+ ziM_B;<@VrmR}0zj0ES2RuX$n-lLXw+Ce`6<*`IL5tq5@tT~V;Q1m2E@5%`K-=fx zA~V5J{?;hgefo^Glz(rIDf)`-KLWGB93$z?s={lkJDfnvlK{%oF_^U!oixe`ulfAv z-uLaUhr4V$T+B~UQ8P+bk9hdN#@$5%YNTtDYAN;6fa~Z&`7rk!D zV5n=gv$jvdC7Zp$p*Rdh&EWD{I{?HJWR$r=9vj=ZbZZvKf_1q$8E$6oVRzv6I<}<1 zTA6$#Zv6mOT~Z$4_CEbk;!+w)C9<=B!kcyLABCZ4z;W#Zs$R5)>h6YUyl!ykucX$D z5L)T!$7)S20jR2En(^nXPqy5kqK=?<3d=ql-;$ZK!shZG3*8%iC$8CuDq`e!#9*awk7p%DRja4UHtKK4qu z+RXk(!AxSd2)rOSkxB439}na_%R%_XUHC+b_3jrVlnEWnuvtWzePMRTR&bXJ)Z&DC zgi_gcKo#(c2GW0vkZho{PI^LmjVfOjzwm*|%E9lf>nxHi9Q zpI%H_F>inn16{RV7HZRB9gFlD_MZ)n)nN)-;lf4x18*5RvmsK^B ziwgZZ*w4MN8EP2)SDvQ-u>nUZ!FiSAag!wAq1gu&*Bl1AP)SdpUXmNCkuG@9 zUVx)lrXT=*PDyCJ5XQENP&nxv1uLmXuUHR+EENXKZ60qp&4jcqEBUji2HRhCf6uVG zqJfrn5`QF&?CY=p3OV*sjKy-H;Q$AXsQ^}qS~JN%=uD>=sB-+lc$eIxj6zU#E5hCJ z_|QSM^7;_=i<1# zA&<#y>vdX%bxB__&?Mjih!w*eF z`uFs836m6sGPQx?LF0DLK{`P*CQ8NsviSj*P*Cg2-rSu+S1S{ZUerUQ%vrkES6?qp zsq)GC<=ob-3$TVVKtRO1l-j z7Cfk#kx#W!$)fwm(vmr!btR58@W!LM`R8g(qAKYcu?W;b;kdQW>z;NG5dC#cKSkuF z6_FoXyRU8k^W(4L^@ZV#p0B&_katSq4V>5Yn-|xQUP1MxI4A{a#Wz&1GwBElOjI0( zk`Z1Ux)UY8Xs5|L^#CVCkTT0Xdrs``?~qN&WI6lYkKGmU-g{kIh(^N;<1Cv76wm(z z{~j0813w<^4zVhH=icNPHHO9pynnW?MRNmsnl9h_#oail7ut~oi}%$2YfOB5<7~%< zZsd^kiB&#HJTU;z`}N578zJLe7{%H+FN_~##POTyjyYw_&VOs@B< zB4n-Ct(%-=xOQ<6n~0bRgHvt9jeR)+X00lW!B>0v=Uaf{9+;)%nzf?{&-opZ`~a+x z#t0*Pab^!{2%iUEAlV;mr^yolm?S^_M<`eEh=#O;og^EF?h_te+3*V|eOaBdCJJsL zjt^(~?ul6ckmH94KSTOa3E`>(q)gwJ{sxrxaW68h2Ig;i2uM4521twYoU7lHK)oip zR`@%051t|D6B0RbPpa$Wg&dCln=^WH(z7g>3mDI0VOQ%MkhcCDxS{@P1*~i-;4FhL zSS)|{2e#S78PHoelB`piqheyxB>`hPJi@bOQ9Sq{O`h8oP!2pG`LVWk0?q2D5NA!g|)tUOd;8>V~{{`Ccy9 z7DQDEuWOq8KhVzQn$`~jZjQ^vZZ?0FZ>k{{W97h(6 diff --git a/dropbox/jsOAuth-1.3.6.min.js b/dropbox/jsOAuth-1.3.6.min.js new file mode 100644 index 000000000..bb6388541 --- /dev/null +++ b/dropbox/jsOAuth-1.3.6.min.js @@ -0,0 +1 @@ +var exports=exports||this;exports.OAuth=function(e){function t(e){var t=arguments,n=t.callee,r=t.length,i,s=this;if(this instanceof n){for(i in e)e.hasOwnProperty(i)&&(s[i]=e[i]);return s}return new n(e)}function n(){}function r(e){var t=arguments,n=t.callee,r,s,o,u,a,f,l,c=/^([^:\/?#]+?:\/\/)*([^\/:?#]*)?(:[^\/?#]*)*([^?#]*)(\?[^#]*)?(#(.*))*/,h=this;if(!(this instanceof n))return new n(e);h.scheme="",h.host="",h.port="",h.path="",h.query=new i,h.anchor="";if(e!==null){r=e.match(c),s=r[1],o=r[2],u=r[3],a=r[4],f=r[5],l=r[6],s=s!==undefined?s.replace("://","").toLowerCase():"http",u=u?u.replace(":",""):s==="https"?"443":"80",s=s=="http"&&u==="443"?"https":s,f=f?f.replace("?",""):"",l=l?l.replace("#",""):"";if(s==="https"&&u!=="443"||s==="http"&&u!=="80")o=o+":"+u;h.scheme=s,h.host=o,h.port=u,h.path=a||"/",h.query.setQueryParams(f),h.anchor=l||""}}function i(e){var t=arguments,n=t.callee,r=t.length,i,s=this,u=o.urlDecode;if(this instanceof n){if(e!=undefined)for(i in e)e.hasOwnProperty(i)&&(s[i]=e[i]);return s}return new n(e)}function o(e){return this instanceof o?this.init(e):new o(e)}function u(e){var t=[],n,r;for(n in e)e[n]&&e[n]!==undefined&&e[n]!==""&&(n==="realm"?r=n+'="'+e[n]+'"':t.push(n+'="'+o.urlEncode(e[n]+"")+'"'));return t.sort(),r&&t.unshift(r),t.join(", ")}function a(e,t,n,r){var i=[],s,u=o.urlEncode;for(s in n)n[s]!==undefined&&n[s]!==""&&i.push([o.urlEncode(s),o.urlEncode(n[s]+"")]);for(s in r)r[s]!==undefined&&r[s]!==""&&(n[s]||i.push([u(s),u(r[s]+"")]));return i=i.sort(function(e,t){return e[0]t[0]?1:e[1]t[1]?1:0}).map(function(e){return e.join("=")}),[e,u(t),u(i.join("&"))].join("&")}function f(){return parseInt(+(new Date)/1e3,10)}function l(e){function t(){return Math.floor(Math.random()*u.length)}e=e||64;var n=e/8,r="",i=n/4,s=n%4,o,u=["20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F","30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F","40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F","50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F","60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F","70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E"];for(o=0;o>6),128+(n&63)):n<65536?t.push(224+(n>>12),128+(n>>6&63),128+(n&63)):n<2097152&&t.push(240+(n>>18),128+(n>>12&63),128+(n>>6&63),128+(n&63));return t}function d(e){var t=[],n;for(n=0;n>>5]>>>24-n%32&255);return t}function v(e){var t=[],n=e.length,r;for(r=0;r>>4).toString(16)),t.push((e[r]&15).toString(16));return t.join("")}function m(e){var t="",n=e.length,r;for(r=0;r>>32-t}function y(e){if(e!==undefined){var t=e,n,r;return t.constructor===String&&(t=p(t)),this instanceof y?n=this:n=new y(e),r=n.hash(t),v(r)}return this instanceof y?this:new y}function b(e,t,n,r){var i=p(t),s=p(n),o=i.length,u,a,f,l;o>e.blocksize&&(i=e.hash(i),o=i.length),i=i.concat(h(e.blocksize-o)),a=i.slice(0),f=i.slice(0);for(l=0;l0&&(r=n.join("&")),r},i.prototype.setQueryParams=function(e){var t=arguments,n=t.length,r,i,s,u=this,a,f=o.urlDecode;if(n==1){if(typeof e=="object")for(r in e)e.hasOwnProperty(r)&&(u[r]=f(e[r]));else if(typeof e=="string"){i=e.split("&");for(r=0,s=i.length;r=200&&m.status<=226||m.status==304||m.status===0?d(a):m.status>=400&&m.status!==0&&v(a)}},y={oauth_callback:n.callbackUrl,oauth_consumer_key:n.consumerKey,oauth_token:n.accessTokenKey,oauth_signature_method:n.signatureMethod,oauth_timestamp:f(),oauth_nonce:l(),oauth_verifier:n.verifier,oauth_version:s},b=n.signatureMethod,N=i.query.toObject();for(g in N)T[g]=N[g];if((!("Content-Type"in p)||p["Content-Type"]=="application/x-www-form-urlencoded")&&!C)for(g in h)T[g]=h[g];k=i.scheme+"://"+i.host+i.path,w=a(t,k,y,T),E=o.signatureMethod[b](n.consumerSecret,n.accessTokenSecret,w),y.oauth_signature=E,this.realm&&(y.realm=this.realm),n.proxyUrl&&(i=r(n.proxyUrl+i.path));if(x||t=="GET")i.query.setQueryParams(h),S=null;else if(!C)if(typeof h=="string")S=h,"Content-Type"in p||(p["Content-Type"]="text/plain");else{for(g in h)S.push(o.urlEncode(g)+"="+o.urlEncode(h[g]+""));S=S.sort().join("&"),"Content-Type"in p||(p["Content-Type"]="application/x-www-form-urlencoded")}else if(C){S=new FormData;for(g in h)S.append(g,h[g])}m.open(t,i+"",!0),m.setRequestHeader("Authorization","OAuth "+u(y)),m.setRequestHeader("X-Requested-With","XMLHttpRequest");for(g in p)m.setRequestHeader(g,p[g]);m.send(S)},this},get:function(e,t,n){this.request({url:e,success:t,failure:n})},post:function(e,t,n,r){this.request({method:"POST",url:e,data:t,success:n,failure:r})},getJSON:function(e,t,n){this.get(e,function(e){t(JSON.parse(e.text))},n)},postJSON:function(e,t,n,r){this.request({method:"POST",url:e,data:JSON.stringify(t),success:function(e){n(JSON.parse(e.text))},failure:r,headers:{"Content-Type":"application/json"}})},parseTokenRequest:function(e,t){switch(t){case"text/xml":var n=e.xml.getElementsByTagName("token"),r=e.xml.getElementsByTagName("secret");a[o.urlDecode(n[0])]=o.urlDecode(r[0]);break;default:var i=0,s=e.text.split("&"),u=s.length,a={};for(;i{}|`^\\\u0080-\uffff]/,r=e.length,i,s=e.split(""),o;for(i=0;i>6))+t(128+(o&63)):o<65536?s[i]=t(224+(o>>12))+t(128+(o>>6&63))+t(128+(o&63)):o<2097152&&(s[i]=t(240+(o>>18))+t(128+(o>>12&63))+t(128+(o>>6&63))+t(128+(o&63)));return s.join("")},o.urlDecode=function(e){return e?e.replace(/%[a-fA-F0-9]{2}/ig,function(e){return String.fromCharCode(parseInt(e.replace("%",""),16))}):""},y.prototype=new y,y.prototype.blocksize=64,y.prototype.hash=function(e){function C(e,t,n,r){switch(e){case 0:return t&n|~t&r;case 1:case 3:return t^n^r;case 2:return t&n|t&r|n&r}return-1}var t=[1732584193,4023233417,2562383102,271733878,3285377520],n=[1518500249,1859775393,2400959708,3395469782],r,i,s,o,u,a,f,l,c,v,m,y,b,w,E,S,x,T,N;e.constructor===String&&(e=p(e.encodeUTF8())),s=e.length,o=Math.ceil((s+9)/this.blocksize)*this.blocksize-(s+9),i=Math.floor(s/4294967296),r=Math.floor(s%4294967296),u=[i*8>>24&255,i*8>>16&255,i*8>>8&255,i*8&255,r*8>>24&255,r*8>>16&255,r*8>>8&255,r*8&255],e=e.concat([128],h(o),u),a=Math.ceil(e.length/this.blocksize);for(f=0;f>>2]|=l[m]<<24-(m-(m>>2)*4)*8;y=t[0],b=t[1],w=t[2],E=t[3],S=t[4];for(x=0;x<80;x++)x>=16&&(v[x]=g(v[x-3]^v[x-8]^v[x-14]^v[x-16],1)),T=Math.floor(x/20),N=g(y,5)+C(T,b,w,E)+S+n[T]+v[x],S=E,E=w,w=g(b,30),b=y,y=N;t[0]+=y,t[1]+=b,t[2]+=w,t[3]+=E,t[4]+=S}return d(t)},o}(exports);var exports=exports||this;(function(e){var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";e.btoa=e.btoa||function(e){var n=0,r=e.length,i,s,o="";for(;n>2,(i[0]&3)<<4|i[1]>>4,(i[1]&15)<<2|i[2]>>6,i[2]&63],isNaN(i[1])&&(s[2]=64),isNaN(i[2])&&(s[3]=64),o+=t.charAt(s[0])+t.charAt(s[1])+t.charAt(s[2])+t.charAt(s[3]);return o}})(exports) \ No newline at end of file From ca6f80a3f2d36489acc05b7299635a3d7e960c1a Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Tue, 19 Feb 2013 22:03:03 +0100 Subject: [PATCH 009/118] Rewrite of the oauth in Dropbox resolver. --- dropbox/dropbox.js | 217 ++++++++++++++++++++++++++++++--------------- 1 file changed, 144 insertions(+), 73 deletions(-) diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index 391579f8c..e429bdbf5 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -1,5 +1,4 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { - oauth: null, uid: '', cursor: '', @@ -44,106 +43,44 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { associateClicked: function () { Tomahawk.log("Associate was clicked"); - this.oauth.fetchRequestToken(this.openAcceptPage, this.queryFailure); + this.oauth.associate(this.updateDatabase); }, deleteClicked: function () { Tomahawk.log("Delete was clicked"); + this.oauth.deleteAssociation(); + }, - openAcceptPage: function(url) { - Tomahawk.requestWebView("acceptPage", url); - - //acceptPage.setWindowModality(2); - //acceptPage.resize(acceptPage.height(), 800); - - acceptPage.show(); - acceptPage.urlChanged.connect(Tomahawk.resolver.instance, function(url){ - this.onUrlChanged(url.toString()); - }); - }, - - onUrlChanged: function(url){ - Tomahawk.log("URL returned : \'" + url+"\'"); - - if(url === 'https://www.dropbox.com/1/oauth/authorize'){ - this.oauth.fetchAccessToken(this.onAccessTokenReceived, this.queryFailure); - } - - if(url === 'https://www.dropbox.com/home'){ - Tomahawk.log("Refused"); - //close webpage - } - }, - - onAccessTokenReceived: function(data){ - //parse response - var i = 0, arr = data.text.split('&'), len = arr.length, obj = {}; - for (; i < len; ++i) { - var pair = arr[i].split('='); - obj[OAuth.urlDecode(pair[0])] = OAuth.urlDecode(pair[1]); - } - - //TODO close webpage - Tomahawk.log("Setting DB"); - - window.localStorage.setItem('accessTokenKey',obj.oauth_token); - window.localStorage.setItem('accessTokenSecret',obj.oauth_token_secret); - window.localStorage.setItem('cursor',''); - - Tomahawk.log("DB setted"); - this.updateDatabase(); - }, - queryFailure: function(data) { - Tomahawk.log("Request Failed : " + data); + Tomahawk.log("Request Failed : " + data.text); }, init: function () { Tomahawk.log("Beginnning INIT of Dropbox resovler"); - Tomahawk.log(this.db.setItem); Tomahawk.addLocalJSFile('jsOAuth-1.3.6.min.js'); //Tomahawk.addLocalJSFile("musicManager.js"); - this.cursor = this.db.getItem('cursor',''); + this.cursor = db.getItem('cursor',''); - this.oauth = OAuth({ - consumerKey: '7scivkf1tstl8dl', - consumerSecret: 'lu05s08m19h0dib', - requestTokenUrl: 'https://api.dropbox.com/1/oauth/request_token', - authorizationUrl: 'https://www.dropbox.com/1/oauth/authorize', - accessTokenUrl: 'https://api.dropbox.com/1/oauth/access_token', - accessTokenKey: this.db.getItem('accessTokenKey',''), - accessTokenSecret: this.db.getItem('accessTokenSecret','') - }); + this.oauth.init(); //TODO updateDatabase every 30 min (and handle if a user asked for a DB refresh before) + //TODO update only if asscociated to an account this.updateDatabase(); }, updateDatabase: function(){ Tomahawk.log("Sending Delta Query : "); - this.oauth.postJSON('https://api.dropbox.com/1/delta', {'cursor': ''}, this.deltaCallback, this.queryFailure); + this.oauth.opostJSON('https://api.dropbox.com/1/delta', {'cursor': ''}, this.deltaCallback, this.queryFailure); }, deltaCallback: function(response){ //TODO set cursor in DB - Tomahawk.log("Delta results : "); - Tomahawk.log(response.text); + Tomahawk.log("Delta returned!"); + Tomahawk.log("Cursor : " + response.cursor); }, - db: { - setItem: window.localStorage.setItem, - getItem: function (key, defaultResponse){ - var result = window.localStorage.getItem(key); - result = (result == null)? defaultResponse : result; - - Tomahawk.log("DB: loaded "+key+" : '"+ result+"' "); - - return result; - } - }, - resolve: function (qid, artist, album, title) { //this.doSearchOrResolve(qid, title, 1); }, @@ -165,7 +102,141 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { tracks: function( qid, artist, album ) { + }, + + oauth: { + + init: function(){ + this.oauthSettings.accessTokenKey = db.getItem('accessTokenKey',''); + this.oauthSettings.accessTokenSecret = db.getItem('accessTokenSecret',''); + + this.oauthEngine = OAuth(this.oauthSettings); + }, + + //associate a new User + //If the association is succesfull the previous token is discarded + associate: function(callback){ + this.oauthEngine.fetchRequestToken(function(data){ + this.resolver.oauth.openAcceptPage(data, callback); + }, this.queryFailure); + }, + + deleteAssociation: function(){ + db.setItem('accessTokenKey',''); + db.setItem('accessTokenSecret',''); + db.setItem('cursor',''); + + this.oauthSettings.accessTokenKey = ''; + this.oauthSettings.accessTokenSecret = ''; + + this.oauthEngine = OAuth(this.oauthSettings); + + }, + + isAssociated: function(){ + var accessKey = db.getItem('accessTokenKey',''); + var accessSecret = db.getItem('accessTokenSecret',''); + return( !(accessKey === '') && !(accessSecret === '') ); + }, + + opostJSON: function(url, data, success, failure){ + if(!this.isAssociated()){ + //TODO throw error NoAccountAssociated ? + Tomahawk.log("REFUSED Post to "+ url + " : No account associated"); + }else{ + this.oauthEngine.postJSON(url, data, success, failure); + } + }, + + ogetJSON: function(url, success, failure){ + if(!this.isAssociated()){ + //TODO throw error NoAccountAssociated ? + Tomahawk.log("REFUSED Get to "+ url + " : No account associated"); + }else{ + this.oauthEngine.getJSON(url, success, failure); + } + }, + + //Private member + oauthEngine: null, + + oauthSettings: { + consumerKey: '7scivkf1tstl8dl', + consumerSecret: 'lu05s08m19h0dib', + requestTokenUrl: 'https://api.dropbox.com/1/oauth/request_token', + authorizationUrl: 'https://www.dropbox.com/1/oauth/authorize', + accessTokenUrl: 'https://api.dropbox.com/1/oauth/access_token', + accessTokenKey: '', + accessTokenSecret: '' + }, + + openAcceptPage: function(url, callback) { + Tomahawk.requestWebView("acceptPage", url); + + //acceptPage.setWindowModality(2); + //acceptPage.resize(acceptPage.height(), 800); + + acceptPage.show(); + acceptPage.urlChanged.connect(Tomahawk.resolver.instance.oauth, function(url){ + this.onUrlChanged(url.toString(), callback); + }); + }, + + onUrlChanged: function(url, callback){ + Tomahawk.log("URL returned : \'" + url+"\'"); + + if(url === 'https://www.dropbox.com/1/oauth/authorize'){ + this.oauthEngine.fetchAccessToken(function(data){ + this.resolver.oauth.onAccessTokenReceived(data, callback); + }, this.queryFailure); + } + + if(url === 'https://www.dropbox.com/home'){ + Tomahawk.log("Refused"); + //close webpage + } + }, + + onAccessTokenReceived: function(data, callback){ + //parse response + var i = 0, arr = data.text.split('&'), len = arr.length, obj = {}; + for (; i < len; ++i) { + var pair = arr[i].split('='); + obj[OAuth.urlDecode(pair[0])] = OAuth.urlDecode(pair[1]); + } + + //TODO close webpage + + this.oauthSettings.accessTokenKey = obj.oauth_token; + this.oauthSettings.accessTokenSecret = obj.oauth_token_secret; + + db.setItem('accessTokenKey',obj.oauth_token); + db.setItem('accessTokenSecret',obj.oauth_token_secret); + + if(! (typeof callback === 'undefined')){ + callback.call(Tomahawk.resolver.instance); + } + }, + + queryFailure: function(data) { + Tomahawk.log("Request Failed : " + data.text); + } + } }); +var db = { + setItem: function(a1, a2){ + window.localStorage.setItem(a1,a2); + }, + getItem: function (key, defaultResponse){ + var result = window.localStorage.getItem(key); + result = (result == null)? defaultResponse : result; + + Tomahawk.log("DB: loaded "+key+" : '"+ result+"' "); + + return result; + } +}; + Tomahawk.resolver.instance = DropboxResolver; From f6751b1a4dc527b5f6e4d3e8545a245d6fd9b197 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Wed, 20 Feb 2013 15:10:18 +0100 Subject: [PATCH 010/118] Minor correction when deleting the association in Dropbox resolver --- dropbox/dropbox.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index e429bdbf5..988f79baa 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -48,6 +48,10 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { deleteClicked: function () { Tomahawk.log("Delete was clicked"); + + this.cursor = ''; + db.setItem('cursor',''); + this.oauth.deleteAssociation(); }, @@ -124,7 +128,6 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { deleteAssociation: function(){ db.setItem('accessTokenKey',''); db.setItem('accessTokenSecret',''); - db.setItem('cursor',''); this.oauthSettings.accessTokenKey = ''; this.oauthSettings.accessTokenSecret = ''; From fd7815f4d6e28a411d288ae41e89f19a236371ab Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Wed, 20 Feb 2013 18:23:53 +0100 Subject: [PATCH 011/118] Add Google drive resolver with OAuth manager and changes.list request. --- googledrive/config.ui | 78 +++++++++ googledrive/googledrive.js | 312 ++++++++++++++++++++++++++++++++++++ googledrive/googledrive.png | Bin 0 -> 11493 bytes 3 files changed, 390 insertions(+) create mode 100644 googledrive/config.ui create mode 100644 googledrive/googledrive.js create mode 100644 googledrive/googledrive.png diff --git a/googledrive/config.ui b/googledrive/config.ui new file mode 100644 index 000000000..73c3b4336 --- /dev/null +++ b/googledrive/config.ui @@ -0,0 +1,78 @@ + + + Form + + + + 0 + 0 + 447 + 305 + + + + Form + + + + + + + + + googledrive.png + + + Qt::AlignCenter + + + + + + + QFormLayout::FieldsStayAtSizeHint + + + Qt::AlignJustify|Qt::AlignVCenter + + + Qt::AlignJustify|Qt::AlignTop + + + + + Account : + + + + + + + nd + + + + + + + Associate + + + + + + + true + + + Delete + + + + + + + + + + diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js new file mode 100644 index 000000000..3f7f2da1e --- /dev/null +++ b/googledrive/googledrive.js @@ -0,0 +1,312 @@ +var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { + uid: '', + cursor: '', + maxResults: '150', + + settings: { + name: 'Google Drive', + weight: 60, + icon : 'googledrive.png', + timeout: 15 + }, + + getConfigUi: function () { + var uiData = Tomahawk.readBase64("config.ui"); + return { + + "widget": uiData, + fields: [{ + name: "associateButton", + widget: "associateButton", + property: "text", + connections : [ { + signal: "clicked()", + javascriptCallback: "resolver.associateClicked();" + }] + }, + { + name: "deleteButton", + widget: "deleteButton", + property: "text", + connections : [ { + signal: "clicked()", + javascriptCallback: "resolver.deleteClicked();" + }] + },], + images: [{ + "googledrive.png": Tomahawk.readBase64("googledrive.png") + }, ] + }; + }, + + newConfigSaved: function () { + }, + + associateClicked: function () { + Tomahawk.log("Associate was clicked"); + + this.oauth.associate(this.updateDatabase); + }, + + deleteClicked: function () { + Tomahawk.log("Delete was clicked"); + + this.cursor = ''; + db.setItem('cursor',''); + + this.oauth.deleteAssociation(); + + }, + + queryFailure: function(data) { + Tomahawk.log("Request Failed : " + data.text); + }, + + init: function () { + Tomahawk.log("Beginnning INIT of Google Drive resovler"); + + //Tomahawk.addLocalJSFile("musicManager.js"); + + this.cursor = db.getItem('cursor',''); + + this.oauth.init(); + + //TODO updateDatabase every 30 min (and handle if a user asked for a DB refresh before) + //TODO update only if asscociated to an account + this.updateDatabase(); + }, + + updateDatabase: function(){ + Tomahawk.log("Sending Delta Query : "); + var url = 'https://www.googleapis.com/drive/v2/changes?' + +'maxResults=' + this.maxResults + +'&pageToken=1'; + this.oauth.ogetJSON(url, this.deltaCallback); + }, + + deltaCallback: function(response){ + //TODO set cursor in DB + Tomahawk.log("Delta returned!"); + Tomahawk.log("Cursor : " + response.selfLink); + }, + + resolve: function (qid, artist, album, title) { + //this.doSearchOrResolve(qid, title, 1); + }, + + search: function (qid, searchString) { + //this.doSearchOrResolve(qid, searchString, 15); + }, + + artists: function( qid ) + { + + }, + + albums: function( qid, artist ) + { + + }, + + tracks: function( qid, artist, album ) + { + + }, + + oauth: { + + init: function(){ + this.accessToken = db.getItem('accessToken',''); + this.refreshToken = db.getItem('refreshToken',''); + this.expiresOn = db.getItem('expiresOn',''); + }, + + //associate a new User + //If the association is succesfull the previous token is discarded + associate: function(callback){ + var url = this.oauthUrl + '?response_type=code&client_id=' + this.clientId + '&redirect_uri=' + this.redirectUri + '&scope=' + this.scopes; + this.openAcceptPage(url, callback); + }, + + deleteAssociation: function(){ + db.setItem('accessToken',''); + db.setItem('refreshToken',''); + db.setItem('expiresOn',''); + + this.accessToken = ''; + this.refreshToken = ''; + this.expiresOn = ''; + }, + + isAssociated: function(){ + var accessToken = db.getItem('accessToken',''); + var refreshToken = db.getItem('refreshToken',''); + return( !(accessToken === '') && !(refreshToken === '') ); + }, + + opostJSON: function(url, data, success){ + if(!this.isAssociated()){ + //TODO throw error NoAccountAssociated ? + Tomahawk.log("REFUSED Post to "+ url + " : No account associated"); + }else{ + if(this.tokenExpired()){ + Tomahawk.log("Token expiré"); + this.getRefreshedAccessToken();//this.opostJSON(url, data, success)); + }else{ + //TODO treat case no parameters given + //data = data + '&access_token=' + this.accessToken; + Tomahawk.asyncPostRequest(url, data, function (data) { + success(JSON.parse(data.responseText)); + }, {'Authorization': 'Bearer '+ this.accessToken}); + } + } + }, + + ogetJSON: function(url, success){ + if(!this.isAssociated()){ + //TODO throw error NoAccountAssociated ? + Tomahawk.log("REFUSED Get to "+ url + " : No account associated"); + }else{ + if(this.tokenExpired()){ + Tomahawk.log("Token expiré"); + this.getRefreshedAccessToken();//this.ogetJSON(url, success)); + }else{ + //TODO treat case no parameters given + //url = url + '&access_token=' + this.accessToken; + Tomahawk.asyncRequest(url, function (data) { + success(JSON.parse(data.responseText)); + }, {'Authorization': 'Bearer '+ this.accessToken}); + } + } + }, + + //Private member + + clientId: '440397511251.apps.googleusercontent.com', + clientSecret: 'Y2ucuavLH6HN4CmlPGhdHuxu', + oauthUrl: 'https://accounts.google.com/o/oauth2/auth', + tokenUrl: 'https://accounts.google.com/o/oauth2/token', + scopes: 'https://www.googleapis.com/auth/drive.readonly', + redirectUri: 'urn:ietf:wg:oauth:2.0:oob', + accessToken: '', + refreshToken: '', + expiresOn: '', + + + openAcceptPage: function(url, callback) { + Tomahawk.log('Opening : ' + url); + Tomahawk.requestWebView("acceptPage", url); + + //acceptPage.setWindowModality(2); + //acceptPage.resize(acceptPage.height(), 800); + + acceptPage.show(); + acceptPage.titleChanged.connect(Tomahawk.resolver.instance.oauth, function(title){ + this.onTitleChanged(title, callback); + }); + }, + + onTitleChanged: function(title, callback){ + Tomahawk.log("Title changed : \'" + title+"\'"); + + //Success code=4/QcbxAjMwlkk56roXuLBM9nltk3ju + //Denied error=access_denied + + var result = title.split('='); + + if(result[0] === 'Success code'){ + Tomahawk.log("Accepted"); + var that = this; + var params = 'grant_type=authorization_code' + + '&code=' + result[1] + + '&client_id=' + this.clientId + + '&client_secret='+ this.clientSecret + + '&redirect_uri=' + this.redirectUri; + Tomahawk.log("Sending post : "+ params); + Tomahawk.asyncPostRequest(this.tokenUrl, params, function(data){ + that.onAccessTokenReceived(data, callback); + }); + } + + if(result[0] === 'Denied error'){ + Tomahawk.log("Refused"); + //close webpage + } + }, + + onAccessTokenReceived: function(data, callback){ + //parse response + var ret = JSON.parse(data.responseText); + + //TODO close webpage + + this.accessToken = ret.access_token; + this.refreshToken = ret.refresh_token; + this.expiresOn = Math.floor(Date.now()/1000) + ret.expires_in; + + db.setItem('accessToken',this.accessToken); + db.setItem('refreshToken',this.refreshToken); + db.setItem('expiresOn',this.expiresOn); + + if(! (typeof callback === 'undefined')){ + callback.call(Tomahawk.resolver.instance); + } + }, + + onRefreshedTokenReceived: function(data, callback){ + //parse response + var ret = JSON.parse(data.responseText); + + Tomahawk.log('Old access token : ' + this.accessToken); + Tomahawk.log('New access token : ' + ret.access_token); + + this.accessToken = ret.access_token; + this.expiresOn = Math.floor(Date.now()/1000) + ret.expires_in; + + db.setItem('accessToken',this.accessToken); + db.setItem('expiresOn',this.expiresOn); + + if(! (typeof callback === 'undefined')){ + callback.call(Tomahawk.resolver.instance); + } + }, + + tokenExpired: function(){ + return (Math.floor(Date.now()/1000) > this.expiresOn); + }, + + getRefreshedAccessToken: function(callback){ + Tomahawk.log("Refreshing token"); + var that = this; + var params = 'grant_type=refresh_token' + + '&refresh_token=' + this.refreshToken + + '&client_id=' + this.clientId + + '&client_secret=' + this.clientSecret; + + Tomahawk.asyncPostRequest(this.tokenUrl, params, function(data){ + that.onRefreshedTokenReceived(data, callback); + }); + }, + + queryFailure: function(data) { + Tomahawk.log("Request Failed : " + data.text); + } + + } +}); + +var db = { + setItem: function(a1, a2){ + window.localStorage.setItem(a1,a2); + }, + getItem: function (key, defaultResponse){ + var result = window.localStorage.getItem(key); + result = (result == null)? defaultResponse : result; + + Tomahawk.log("DB: loaded "+key+" : '"+ result+"' "); + + return result; + } +}; + +Tomahawk.resolver.instance = GoogleDriveResolver; diff --git a/googledrive/googledrive.png b/googledrive/googledrive.png new file mode 100644 index 0000000000000000000000000000000000000000..49c89b660517cf3c145d0126ecf3ff1dc176e541 GIT binary patch literal 11493 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 LNkvXXu0mjf{xs+S literal 0 HcmV?d00001 From d635ec2b12257c68135f4d602c53a21dcfdd917c Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Thu, 21 Feb 2013 13:13:43 +0100 Subject: [PATCH 012/118] Add oauth managment in google drive resolver. Add pretty logging of delta in Dropbox resolver. --- dropbox/dropbox.js | 38 ++++++++++ googledrive/googledrive.js | 146 +++++++++++++++++++++++++++--------- googledrive/googledrive.png | Bin 3 files changed, 150 insertions(+), 34 deletions(-) mode change 100644 => 100755 googledrive/googledrive.png diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index 988f79baa..69432904c 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -83,6 +83,11 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { //TODO set cursor in DB Tomahawk.log("Delta returned!"); Tomahawk.log("Cursor : " + response.cursor); + Tomahawk.log("Hasmore : " + response.has_more); + Tomahawk.log("Entries length : " + response.entries.length); + for(var i = 0; i < 5; i++){ + Tomahawk.log("Entry n°" + i + " : " + response.entries[i][0] + " : " + DumpObjectIndented(response.entries[i][1])); + } }, resolve: function (qid, artist, album, title) { @@ -243,3 +248,36 @@ var db = { }; Tomahawk.resolver.instance = DropboxResolver; + +function DumpObjectIndented(obj, indent) +{ + var result = ""; + if (indent == null) indent = ""; + + for (var property in obj) + { + var value = obj[property]; + if (typeof value == 'string') + value = "'" + value + "'"; + else if (typeof value == 'object') + { + if (value instanceof Array) + { + // Just let JS convert the Array to a string! + value = "[ " + value + " ]"; + } + else + { + // Recursive dump + // (replace " " by "\t" or something else if you prefer) + var od = DumpObjectIndented(value, indent + " "); + // If you like { on the same line as the key + //value = "{\n" + od + "\n" + indent + "}"; + // If you prefer { and } to be aligned + value = "\n" + indent + "{\n" + od + "\n" + indent + "}"; + } + } + result += indent + "'" + property + "' : " + value + ",\n"; + } + return result.replace(/,\n$/, ""); +} diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 3f7f2da1e..321c1e28d 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -1,7 +1,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { uid: '', cursor: '', - maxResults: '150', + maxResults: '15000', settings: { name: 'Google Drive', @@ -18,7 +18,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { fields: [{ name: "associateButton", widget: "associateButton", - property: "text", + property: "text", connections : [ { signal: "clicked()", javascriptCallback: "resolver.associateClicked();" @@ -44,15 +44,17 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { associateClicked: function () { Tomahawk.log("Associate was clicked"); - - this.oauth.associate(this.updateDatabase); + var that = this; + this.oauth.associate(function(){ + that.updateDatabase(); + }); }, deleteClicked: function () { Tomahawk.log("Delete was clicked"); this.cursor = ''; - db.setItem('cursor',''); + dbLocal.setItem('cursor',''); this.oauth.deleteAssociation(); @@ -64,30 +66,60 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { init: function () { Tomahawk.log("Beginnning INIT of Google Drive resovler"); - + dbLocal.setItem("expiresOn","1"); //Tomahawk.addLocalJSFile("musicManager.js"); - this.cursor = db.getItem('cursor',''); + this.cursor = dbLocal.getItem('cursor',''); this.oauth.init(); + + Tomahawk.log(typeof this.expiresOn ); + Tomahawk.log((Math.floor(Date.now()/1000) ).toString()); //TODO updateDatabase every 30 min (and handle if a user asked for a DB refresh before) //TODO update only if asscociated to an account + this.updateDatabase(); }, updateDatabase: function(){ + var that = this; Tomahawk.log("Sending Delta Query : "); var url = 'https://www.googleapis.com/drive/v2/changes?' +'maxResults=' + this.maxResults +'&pageToken=1'; - this.oauth.ogetJSON(url, this.deltaCallback); + this.oauth.ogetJSON(url, function(){that.deltaCallback;}); }, deltaCallback: function(response){ //TODO set cursor in DB Tomahawk.log("Delta returned!"); - Tomahawk.log("Cursor : " + response.selfLink); + Tomahawk.log("selfLink : " + response.selfLink); + Tomahawk.log("nextPageToken : " + response.nextPageToken); + //Tomahawk.log(DumpObjectIndented(response.items)); + + for( var i = 0; i < response.items.length; i++){ + var item = response.items[i]; + //Tomahawk.log(DumpObjectIndented(item)); + Tomahawk.log(item['file']['mimeType']); + Tomahawk.log(this.isMimeTypeSupported); + for(var p in this){ + Tomahawk.log(p + " : "+ this[p]); + } + if(this.isMimeTypeSupported(item['file']['mimeType'])){ + if(item.deleted === 'true'){ + Tomahawk.log("Deleting : " + item['fileId']); + //dbSQL.deleteTrack(item.file.id); + }else{ + //Get ID3 Tag + Tomahawk.log("Get ID3Tag from : " + item['file']['originalFilename']); + //var that = this; + //Tomahawk.getID3Tag(this.oauth.createOauthUrl(item['file']['downloadUrl']), function(tags){ + //that.onID3TagCallback(item['fileId'], tags); + //}); + } + } + } }, resolve: function (qid, artist, album, title) { @@ -113,12 +145,26 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, + onID3TagCallback: function(fileId, tags) + { + //Add track to database + //var url = 'googledrive://' + fileId; + //dbSql.addTrack + }, + + isMimeTypeSupported: function(mimeType) + { + Tomahawk.log("Checking : "+ mimeType); + var mimes = [ "audio/mpeg" , "application/ogg" , "application/ogg" , "audio/x-musepack" , "audio/x-ms-wma" , "audio/mp4" , "audio/mp4" , "audio/mp4" , "audio/flac" , "audio/aiff" , "audio/aiff" , "audio/x-wavpack" ]; + return (mimes.contains(mimeType)); + }, + oauth: { init: function(){ - this.accessToken = db.getItem('accessToken',''); - this.refreshToken = db.getItem('refreshToken',''); - this.expiresOn = db.getItem('expiresOn',''); + this.accessToken = dbLocal.getItem('accessToken',''); + this.refreshToken = dbLocal.getItem('refreshToken',''); + this.expiresOn = dbLocal.getItem('expiresOn',''); }, //associate a new User @@ -129,9 +175,9 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, deleteAssociation: function(){ - db.setItem('accessToken',''); - db.setItem('refreshToken',''); - db.setItem('expiresOn',''); + dbLocal.setItem('accessToken',''); + dbLocal.setItem('refreshToken',''); + dbLocal.setItem('expiresOn',''); this.accessToken = ''; this.refreshToken = ''; @@ -139,22 +185,22 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, isAssociated: function(){ - var accessToken = db.getItem('accessToken',''); - var refreshToken = db.getItem('refreshToken',''); + var accessToken = dbLocal.getItem('accessToken',''); + var refreshToken = dbLocal.getItem('refreshToken',''); return( !(accessToken === '') && !(refreshToken === '') ); }, opostJSON: function(url, data, success){ + var that = this; if(!this.isAssociated()){ //TODO throw error NoAccountAssociated ? Tomahawk.log("REFUSED Post to "+ url + " : No account associated"); }else{ if(this.tokenExpired()){ - Tomahawk.log("Token expiré"); - this.getRefreshedAccessToken();//this.opostJSON(url, data, success)); + Tomahawk.log("Token expired"); + this.getRefreshedAccessToken(function (){that.opostJSON(url, data, success);}); }else{ //TODO treat case no parameters given - //data = data + '&access_token=' + this.accessToken; Tomahawk.asyncPostRequest(url, data, function (data) { success(JSON.parse(data.responseText)); }, {'Authorization': 'Bearer '+ this.accessToken}); @@ -163,16 +209,16 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, ogetJSON: function(url, success){ + var that = this; if(!this.isAssociated()){ //TODO throw error NoAccountAssociated ? Tomahawk.log("REFUSED Get to "+ url + " : No account associated"); }else{ if(this.tokenExpired()){ - Tomahawk.log("Token expiré"); - this.getRefreshedAccessToken();//this.ogetJSON(url, success)); + Tomahawk.log("Token expired"); + this.getRefreshedAccessToken(function (){that.ogetJSON(url, success);}); }else{ //TODO treat case no parameters given - //url = url + '&access_token=' + this.accessToken; Tomahawk.asyncRequest(url, function (data) { success(JSON.parse(data.responseText)); }, {'Authorization': 'Bearer '+ this.accessToken}); @@ -209,9 +255,6 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { onTitleChanged: function(title, callback){ Tomahawk.log("Title changed : \'" + title+"\'"); - //Success code=4/QcbxAjMwlkk56roXuLBM9nltk3ju - //Denied error=access_denied - var result = title.split('='); if(result[0] === 'Success code'){ @@ -222,7 +265,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { + '&client_id=' + this.clientId + '&client_secret='+ this.clientSecret + '&redirect_uri=' + this.redirectUri; - Tomahawk.log("Sending post : "+ params); + Tomahawk.asyncPostRequest(this.tokenUrl, params, function(data){ that.onAccessTokenReceived(data, callback); }); @@ -244,12 +287,13 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { this.refreshToken = ret.refresh_token; this.expiresOn = Math.floor(Date.now()/1000) + ret.expires_in; - db.setItem('accessToken',this.accessToken); - db.setItem('refreshToken',this.refreshToken); - db.setItem('expiresOn',this.expiresOn); + dbLocal.setItem('accessToken',this.accessToken); + dbLocal.setItem('refreshToken',this.refreshToken); + dbLocal.setItem('expiresOn',this.expiresOn); if(! (typeof callback === 'undefined')){ callback.call(Tomahawk.resolver.instance); + //callback(); } }, @@ -263,11 +307,13 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { this.accessToken = ret.access_token; this.expiresOn = Math.floor(Date.now()/1000) + ret.expires_in; - db.setItem('accessToken',this.accessToken); - db.setItem('expiresOn',this.expiresOn); + dbLocal.setItem('accessToken',this.accessToken); + dbLocal.setItem('expiresOn',this.expiresOn); if(! (typeof callback === 'undefined')){ + Tomahawk.log("Calling..."); callback.call(Tomahawk.resolver.instance); + //callback(); } }, @@ -276,7 +322,6 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, getRefreshedAccessToken: function(callback){ - Tomahawk.log("Refreshing token"); var that = this; var params = 'grant_type=refresh_token' + '&refresh_token=' + this.refreshToken @@ -295,7 +340,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { } }); -var db = { +var dbLocal = { setItem: function(a1, a2){ window.localStorage.setItem(a1,a2); }, @@ -310,3 +355,36 @@ var db = { }; Tomahawk.resolver.instance = GoogleDriveResolver; + +function DumpObjectIndented(obj, indent) +{ + var result = ""; + if (indent == null) indent = ""; + + for (var property in obj) + { + var value = obj[property]; + if (typeof value == 'string') + value = "'" + value + "'"; + else if (typeof value == 'object') + { + if (value instanceof Array) + { + // Just let JS convert the Array to a string! + value = "[ " + value + " ]"; + } + else + { + // Recursive dump + // (replace " " by "\t" or something else if you prefer) + var od = DumpObjectIndented(value, indent + " "); + // If you like { on the same line as the key + //value = "{\n" + od + "\n" + indent + "}"; + // If you prefer { and } to be aligned + value = "\n" + indent + "{\n" + od + "\n" + indent + "}"; + } + } + result += indent + "'" + property + "' : " + value + ",\n"; + } + return result.replace(/,\n$/, ""); +} diff --git a/googledrive/googledrive.png b/googledrive/googledrive.png old mode 100644 new mode 100755 From 006b53b11889054d29ec15d245574462e584424d Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Thu, 21 Feb 2013 23:32:49 +0100 Subject: [PATCH 013/118] Added client_id param for ex.fm calls. --- exfm/exfm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exfm/exfm.js b/exfm/exfm.js index a129bd99b..55267b33b 100644 --- a/exfm/exfm.js +++ b/exfm/exfm.js @@ -15,7 +15,7 @@ var ExfmResolver = Tomahawk.extend(TomahawkResolver, { url += encodeURIComponent(title); - url += "?start=0&results=20"; + url += "?start=0&results=20&client_id=tomahawk"; // send request and parse it into javascript var that = this; From fc0480f2c0981fe730b1ce8723d1a2674708f2f1 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Fri, 22 Feb 2013 09:04:53 +0100 Subject: [PATCH 014/118] Intercept session error on every API call and reauth as needed. --- ampache/ampache-resolver.js | 101 ++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 46 deletions(-) diff --git a/ampache/ampache-resolver.js b/ampache/ampache-resolver.js index 1915da229..74a6e109b 100644 --- a/ampache/ampache-resolver.js +++ b/ampache/ampache-resolver.js @@ -70,6 +70,21 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { } }, + prepareHandshake: function() + { + // prepare handshake arguments + var time = Tomahawk.timestamp(); + var key = Tomahawk.sha256(this.password); + this.passphrase = Tomahawk.sha256(time + key); + + // do the handshake + this.params = { + timestamp: time, + version: 350001, + user: this.username + } + }, + init: function () { // check resolver is properly configured var userConfig = this.getUserConfig(); @@ -88,20 +103,12 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { this.password = userConfig.password; this.ampache = userConfig.ampache; - // prepare handshake arguments - var time = Tomahawk.timestamp(); - var key = Tomahawk.sha256(this.password); - var passphrase = Tomahawk.sha256(time + key); + this.prepareHandshake(); - // do the handshake - var params = { - timestamp: time, - version: 350001, - user: this.username - } try { var that = this; - this.apiCall('handshake', passphrase, params, function (xhr) { + Tomahawk.asyncRequest(this.generateUrl('handshake', this.passphrase, this.params), function (xhr){ + //this.apiCall('handshake', this.passphrase, this.params, function (xhr) { Tomahawk.log(xhr.responseText); @@ -151,7 +158,7 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { return ampacheUrl; }, - apiCallSync: function (action, auth, params) { + apiCallSync: function (action, auth, params) { //do not use this because it doesn't do re-auth var ampacheUrl = this.generateUrl(action, auth, params); return Tomahawk.syncRequest(ampacheUrl); @@ -161,7 +168,33 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { var ampacheUrl = this.generateUrl(action, auth, params); Tomahawk.log("Ampache API call: " + ampacheUrl ); - Tomahawk.asyncRequest(ampacheUrl, callback); + + var that = this; + Tomahawk.asyncRequest(ampacheUrl, function(xhr) { + var result = xhr.responseText; + Tomahawk.log(result); + + var domParser = new DOMParser(); + xmlDoc = domParser.parseFromString(result, "text/xml"); + + var error = xmlDoc.getElementsByTagName("error")[0]; + if ( typeof error != 'undefined' && + error.getAttribute("code") == "401" ) //session expired + { + that.prepareHandshake(); + var hsResponse = Tomahawk.syncRequest(this.generateUrl('handshake',this.passphrase,this.params)); + xmlDoc = domParser.parseFromString(hsResponse.responseText, "text/xml"); + + that.ready = true; + window.sessionStorage["ampacheAuth"] = that.auth; + + result = Tomahawk.syncRequest(ampacheUrl); + Tomahawk.log(result); + + xmlDoc = domParser.parseFromString(result, "text/xml"); + } + callback(xmlDoc) + }); }, ping: function () { @@ -175,11 +208,7 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { return this.element.textContent; }, - parseSongResponse: function(responseString) { - // parse xml - var domParser = new DOMParser(); - xmlDoc = domParser.parseFromString(responseString, "text/xml"); - + parseSongResponse: function(xmlDoc) { var results = new Array(); // check the repsonse var songElements = xmlDoc.getElementsByTagName("song")[0]; @@ -211,8 +240,8 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { return results; }, - parseSearchResponse: function (qid, responseString) { - var results = this.parseSongResponse(responseString); + parseSearchResponse: function (qid, xmlDoc) { + var results = this.parseSongResponse(xmlDoc); // prepare the return var return1 = { @@ -241,8 +270,8 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { }; var that = this; - this.apiCall("search_songs", AmpacheResolver.auth, params, function (xhr) { - that.parseSearchResponse(qid, xhr.responseText); + this.apiCall("search_songs", AmpacheResolver.auth, params, function (xmlDoc) { + that.parseSearchResponse(qid, xmlDoc); }); //Tomahawk.log( searchResult ); @@ -253,15 +282,7 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { var that = this; this.artistIds = {}; - this.apiCall("artists", AmpacheResolver.auth, [], function (xhr) { - var searchResult = xhr.responseText; - - Tomahawk.log(searchResult); - - // parse xml - var domParser = new DOMParser(); - xmlDoc = domParser.parseFromString(searchResult, "text/xml"); - + this.apiCall("artists", AmpacheResolver.auth, [], function (xmlDoc) { var results = []; // check the repsonse @@ -295,15 +316,7 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { filter: artistId }; - this.apiCall("artist_albums", AmpacheResolver.auth, params, function (xhr) { - var searchResult = xhr.responseText; - - Tomahawk.log( searchResult ); - - // parse xml - var domParser = new DOMParser(); - xmlDoc = domParser.parseFromString(searchResult, "text/xml"); - + this.apiCall("artist_albums", AmpacheResolver.auth, params, function (xmlDoc) { var results = []; // check the repsonse @@ -344,12 +357,8 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { filter: albumId }; - this.apiCall("album_songs", AmpacheResolver.auth, params, function (xhr) { - var searchResult = xhr.responseText; - - Tomahawk.log( searchResult ); - - var tracks_result = that.parseSongResponse(searchResult); + this.apiCall("album_songs", AmpacheResolver.auth, params, function (xmlDoc) { + var tracks_result = that.parseSongResponse(xmlDoc); tracks_result.sort( function(a,b) { if ( a.albumpos < b.albumpos ) return -1; From 82487a7381d849d81730991f6bcab6fdffee9f14 Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Fri, 22 Feb 2013 13:32:52 +0100 Subject: [PATCH 015/118] Fix in the musicManager.js --- dropbox/dropbox.js | 12 +- dropbox/musicManager.js | 237 +++++++++++++++++++++++----------------- 2 files changed, 149 insertions(+), 100 deletions(-) diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index 988f79baa..d38b277d9 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -63,11 +63,13 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { init: function () { Tomahawk.log("Beginnning INIT of Dropbox resovler"); Tomahawk.addLocalJSFile('jsOAuth-1.3.6.min.js'); - //Tomahawk.addLocalJSFile("musicManager.js"); + Tomahawk.addLocalJSFile("musicManager.js"); this.cursor = db.getItem('cursor',''); + this.oauth.init(); + musicManager.initDatabase() ; //TODO updateDatabase every 30 min (and handle if a user asked for a DB refresh before) //TODO update only if asscociated to an account @@ -95,7 +97,13 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { artists: function( qid ) { - + musicManager.initDatabase() ; + var results = this.musicManager.allArtistsQuery() ; + var return_artists = { + qid: qid, + artists: results + }; + }, albums: function( qid, artist ) diff --git a/dropbox/musicManager.js b/dropbox/musicManager.js index 6946c254b..ac7c3c0c7 100644 --- a/dropbox/musicManager.js +++ b/dropbox/musicManager.js @@ -18,118 +18,159 @@ * along with Tomahawk. If not, see . */ - initDatabase : function(userAccountParameters) + +Tomahawk.log(" Music Manager begining"); +var musicManager = { + + + dbName : "MyDropBoxDB" , + dbSQL: null ,//openDatabase(this.dbName, '1.0', 'DropBox Muic Database', 2 * 1024 * 1024) , + searchLimitResults : 500 , + + + + initDatabase : function() { - // get db infos - parse = JSON.parse(userAccountParameters) ; - var token = parse.token ; - var username = parse.username; - - var db = openDatabase(username, '1.0', 'DropBox Muic Database', 2 * 1024 * 1024); - // tx.executeSql('CREATE TABLE IF NOT EXISTS track (id integer primary key autoincrement, title , artist, album, year, genre, url)'); - db.transaction(function (transaction) { - transaction.executeSql("CREATE TABLE IF NOT EXISTS track (" + - "title VARCHAR(20) NOT NULL ," + - "artist VARCHAR(20) NOT NULL ,"+ - "album VARCHAR(20) NOT NULL ,"+ - "year VARCHAR(4) , "+ - "genre VARCHAR(15) ,"+ - "url VARCHAR(50) NOT NULL ,"); - }); - - db.transaction(function (tx) { - tx.executeSql('CREATE TABLE IF NOT EXISTS dbinfo (token primary key, username )'); - }); - - }, - - // delete the database ( token & username required ) - deleteDatabase : function(userAccountParameters) + Tomahawk.log("Sending Delta Query : "); + this.dbSQL = openDatabase(this.dbName, '1.0', 'DropBox Muic Database', 2 * 1024 * 1024); + this.dbSQL.transaction(function (tx) { + tx.executeSql('CREATE TABLE IF NOT EXISTS track (id integer primary key autoincrement, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url)'); + }); + }, + + // delete the database + flushDatabase : function() { - // TODO : erase dbinfo table ?? + this.dbSQL.transaction(function (tx) { + tx.executeSql('DROP TABLE track'); + }); }, - - // Database content management - - addTrack : function(JsonTrackDetails) + addTrack : function(tabTrackDetails) { - parse = JSON.parse(JsonTrackDetails) ; - var title = parse.title ; - var artists = parse.arist ; var concatartists ; - var albums = parse.album ; var concatalbums ; - var years = parse.year ; var concatyears ; - var genres = parse.genre ; var concatgenres ; - var url = parse.url ; + var title = tabTrackDetails["title"].trim().toLowerCase() ; + var artist = tabTrackDetails["artist"].trim().toLowerCase() ; + var album = tabTrackDetails["album"].trim().toLowerCase() ; + var albumpos = tabTrackDetails["albumpos"].trim().toLowerCase() ; + var year = tabTrackDetails["year"] ; + var genre = tabTrackDetails["genre"] ; + var size = tabTrackDetails["size"] ; + var duration = tabTrackDetails["duration"] ; + var mimetype = tabTrackDetails["mimetype"] ; + var bitrate = tabTrackDetails["bitrate"] ; + var url = tabTrackDetails["url"] ; - // Checking presence in the database before adding + // Checking presence in the database before adding // TODO : request :) - - // Multiple artist - if (artists.length > 1) { - var len = artists.length ; - for (var i = 0; i < len; i++) { - concatartists = artists[i].artist.trim().toLowerCase() + ";" - } - artists = concatartists ; - } - - // Miltiple Album - if (albums.length > 1) { - var len = albums.length ; - for (var i = 0; i < len; i++) { - concatalbums += albums[i].album.trim().toLowerCase() + ";" - } - albums = concatalbums ; - } - //Multiple Year - if (years.length > 1) { - var len = years.length - for (var i = 0; i < len; i++) { - concatyears += years[i].year.trim().toLowerCase() + ";" - } - years = concatyears ; - } - - //Multiple genre - if (var genres.length > 1) { - var len = genres.length ; - for (var i = 0; i < len; i++) { - concatgenres += genres[i].genre.trim().toLowerCase() + ";" - } - genres = concatgenres ; - } - - // Track Insertion - db.transaction(function (tx) { - tx.executeSql('INSERT INTO track (title, artist, album, year, genre, url) VALUES (?, ?, ?, ?, ?, ?)', - [title, artists, albums, years, genres, url]); - }); + + // Track Insertion + this.dbSQL.transaction(function (tx) { + tx.executeSql('INSERT INTO track (title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + [title, artists, albums, albumpos, year, genre, size, duration, mimetype, bitrate, url]); + }); + }, + + deleteTrack: function (tabTrackDetails) + { + this.dbSQL.transaction(function (tx) { + tx.executeSql('DELETE FROM track (title, artist, album, url) VALUES (?, ?, ?, ?)', + [tabTrackDetails["title"].trim().toLowerCase(), + tabTrackDetails["artist"].trim().toLowerCase(), + tabTrackDetails["album"].trim().toLowerCase() , + tabTrackDetails["url"]]); + }); }, - artistRequest : function(artist) + parseSongAttriutes: function (resultsQuery) { - artist = artist.trim().toLowerCase() ; - db.transaction(function (tx) { - tx.executeSql('SELECT album FROM track WHERE artist LIKE % "'+ artist+ '"%' , [], function (tx, results ) { - // check : results.rows.length, i; - // TODO : if the track with the required artist has severals album : explode on the ";" - // TODO : create a Json as return or string : check script Collection needs ?! - }); + var results = [] ; + var len = resultsQuery.rows.length + for (i = 0; i < len; i++) { + results[i] = []; + results[i]["title"] = resultsQuery.rows.item(i).title ; + results[i]["artist"] = resultsQuery.rows.item(i).artist ; + results[i]["album"] = resultsQuery.rows.item(i).album ; + results[i]["albumpos"] = resultsQuery.rows.item(i).albumpos ; + results[i]["year"] = resultsQuery.rows.item(i).year ; + results[i]["genre"] = resultsQuery.rows.item(i).genre ; + results[i]["size"] = resultsQuery.rows.item(i).size ; + results[i]["duration"] = resultsQuery.rows.item(i).duration ; + results[i]["mimetype"] = resultsQuery.rows.item(i).mimetype ; + results[i]["bitrate"] = resultsQuery.rows.item(i).bitrate; + results[i]["url"] = resultsQuery.rows.item(i).url ; + } + return results ; + }, + + + // Return all the artists + allArtistsQuery : function() + { + var results = []; + this.dbSQL.transaction(function (tx) { + tx.executeSql('SELECT DISTINCT artist FROM track WHERE artist LIKE % "'+ artist+ '"%' , [], function (tx, resultsQuery ) { + var len = resultsQuery.rows.length, i; + for (i = 0; i < len; i++) { + results.push (resultsQuery.rows.item(i).artist) ; + } + return results ; + }); }); }, - - // search for the artist' album - albumRequest : function() + + // return all the albums name for this artist + albumsQuery: function(artistName) { - - + var results = [] ; + artistName = artistName.trim().toLowerCase() ; + this.dbSQL.transaction(function (tx) { + tx.executeSql('SELECT DISTINCT album FROM track WHERE artist LIKE % "'+ artistName+ '"%' , [], function (tx, resultsQuery ) { + var len = resultsQuery.rows.length, i; + for (i = 0; i < len; i++) { + results.push (resultsQuery.rows.item(i).album) ; + } + return results ; + }); + }); }, - // search for the artist - trackRequest : function() + + // return all the tracks of this album + tracksQuery: function(artistName , albumName) { - - - }, \ No newline at end of file + artistName = artistName.trim().toLowerCase() ; var results = [] ; + albumName = albumName.trim().toLowerCase() ; + + this.dbSQL.transaction(function (tx) { + tx.executeSql('SELECT * FROM track WHERE album LIKE % "'+ albumName+ '"% and artist LIKE % "'+ artistName+ '"%', [], + function (tx, resultsQuery ) { + return parseSongAttriutes(resultsQuery) ; + }); + }); + }, + + // Parse Title, Album , Artist + searchQuery : function (searchString) + { + // TODO + }, + + // Only one Track matching + resolve: function(artist, album, title) + { + artistName = artistName.trim().toLowerCase() ; var results ; + albumName = albumName.trim().toLowerCase() ; + + this.dbSQL.transaction(function (tx) { + tx.executeSql('SELECT * FROM track WHERE album LIKE % "'+artist+ '"% and artist LIKE % "'+album+ '"% and title LIKE % "'+title+ '"% ', [], + function (tx, resultsQuery ) { + results = parseSongAttriutes(resultsQuery) ; // Filtre to give only onre ROW !!! + if (results.length > 0 ) return results[0] + else return []; + }); + + }); + }, + +}; From 7bcb6c04ec74be219aea1e20b8ea665a2ca3303b Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Sun, 24 Feb 2013 14:16:41 +0100 Subject: [PATCH 016/118] Actually store the new auth token, and use it. --- ampache/ampache-resolver.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ampache/ampache-resolver.js b/ampache/ampache-resolver.js index 74a6e109b..492dd5139 100644 --- a/ampache/ampache-resolver.js +++ b/ampache/ampache-resolver.js @@ -181,13 +181,20 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { if ( typeof error != 'undefined' && error.getAttribute("code") == "401" ) //session expired { + Tomahawk.log("Let's reauth!"); that.prepareHandshake(); - var hsResponse = Tomahawk.syncRequest(this.generateUrl('handshake',this.passphrase,this.params)); - xmlDoc = domParser.parseFromString(hsResponse.responseText, "text/xml"); + var hsResponse = Tomahawk.syncRequest(that.generateUrl('handshake',that.passphrase,that.params)); + Tomahawk.log(hsResponse); + xmlDoc = domParser.parseFromString(hsResponse, "text/xml"); + var roots = xmlDoc.getElementsByTagName("root"); + Tomahawk.log("Old auth token: " + that.auth); + that.auth = roots[0] === undefined ? false : Tomahawk.valueForSubNode(roots[0], "auth"); + Tomahawk.log("New auth token: " + that.auth); that.ready = true; window.sessionStorage["ampacheAuth"] = that.auth; + ampacheUrl = that.generateUrl(action,that.auth,params); result = Tomahawk.syncRequest(ampacheUrl); Tomahawk.log(result); From 8d7f0c9e8ffda490e001c6d92740425385ed43c8 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Sun, 24 Feb 2013 14:19:45 +0100 Subject: [PATCH 017/118] Remove commented-out code. --- ampache/ampache-resolver.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/ampache/ampache-resolver.js b/ampache/ampache-resolver.js index 492dd5139..da6f87d1a 100644 --- a/ampache/ampache-resolver.js +++ b/ampache/ampache-resolver.js @@ -108,8 +108,6 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { try { var that = this; Tomahawk.asyncRequest(this.generateUrl('handshake', this.passphrase, this.params), function (xhr){ - //this.apiCall('handshake', this.passphrase, this.params, function (xhr) { - Tomahawk.log(xhr.responseText); // parse the result From 7b0a779d1eaa68af6f8acf85704757dd7ee53ab1 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Sun, 24 Feb 2013 16:44:42 +0100 Subject: [PATCH 018/118] Fix callbacks in google drive (use bind function). --- googledrive/googledrive.js | 69 ++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 321c1e28d..25f4b2d7e 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -44,10 +44,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { associateClicked: function () { Tomahawk.log("Associate was clicked"); - var that = this; - this.oauth.associate(function(){ - that.updateDatabase(); - }); + this.oauth.associate(this.updateDatabase.bind(this)); }, deleteClicked: function () { @@ -66,7 +63,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { init: function () { Tomahawk.log("Beginnning INIT of Google Drive resovler"); - dbLocal.setItem("expiresOn","1"); + //dbLocal.setItem("expiresOn","1"); //Tomahawk.addLocalJSFile("musicManager.js"); this.cursor = dbLocal.getItem('cursor',''); @@ -85,10 +82,11 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { updateDatabase: function(){ var that = this; Tomahawk.log("Sending Delta Query : "); + var url = 'https://www.googleapis.com/drive/v2/changes?' +'maxResults=' + this.maxResults +'&pageToken=1'; - this.oauth.ogetJSON(url, function(){that.deltaCallback;}); + this.oauth.ogetJSON(url, this.deltaCallback.bind(this)); }, deltaCallback: function(response){ @@ -100,23 +98,20 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { for( var i = 0; i < response.items.length; i++){ var item = response.items[i]; - //Tomahawk.log(DumpObjectIndented(item)); - Tomahawk.log(item['file']['mimeType']); - Tomahawk.log(this.isMimeTypeSupported); - for(var p in this){ - Tomahawk.log(p + " : "+ this[p]); - } - if(this.isMimeTypeSupported(item['file']['mimeType'])){ - if(item.deleted === 'true'){ + + if(item['deleted']){ Tomahawk.log("Deleting : " + item['fileId']); //dbSQL.deleteTrack(item.file.id); - }else{ - //Get ID3 Tag - Tomahawk.log("Get ID3Tag from : " + item['file']['originalFilename']); - //var that = this; - //Tomahawk.getID3Tag(this.oauth.createOauthUrl(item['file']['downloadUrl']), function(tags){ - //that.onID3TagCallback(item['fileId'], tags); - //}); + }else{ + //Tomahawk.log("File : " + item['file']['title']+ " is supported : " + this.isMimeTypeSupported(item['file']['mimeType'])); + + if(this.isMimeTypeSupported(item['file']['mimeType'])){ + Tomahawk.log(DumpObjectIndented(item)); + //Get ID3 Tag + Tomahawk.log("Get ID3Tag from : " + item['file']['originalFilename']); + //var that = this; + //Tomahawk.getID3Tag(this.oauth.createOauthUrl(item['file']['downloadUrl']), this.onID3TagCallback(item['fileId'], tags).bind(this) + //); } } } @@ -154,9 +149,9 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { isMimeTypeSupported: function(mimeType) { - Tomahawk.log("Checking : "+ mimeType); + //Tomahawk.log("Checking : "+ mimeType); var mimes = [ "audio/mpeg" , "application/ogg" , "application/ogg" , "audio/x-musepack" , "audio/x-ms-wma" , "audio/mp4" , "audio/mp4" , "audio/mp4" , "audio/flac" , "audio/aiff" , "audio/aiff" , "audio/x-wavpack" ]; - return (mimes.contains(mimeType)); + return (mimes.lastIndexOf(mimeType) != -1); }, oauth: { @@ -170,7 +165,10 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //associate a new User //If the association is succesfull the previous token is discarded associate: function(callback){ - var url = this.oauthUrl + '?response_type=code&client_id=' + this.clientId + '&redirect_uri=' + this.redirectUri + '&scope=' + this.scopes; + var url = this.oauthUrl + '?response_type=code' + + '&client_id=' + this.clientId + + '&redirect_uri=' + this.redirectUri + + '&scope=' + this.scopes; this.openAcceptPage(url, callback); }, @@ -191,14 +189,14 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, opostJSON: function(url, data, success){ - var that = this; + //var that = this; if(!this.isAssociated()){ //TODO throw error NoAccountAssociated ? Tomahawk.log("REFUSED Post to "+ url + " : No account associated"); }else{ if(this.tokenExpired()){ Tomahawk.log("Token expired"); - this.getRefreshedAccessToken(function (){that.opostJSON(url, data, success);}); + this.getRefreshedAccessToken(function (){this.opostJSON(url, data, success);}.bind(this)); }else{ //TODO treat case no parameters given Tomahawk.asyncPostRequest(url, data, function (data) { @@ -209,14 +207,14 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, ogetJSON: function(url, success){ - var that = this; + //var that = this; if(!this.isAssociated()){ //TODO throw error NoAccountAssociated ? Tomahawk.log("REFUSED Get to "+ url + " : No account associated"); }else{ if(this.tokenExpired()){ Tomahawk.log("Token expired"); - this.getRefreshedAccessToken(function (){that.ogetJSON(url, success);}); + this.getRefreshedAccessToken(function (){this.ogetJSON(url, success);}.bind(this)); }else{ //TODO treat case no parameters given Tomahawk.asyncRequest(url, function (data) { @@ -267,8 +265,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { + '&redirect_uri=' + this.redirectUri; Tomahawk.asyncPostRequest(this.tokenUrl, params, function(data){ - that.onAccessTokenReceived(data, callback); - }); + this.onAccessTokenReceived(data, callback); + }.bind(this)); } if(result[0] === 'Denied error'){ @@ -292,8 +290,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { dbLocal.setItem('expiresOn',this.expiresOn); if(! (typeof callback === 'undefined')){ - callback.call(Tomahawk.resolver.instance); - //callback(); + callback(); } }, @@ -311,9 +308,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { dbLocal.setItem('expiresOn',this.expiresOn); if(! (typeof callback === 'undefined')){ - Tomahawk.log("Calling..."); - callback.call(Tomahawk.resolver.instance); - //callback(); + callback(); } }, @@ -329,8 +324,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { + '&client_secret=' + this.clientSecret; Tomahawk.asyncPostRequest(this.tokenUrl, params, function(data){ - that.onRefreshedTokenReceived(data, callback); - }); + this.onRefreshedTokenReceived(data, callback); + }.bind(this)); }, queryFailure: function(data) { From cd5a2528c82e197a6839b4d5a6e26b66e26f11f4 Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Sun, 24 Feb 2013 16:55:56 +0100 Subject: [PATCH 019/118] working version of music Manager --- dropbox/dropbox.js | 1 - dropbox/musicManager.js | 247 +++++++++++++++++++++---------- googledrive/googledrive.js | 34 ++++- googledrive/musicManager.js | 279 ++++++++++++++++++++++++++++++++++++ 4 files changed, 482 insertions(+), 79 deletions(-) create mode 100644 googledrive/musicManager.js diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index 42b518b89..8982bd097 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -67,7 +67,6 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { this.cursor = db.getItem('cursor',''); - this.oauth.init(); musicManager.initDatabase() ; diff --git a/dropbox/musicManager.js b/dropbox/musicManager.js index ac7c3c0c7..94430eea4 100644 --- a/dropbox/musicManager.js +++ b/dropbox/musicManager.js @@ -20,38 +20,54 @@ Tomahawk.log(" Music Manager begining"); -var musicManager = { +var musicManager = { dbName : "MyDropBoxDB" , - dbSQL: null ,//openDatabase(this.dbName, '1.0', 'DropBox Muic Database', 2 * 1024 * 1024) , + dbSQL: null , + //dbSQL: openDatabase(this.dbName, '1.0', 'DropBox Muic Database', 2 * 1024 * 1024), searchLimitResults : 500 , - - - - initDatabase : function() + + initDatabase : function() { - Tomahawk.log("Sending Delta Query : "); - this.dbSQL = openDatabase(this.dbName, '1.0', 'DropBox Muic Database', 2 * 1024 * 1024); + // TODO : choose the id : url / device ID / combo of columns ? + Tomahawk.log("Init webSQL Db : "); + if (!this.dbSQL) this.dbSQL = openDatabase(this.dbName, '1.0', 'DropBox Muic Database', 2 * 1024 * 1024) ; this.dbSQL.transaction(function (tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS track (id integer primary key autoincrement, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url)'); }); }, - + + showDatabase: function() + { + this.dbSQL.transaction(function (tx) { + tx.executeSql('SELECT * FROM track', [], function (tx, resultsQuery ) { + var results = musicManager.parseSongAttriutes(resultsQuery) ; + var len = results.length ; var i = 0 ; + for (i ; i < len ; i ++) { + Tomahawk.log("Displaying Content of Database"); + Tomahawk.log("title: "+results[i].title+", artist: "+results[i].artist+", album: "+results[i].album+", url: "+results[i].url+""); + } + }); + }); + }, + // delete the database flushDatabase : function() { this.dbSQL.transaction(function (tx) { tx.executeSql('DROP TABLE track'); }); + musicManager.initDatabase() ; + Tomahawk.log("webSQL db cleaned out"); }, addTrack : function(tabTrackDetails) { - var title = tabTrackDetails["title"].trim().toLowerCase() ; - var artist = tabTrackDetails["artist"].trim().toLowerCase() ; - var album = tabTrackDetails["album"].trim().toLowerCase() ; - var albumpos = tabTrackDetails["albumpos"].trim().toLowerCase() ; + var title = tabTrackDetails["title"]; + var artist = tabTrackDetails["artist"]; + var album = tabTrackDetails["album"] ; + var albumpos = tabTrackDetails["albumpos"]; var year = tabTrackDetails["year"] ; var genre = tabTrackDetails["genre"] ; var size = tabTrackDetails["size"] ; @@ -63,114 +79,201 @@ var musicManager = { // Checking presence in the database before adding // TODO : request :) - // Track Insertion + // Track Insertion this.dbSQL.transaction(function (tx) { tx.executeSql('INSERT INTO track (title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', - [title, artists, albums, albumpos, year, genre, size, duration, mimetype, bitrate, url]); + [title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url]); }); + Tomahawk.log("Insertion inside "+this.dbName+""); }, deleteTrack: function (tabTrackDetails) { this.dbSQL.transaction(function (tx) { tx.executeSql('DELETE FROM track (title, artist, album, url) VALUES (?, ?, ?, ?)', - [tabTrackDetails["title"].trim().toLowerCase(), - tabTrackDetails["artist"].trim().toLowerCase(), - tabTrackDetails["album"].trim().toLowerCase() , + [tabTrackDetails["title"], + tabTrackDetails["artist"], + tabTrackDetails["album"] , tabTrackDetails["url"]]); }); + Tomahawk.log("Deletion inside "+this.dbName+""); }, parseSongAttriutes: function (resultsQuery) { - var results = [] ; + //Tomahawk.log("parsing Attribute"); + var results = [] ; var song ; var len = resultsQuery.rows.length for (i = 0; i < len; i++) { - results[i] = []; - results[i]["title"] = resultsQuery.rows.item(i).title ; - results[i]["artist"] = resultsQuery.rows.item(i).artist ; - results[i]["album"] = resultsQuery.rows.item(i).album ; - results[i]["albumpos"] = resultsQuery.rows.item(i).albumpos ; - results[i]["year"] = resultsQuery.rows.item(i).year ; - results[i]["genre"] = resultsQuery.rows.item(i).genre ; - results[i]["size"] = resultsQuery.rows.item(i).size ; - results[i]["duration"] = resultsQuery.rows.item(i).duration ; - results[i]["mimetype"] = resultsQuery.rows.item(i).mimetype ; - results[i]["bitrate"] = resultsQuery.rows.item(i).bitrate; - results[i]["url"] = resultsQuery.rows.item(i).url ; + song = { + title: resultsQuery.rows.item(i).title , + artist: resultsQuery.rows.item(i).artist , + album: resultsQuery.rows.item(i).album , + albumpos: resultsQuery.rows.item(i).albumpos , + year: resultsQuery.rows.item(i).year , + genre: resultsQuery.rows.item(i).genre , + size: resultsQuery.rows.item(i).size , + duration: resultsQuery.rows.item(i).duration , + mimetype: resultsQuery.rows.item(i).mimetype , + bitrate: resultsQuery.rows.item(i).bitrate, + url: resultsQuery.rows.item(i).url , + }; + results.push(song) ; } return results ; }, - // Return all the artists - allArtistsQuery : function() + allArtistsQuery : function(callBack) { - var results = []; + var results = []; this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT DISTINCT artist FROM track WHERE artist LIKE % "'+ artist+ '"%' , [], function (tx, resultsQuery ) { - var len = resultsQuery.rows.length, i; - for (i = 0; i < len; i++) { - results.push (resultsQuery.rows.item(i).artist) ; - } - return results ; - }); + tx.executeSql('SELECT DISTINCT artist FROM track', [], function (tx, resultsQuery ) { + var len = resultsQuery.rows.length, i; + Tomahawk.log("Number of artists results : "+ len); + for (i = 0; i < len; i++) { + results.push(resultsQuery.rows.item(i).artist) ; + } + callBack(results); + }); }); }, // return all the albums name for this artist - albumsQuery: function(artistName) + albumsQuery: function(artist,callBack) { - var results = [] ; - artistName = artistName.trim().toLowerCase() ; - this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT DISTINCT album FROM track WHERE artist LIKE % "'+ artistName+ '"%' , [], function (tx, resultsQuery ) { - var len = resultsQuery.rows.length, i; - for (i = 0; i < len; i++) { - results.push (resultsQuery.rows.item(i).album) ; - } - return results ; - }); + var results = [] ; + this.dbSQL.transaction(function (tx) { + tx.executeSql('SELECT DISTINCT album FROM track WHERE artist=?', [artist], function (tx, resultsQuery ) { + var len = resultsQuery.rows.length, i; + //Tomahawk.log("Number of albums results : "+ len); + for (i = 0; i < len; i++) { + results.push (resultsQuery.rows.item(i).album) ; + } + callBack(results); + }); }); }, - - // return all the tracks of this album - tracksQuery: function(artistName , albumName) + // return all the tracks of this artist' album + tracksQuery: function(artist , album, callBack) { - artistName = artistName.trim().toLowerCase() ; var results = [] ; - albumName = albumName.trim().toLowerCase() ; - this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT * FROM track WHERE album LIKE % "'+ albumName+ '"% and artist LIKE % "'+ artistName+ '"%', [], + tx.executeSql('SELECT * FROM track WHERE artist=? and album=?', [artist,album], function (tx, resultsQuery ) { - return parseSongAttriutes(resultsQuery) ; + var results = musicManager.parseSongAttriutes(resultsQuery) ; + //Tomahawk.log("Number of results : "+results.length); + callBack(results) ; }); }); }, // Parse Title, Album , Artist - searchQuery : function (searchString) + searchQuery : function (searchString,callBack) { // TODO }, // Only one Track matching - resolve: function(artist, album, title) - { - artistName = artistName.trim().toLowerCase() ; var results ; - albumName = albumName.trim().toLowerCase() ; - + resolve: function(artist, album, title, callBack) + { + var results = [] ; this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT * FROM track WHERE album LIKE % "'+artist+ '"% and artist LIKE % "'+album+ '"% and title LIKE % "'+title+ '"% ', [], - function (tx, resultsQuery ) { - results = parseSongAttriutes(resultsQuery) ; // Filtre to give only onre ROW !!! - if (results.length > 0 ) return results[0] - else return []; + tx.executeSql('SELECT * FROM track WHERE album=? and artist=? and title=? ', [album,artist,title], // Select first or limit mechanisim ? + function (tx, resultsQuery ) { + var results = musicManager.parseSongAttriutes(resultsQuery) ; + //Tomahawk.log("Number of track results for resolve : "+results.length); + // Filter to give only ONE row + callBack(results[0]) ; }); - }); }, +}; + // Testing Object + var musicManagerTester = { tabTrackDetails: [] , + init: function() { + this.tabTrackDetails = ["title", "artist", "album", "albumpos","year","genre" ,"size","duration","mimetype","bitrate","url" ] ; + // OMG Javascript SUCKS ! ! ! + this.tabTrackDetails["title"] = "title1" ; + this.tabTrackDetails["artist"] = "artist1" ; + this.tabTrackDetails["album"] = "album1" ; + this.tabTrackDetails["albumpos"] = "Track1" ; + this.tabTrackDetails["year"] = "1990" ; + this.tabTrackDetails["genre"] = "Jazz" ; + this.tabTrackDetails["size"] = "1024" ; + this.tabTrackDetails["duration"] = "3:06" ; + this.tabTrackDetails["mimetype"] = "mp3" ; + this.tabTrackDetails["bitrate"] = "128 kps" ; + this.tabTrackDetails["url"] = "http://dropbox.com/user/jimmy/music/mysong.mp3" ; + }, + + populateDatabase: function (rows){ + musicManager.flushDatabase() ; + //this.tabTrackDetails = ["title", "artist", "album", "albumpos","year","genre" ,"size","duration","mimetype","bitrate","url" ] ; + var i = 0 ; + for (i ; i < rows ; i++) { + for (index in this.tabTrackDetails){ + this.tabTrackDetails[index] = index+i ; + } + musicManager.addTrack(this.tabTrackDetails) ; + } + }, + + showDatabase: function() { + musicManager.showDatabase() ; + }, + + addTrackTest: function (){ + musicManager.addTrack(this.tabTrackDetails) ; + }, + + deleteTrackTest: function() { + musicManager.deleteTrack(this.tabTrackDetails) ; + }, + + flushDatabaseTest: function() { + musicManager.flushDatabase() ; + }, + + resolveTest: function() { + var artist = this.tabTrackDetails["artist"]; + var album = this.tabTrackDetails["album"]; + var title = this.tabTrackDetails["title"]; + musicManager.resolve(artist,album,title, function(results){ + Tomahawk.log("Return songs title "+results.title); + }); + }, + + allArtistsQueryTest: function() { + musicManager.allArtistsQuery(function(results){ + var len = results.length ; var i = 0; + for (i ; i < len ; i++) { + Tomahawk.log("Return artist name num "+i+" : "+results[i]); + } + }); + }, + + tracksQueryTest: function() { + var artist = this.tabTrackDetails["artist"]; + var album = this.tabTrackDetails["album"]; + + musicManager.tracksQuery(artist, album , function(results){ + var len = results.length ; var i = 0; + for (i ; i < len ; i++) { + Tomahawk.log("Return track title name num "+i+" : "+results[i].title); + } + }); + }, + + albumsQueryTest: function() { + var artist = this.tabTrackDetails["artist"]; + musicManager.albumsQuery(artist, function(results){ + var len = results.length ; var i = 0; + for (i ; i < len ; i++) { + Tomahawk.log("Return album title name num "+i+" : "+results[i]); + } + }); + }, }; diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 321c1e28d..c6fa91b31 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -66,13 +66,16 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { init: function () { Tomahawk.log("Beginnning INIT of Google Drive resovler"); - dbLocal.setItem("expiresOn","1"); - //Tomahawk.addLocalJSFile("musicManager.js"); + //dbLocal.setItem("expiresOn","1"); + Tomahawk.addLocalJSFile("musicManager.js"); this.cursor = dbLocal.getItem('cursor',''); this.oauth.init(); + musicManager.initDatabase() ; + this.googleDriveMusicManagerTests() ; + Tomahawk.log(typeof this.expiresOn ); Tomahawk.log((Math.floor(Date.now()/1000) ).toString()); @@ -81,7 +84,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { this.updateDatabase(); }, - + updateDatabase: function(){ var that = this; Tomahawk.log("Sending Delta Query : "); @@ -101,8 +104,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { for( var i = 0; i < response.items.length; i++){ var item = response.items[i]; //Tomahawk.log(DumpObjectIndented(item)); - Tomahawk.log(item['file']['mimeType']); - Tomahawk.log(this.isMimeTypeSupported); + //Tomahawk.log(item['file']['mimeType']); + //Tomahawk.log(this.isMimeTypeSupported); for(var p in this){ Tomahawk.log(p + " : "+ this[p]); } @@ -144,6 +147,24 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { { }, + + googleDriveMusicManagerTests: function() { + //~ musicManagerTester.flushDatabaseTest() ; + //~ musicManagerTester.init() ; + //~ musicManagerTester.addTrackTest() ; + //~ musicManagerTester.deleteTrackTest() ; + //~ musicManagerTester.resolveTest() ; + //~ musicManagerTester.allArtistsQueryTest() ; + //~ musicManagerTester.tracksQueryTest() ; + //~ musicManagerTester.albumsQueryTest() ; + //~ musicManagerTester.populateDatabase(9) ; + //~ musicManagerTester.showDatabase() ; + }, + + getID3Tag: function(fileUrl, callback) + { + + }, onID3TagCallback: function(fileId, tags) { @@ -349,11 +370,12 @@ var dbLocal = { result = (result == null)? defaultResponse : result; Tomahawk.log("DB: loaded "+key+" : '"+ result+"' "); - + return result; } }; + Tomahawk.resolver.instance = GoogleDriveResolver; function DumpObjectIndented(obj, indent) diff --git a/googledrive/musicManager.js b/googledrive/musicManager.js new file mode 100644 index 000000000..6a5d403fe --- /dev/null +++ b/googledrive/musicManager.js @@ -0,0 +1,279 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012, mack-t + * Copyright 2012, Peter Loron + * Copyright 2013, Teo Mrnjavac + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + + +Tomahawk.log(" Music Manager begining"); + +var musicManager = { + + dbName : "GoogleDriveDB" , + dbSQL: null , + //dbSQL: openDatabase(this.dbName, '1.0', 'DropBox Muic Database', 2 * 1024 * 1024), + searchLimitResults : 500 , + + initDatabase : function() + { + // TODO : choose the id : url / device ID / combo of columns ? + Tomahawk.log("Init webSQL Db : "); + if (!this.dbSQL) this.dbSQL = openDatabase(this.dbName, '1.0', 'DropBox Muic Database', 2 * 1024 * 1024) ; + this.dbSQL.transaction(function (tx) { + tx.executeSql('CREATE TABLE IF NOT EXISTS track (id integer primary key autoincrement, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url)'); + }); + }, + + showDatabase: function() + { + this.dbSQL.transaction(function (tx) { + tx.executeSql('SELECT * FROM track', [], function (tx, resultsQuery ) { + var results = musicManager.parseSongAttriutes(resultsQuery) ; + var len = results.length ; var i = 0 ; + for (i ; i < len ; i ++) { + Tomahawk.log("Displaying Content of Database"); + Tomahawk.log("title: "+results[i].title+", artist: "+results[i].artist+", album: "+results[i].album+", url: "+results[i].url+""); + } + }); + }); + }, + + // delete the database + flushDatabase : function() + { + this.dbSQL.transaction(function (tx) { + tx.executeSql('DROP TABLE track'); + }); + musicManager.initDatabase() ; + Tomahawk.log("webSQL db cleaned out"); + }, + + addTrack : function(tabTrackDetails) + { + var title = tabTrackDetails["title"]; + var artist = tabTrackDetails["artist"]; + var album = tabTrackDetails["album"] ; + var albumpos = tabTrackDetails["albumpos"]; + var year = tabTrackDetails["year"] ; + var genre = tabTrackDetails["genre"] ; + var size = tabTrackDetails["size"] ; + var duration = tabTrackDetails["duration"] ; + var mimetype = tabTrackDetails["mimetype"] ; + var bitrate = tabTrackDetails["bitrate"] ; + var url = tabTrackDetails["url"] ; + + // Checking presence in the database before adding + // TODO : request :) + + // Track Insertion + this.dbSQL.transaction(function (tx) { + tx.executeSql('INSERT INTO track (title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + [title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url]); + }); + Tomahawk.log("Insertion inside "+this.dbName+""); + }, + + deleteTrack: function (tabTrackDetails) + { + this.dbSQL.transaction(function (tx) { + tx.executeSql('DELETE FROM track (title, artist, album, url) VALUES (?, ?, ?, ?)', + [tabTrackDetails["title"], + tabTrackDetails["artist"], + tabTrackDetails["album"] , + tabTrackDetails["url"]]); + }); + Tomahawk.log("Deletion inside "+this.dbName+""); + }, + + + parseSongAttriutes: function (resultsQuery) + { + //Tomahawk.log("parsing Attribute"); + var results = [] ; var song ; + var len = resultsQuery.rows.length + for (i = 0; i < len; i++) { + song = { + title: resultsQuery.rows.item(i).title , + artist: resultsQuery.rows.item(i).artist , + album: resultsQuery.rows.item(i).album , + albumpos: resultsQuery.rows.item(i).albumpos , + year: resultsQuery.rows.item(i).year , + genre: resultsQuery.rows.item(i).genre , + size: resultsQuery.rows.item(i).size , + duration: resultsQuery.rows.item(i).duration , + mimetype: resultsQuery.rows.item(i).mimetype , + bitrate: resultsQuery.rows.item(i).bitrate, + url: resultsQuery.rows.item(i).url , + }; + results.push(song) ; + } + return results ; + }, + + // Return all the artists + allArtistsQuery : function(callBack) + { + var results = []; + this.dbSQL.transaction(function (tx) { + tx.executeSql('SELECT DISTINCT artist FROM track', [], function (tx, resultsQuery ) { + var len = resultsQuery.rows.length, i; + Tomahawk.log("Number of artists results : "+ len); + for (i = 0; i < len; i++) { + results.push(resultsQuery.rows.item(i).artist) ; + } + callBack(results); + }); + }); + }, + + // return all the albums name for this artist + albumsQuery: function(artist,callBack) + { + var results = [] ; + this.dbSQL.transaction(function (tx) { + tx.executeSql('SELECT DISTINCT album FROM track WHERE artist=?', [artist], function (tx, resultsQuery ) { + var len = resultsQuery.rows.length, i; + //Tomahawk.log("Number of albums results : "+ len); + for (i = 0; i < len; i++) { + results.push (resultsQuery.rows.item(i).album) ; + } + callBack(results); + }); + }); + }, + + // return all the tracks of this artist' album + tracksQuery: function(artist , album, callBack) + { + this.dbSQL.transaction(function (tx) { + tx.executeSql('SELECT * FROM track WHERE artist=? and album=?', [artist,album], + function (tx, resultsQuery ) { + var results = musicManager.parseSongAttriutes(resultsQuery) ; + //Tomahawk.log("Number of results : "+results.length); + callBack(results) ; + }); + }); + }, + + // Parse Title, Album , Artist + searchQuery : function (searchString,callBack) + { + // TODO + }, + + // Only one Track matching + resolve: function(artist, album, title, callBack) + { + var results = [] ; + this.dbSQL.transaction(function (tx) { + tx.executeSql('SELECT * FROM track WHERE album=? and artist=? and title=? ', [album,artist,title], // Select first or limit mechanisim ? + function (tx, resultsQuery ) { + var results = musicManager.parseSongAttriutes(resultsQuery) ; + //Tomahawk.log("Number of track results for resolve : "+results.length); + // Filter to give only ONE row + callBack(results[0]) ; + }); + }); + }, +}; + + // Testing Object + var musicManagerTester = { tabTrackDetails: [] , + init: function() { + this.tabTrackDetails = ["title", "artist", "album", "albumpos","year","genre" ,"size","duration","mimetype","bitrate","url" ] ; + // OMG Javascript SUCKS ! ! ! + this.tabTrackDetails["title"] = "title1" ; + this.tabTrackDetails["artist"] = "artist1" ; + this.tabTrackDetails["album"] = "album1" ; + this.tabTrackDetails["albumpos"] = "Track1" ; + this.tabTrackDetails["year"] = "1990" ; + this.tabTrackDetails["genre"] = "Jazz" ; + this.tabTrackDetails["size"] = "1024" ; + this.tabTrackDetails["duration"] = "3:06" ; + this.tabTrackDetails["mimetype"] = "mp3" ; + this.tabTrackDetails["bitrate"] = "128 kps" ; + this.tabTrackDetails["url"] = "http://dropbox.com/user/jimmy/music/mysong.mp3" ; + }, + + populateDatabase: function (rows){ + musicManager.flushDatabase() ; + //this.tabTrackDetails = ["title", "artist", "album", "albumpos","year","genre" ,"size","duration","mimetype","bitrate","url" ] ; + var i = 0 ; + for (i ; i < rows ; i++) { + for (index in this.tabTrackDetails){ + this.tabTrackDetails[index] = index+i ; + } + musicManager.addTrack(this.tabTrackDetails) ; + } + }, + + showDatabase: function() { + musicManager.showDatabase() ; + }, + + addTrackTest: function (){ + musicManager.addTrack(this.tabTrackDetails) ; + }, + + deleteTrackTest: function() { + musicManager.deleteTrack(this.tabTrackDetails) ; + }, + + flushDatabaseTest: function() { + musicManager.flushDatabase() ; + }, + + resolveTest: function() { + var artist = this.tabTrackDetails["artist"]; + var album = this.tabTrackDetails["album"]; + var title = this.tabTrackDetails["title"]; + musicManager.resolve(artist,album,title, function(results){ + Tomahawk.log("Return songs title "+results.title); + }); + }, + + allArtistsQueryTest: function() { + musicManager.allArtistsQuery(function(results){ + var len = results.length ; var i = 0; + for (i ; i < len ; i++) { + Tomahawk.log("Return artist name num "+i+" : "+results[i]); + } + }); + }, + + tracksQueryTest: function() { + var artist = this.tabTrackDetails["artist"]; + var album = this.tabTrackDetails["album"]; + + musicManager.tracksQuery(artist, album , function(results){ + var len = results.length ; var i = 0; + for (i ; i < len ; i++) { + Tomahawk.log("Return track title name num "+i+" : "+results[i].title); + } + }); + }, + + albumsQueryTest: function() { + var artist = this.tabTrackDetails["artist"]; + musicManager.albumsQuery(artist, function(results){ + var len = results.length ; var i = 0; + for (i ; i < len ; i++) { + Tomahawk.log("Return album title name num "+i+" : "+results[i]); + } + }); + }, +}; From 63433eca39a54dbcdef211b97709081d33d5b9e2 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Sun, 24 Feb 2013 17:09:00 +0100 Subject: [PATCH 020/118] Add license to Google drive, dropbox and musicManager.js --- dropbox/dropbox.js | 18 ++++++++++++++++++ dropbox/musicManager.js | 4 +--- googledrive/googledrive.js | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index 8982bd097..3718cd3e6 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -1,3 +1,21 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2013, Rémi Benoit + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + var DropboxResolver = Tomahawk.extend(TomahawkResolver, { uid: '', cursor: '', diff --git a/dropbox/musicManager.js b/dropbox/musicManager.js index 94430eea4..7070407b0 100644 --- a/dropbox/musicManager.js +++ b/dropbox/musicManager.js @@ -1,8 +1,6 @@ /* === This file is part of Tomahawk Player - === * - * Copyright 2012, mack-t - * Copyright 2012, Peter Loron - * Copyright 2013, Teo Mrnjavac + * Copyright 2013, Franck Arrecot * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index fb79c61b1..92acddfed 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -1,3 +1,21 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2013, Rémi Benoit + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { uid: '', cursor: '', From 905d7ca1c40c9cb60e619f7ce241c097b0cc3994 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Sun, 24 Feb 2013 19:14:12 +0100 Subject: [PATCH 021/118] Asyncify. --- ampache/ampache-resolver.js | 40 +++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/ampache/ampache-resolver.js b/ampache/ampache-resolver.js index da6f87d1a..fc7f9fa16 100644 --- a/ampache/ampache-resolver.js +++ b/ampache/ampache-resolver.js @@ -176,29 +176,35 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { xmlDoc = domParser.parseFromString(result, "text/xml"); var error = xmlDoc.getElementsByTagName("error")[0]; + if( 1 ) if ( typeof error != 'undefined' && error.getAttribute("code") == "401" ) //session expired { Tomahawk.log("Let's reauth!"); that.prepareHandshake(); - var hsResponse = Tomahawk.syncRequest(that.generateUrl('handshake',that.passphrase,that.params)); - Tomahawk.log(hsResponse); - xmlDoc = domParser.parseFromString(hsResponse, "text/xml"); - var roots = xmlDoc.getElementsByTagName("root"); - Tomahawk.log("Old auth token: " + that.auth); - that.auth = roots[0] === undefined ? false : Tomahawk.valueForSubNode(roots[0], "auth"); - Tomahawk.log("New auth token: " + that.auth); - - that.ready = true; - window.sessionStorage["ampacheAuth"] = that.auth; - - ampacheUrl = that.generateUrl(action,that.auth,params); - result = Tomahawk.syncRequest(ampacheUrl); - Tomahawk.log(result); - - xmlDoc = domParser.parseFromString(result, "text/xml"); + Tomahawk.asyncRequest(that.generateUrl('handshake',that.passphrase,that.params), function(xhr){ + var hsResponse = xhr.responseText; + Tomahawk.log(hsResponse); + xmlDoc = domParser.parseFromString(hsResponse, "text/xml"); + var roots = xmlDoc.getElementsByTagName("root"); + Tomahawk.log("Old auth token: " + that.auth); + that.auth = roots[0] === undefined ? false : Tomahawk.valueForSubNode(roots[0], "auth"); + Tomahawk.log("New auth token: " + that.auth); + + that.ready = true; + window.sessionStorage["ampacheAuth"] = that.auth; + + ampacheUrl = that.generateUrl(action,that.auth,params); + Tomahawk.asyncRequest(ampacheUrl, function(xhr){ + result = xhr.responseText; + Tomahawk.log(result); + xmlDoc = domParser.parseFromString(result, "text/xml"); + callback(xmlDoc); + }); + }); } - callback(xmlDoc) + else + callback(xmlDoc) }); }, From ed8afb135a374502c14b68e37dd28746d7cdbaa3 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 26 Feb 2013 10:51:21 +0100 Subject: [PATCH 022/118] Added track count support to Ampache. --- ampache/ampache-resolver.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ampache/ampache-resolver.js b/ampache/ampache-resolver.js index fc7f9fa16..476324c3b 100644 --- a/ampache/ampache-resolver.js +++ b/ampache/ampache-resolver.js @@ -116,6 +116,9 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { var roots = xmlDoc.getElementsByTagName("root"); that.auth = roots[0] === undefined ? false : Tomahawk.valueForSubNode(roots[0], "auth"); var pingInterval = parseInt(roots[0] === undefined ? 0 : Tomahawk.valueForSubNode(roots[0], "session_length")) * 1000; + var trackCount = roots[0] === undefined ? (-1) : Tomahawk.valueForSubNode(roots[0], "songs"); + if ( trackCount > -1 ) + that.trackCount = parseInt(trackCount); // inform the user if something went wrong if (!that.auth) { @@ -190,6 +193,9 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.log("Old auth token: " + that.auth); that.auth = roots[0] === undefined ? false : Tomahawk.valueForSubNode(roots[0], "auth"); Tomahawk.log("New auth token: " + that.auth); + var trackCount = roots[0] === undefined ? (-1) : Tomahawk.valueForSubNode(roots[0], "songs"); + if ( trackCount > -1 ) + that.trackCount = parseInt(trackCount); that.ready = true; window.sessionStorage["ampacheAuth"] = that.auth; @@ -396,10 +402,16 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { var desc = this.ampache.replace(/^http:\/\//,"") .replace(/\/$/, "") .replace(/\/remote.php\/ampache/, ""); - return { + + var return_object = { prettyname: "Ampache", - description: desc + description: desc, }; + + if ( typeof( this.trackCount ) !== 'undefined' ) + return_object["trackcount"] = this.trackCount; + + return return_object; } }); From 53ccdf7e378e5342cb5c7b2dc7223affa49b25b4 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 26 Feb 2013 11:03:26 +0100 Subject: [PATCH 023/118] DRY in Ampache handshake processing. --- ampache/ampache-resolver.js | 48 ++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/ampache/ampache-resolver.js b/ampache/ampache-resolver.js index 476324c3b..59e32516b 100644 --- a/ampache/ampache-resolver.js +++ b/ampache/ampache-resolver.js @@ -85,6 +85,25 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { } }, + applyHandshake: function(xmlDoc) + { + var roots = xmlDoc.getElementsByTagName("root"); + Tomahawk.log("Old auth token: " + this.auth); + this.auth = roots[0] === undefined ? false : Tomahawk.valueForSubNode(roots[0], "auth"); + Tomahawk.log("New auth token: " + this.auth); + var pingInterval = parseInt(roots[0] === undefined ? 0 : Tomahawk.valueForSubNode(roots[0], "session_length")) * 1000; + var trackCount = roots[0] === undefined ? (-1) : Tomahawk.valueForSubNode(roots[0], "songs"); + if ( trackCount > -1 ) + this.trackCount = parseInt(trackCount); + + // all fine, set the resolver to ready state + this.ready = true; + window.sessionStorage["ampacheAuth"] = this.auth; + + // setup pingTimer + if (pingInterval) window.setInterval(this.ping, pingInterval - 60); + }, + init: function () { // check resolver is properly configured var userConfig = this.getUserConfig(); @@ -113,25 +132,14 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { // parse the result var domParser = new DOMParser(); xmlDoc = domParser.parseFromString(xhr.responseText, "text/xml"); - var roots = xmlDoc.getElementsByTagName("root"); - that.auth = roots[0] === undefined ? false : Tomahawk.valueForSubNode(roots[0], "auth"); - var pingInterval = parseInt(roots[0] === undefined ? 0 : Tomahawk.valueForSubNode(roots[0], "session_length")) * 1000; - var trackCount = roots[0] === undefined ? (-1) : Tomahawk.valueForSubNode(roots[0], "songs"); - if ( trackCount > -1 ) - that.trackCount = parseInt(trackCount); + + that.applyHandshake(xmlDoc); // inform the user if something went wrong if (!that.auth) { Tomahawk.log("INVALID HANDSHAKE RESPONSE: " + xhr.responseText); } - // all fine, set the resolver to ready state - that.ready = true; - window.sessionStorage["ampacheAuth"] = that.auth; - - // setup pingTimer - if (pingInterval) window.setInterval(that.ping, pingInterval - 60); - Tomahawk.log("Ampache Resolver properly initialised!"); Tomahawk.reportCapabilities( TomahawkResolverCapability.Browsable | TomahawkResolverCapability.AccountFactory ); @@ -179,7 +187,7 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { xmlDoc = domParser.parseFromString(result, "text/xml"); var error = xmlDoc.getElementsByTagName("error")[0]; - if( 1 ) + if ( typeof error != 'undefined' && error.getAttribute("code") == "401" ) //session expired { @@ -189,17 +197,9 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { var hsResponse = xhr.responseText; Tomahawk.log(hsResponse); xmlDoc = domParser.parseFromString(hsResponse, "text/xml"); - var roots = xmlDoc.getElementsByTagName("root"); - Tomahawk.log("Old auth token: " + that.auth); - that.auth = roots[0] === undefined ? false : Tomahawk.valueForSubNode(roots[0], "auth"); - Tomahawk.log("New auth token: " + that.auth); - var trackCount = roots[0] === undefined ? (-1) : Tomahawk.valueForSubNode(roots[0], "songs"); - if ( trackCount > -1 ) - that.trackCount = parseInt(trackCount); - - that.ready = true; - window.sessionStorage["ampacheAuth"] = that.auth; + that.applyHandshake(xmlDoc); + //reauth done, let's retry the API call ampacheUrl = that.generateUrl(action,that.auth,params); Tomahawk.asyncRequest(ampacheUrl, function(xhr){ result = xhr.responseText; From db1b2aaaa6025a0a0504f154c55423451bb13e16 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Tue, 26 Feb 2013 11:22:45 +0100 Subject: [PATCH 024/118] Cursor support and multiple delta pages on Google drive resolver. --- googledrive/googledrive.js | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 92acddfed..f3ee9eeb4 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -19,7 +19,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { uid: '', cursor: '', - maxResults: '15000', + maxResults: '15', settings: { name: 'Google Drive', @@ -84,30 +84,31 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //dbLocal.setItem("expiresOn","1"); Tomahawk.addLocalJSFile("musicManager.js"); - + this.cursor = dbLocal.getItem('cursor',''); + Tomahawk.log("That is cursor : "+ this.cursor); this.oauth.init(); - musicManager.initDatabase() ; + this.googleDriveMusicManagerTests() ; - Tomahawk.log(typeof this.expiresOn ); Tomahawk.log((Math.floor(Date.now()/1000) ).toString()); - //TODO updateDatabase every 30 min (and handle if a user asked for a DB refresh before) - //TODO update only if asscociated to an account + //TODO updateDatabase when? this.updateDatabase(); }, - updateDatabase: function(){ - var that = this; + updateDatabase: function(pageToken){ Tomahawk.log("Sending Delta Query : "); + pageToken = pageToken || (this.cursor === '' ? '1' : this.cursor); var url = 'https://www.googleapis.com/drive/v2/changes?' +'maxResults=' + this.maxResults - +'&pageToken=1'; + +'&pageToken=' + pageToken; + + Tomahawk.log("URL used : "+ url); this.oauth.ogetJSON(url, this.deltaCallback.bind(this)); }, @@ -116,11 +117,12 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.log("Delta returned!"); Tomahawk.log("selfLink : " + response.selfLink); Tomahawk.log("nextPageToken : " + response.nextPageToken); - //Tomahawk.log(DumpObjectIndented(response.items)); + Tomahawk.log("largestChangeId : " + response.largestChangeId); + //Tomahawk.log(DumpObjectIndented(response)); + for( var i = 0; i < response.items.length; i++){ var item = response.items[i]; - if(item['deleted']){ Tomahawk.log("Deleting : " + item['fileId']); //dbSQL.deleteTrack(item.file.id); @@ -128,15 +130,21 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //Tomahawk.log("File : " + item['file']['title']+ " is supported : " + this.isMimeTypeSupported(item['file']['mimeType'])); if(this.isMimeTypeSupported(item['file']['mimeType'])){ - Tomahawk.log(DumpObjectIndented(item)); + //Tomahawk.log(DumpObjectIndented(item)); //Get ID3 Tag Tomahawk.log("Get ID3Tag from : " + item['file']['originalFilename']); - //var that = this; //Tomahawk.getID3Tag(this.oauth.createOauthUrl(item['file']['downloadUrl']), this.onID3TagCallback(item['fileId'], tags).bind(this) //); } } } + + if(response.nextPageToken){ + this.updateDatabase(response.nextPageToken); + }else{ + this.cursor = parseInt(response.largestChangeId) + 1; + dbLocal.setItem('cursor', this.cursor); + } }, resolve: function (qid, artist, album, title) { @@ -187,6 +195,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //dbSql.addTrack }, + //TODO: put that in QTScriptResolverHelper isMimeTypeSupported: function(mimeType) { //Tomahawk.log("Checking : "+ mimeType); From 5a38139414315671ecfc5d9ead66bf24a9ac3acf Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Tue, 26 Feb 2013 11:24:00 +0100 Subject: [PATCH 025/118] Add ID music Manager --- dropbox/dropbox.js | 4 ++-- dropbox/musicManager.js | 34 +++++++++++++++++++--------------- googledrive/musicManager.js | 34 +++++++++++++++++++--------------- 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index 8982bd097..692335a0e 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -86,9 +86,9 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.log("Cursor : " + response.cursor); Tomahawk.log("Hasmore : " + response.has_more); Tomahawk.log("Entries length : " + response.entries.length); - for(var i = 0; i < 5; i++){ + /*for(var i = 0; i < 5; i++){ Tomahawk.log("Entry n°" + i + " : " + response.entries[i][0] + " : " + DumpObjectIndented(response.entries[i][1])); - } + }*/ }, resolve: function (qid, artist, album, title) { diff --git a/dropbox/musicManager.js b/dropbox/musicManager.js index 94430eea4..fd309748c 100644 --- a/dropbox/musicManager.js +++ b/dropbox/musicManager.js @@ -25,16 +25,15 @@ var musicManager = { dbName : "MyDropBoxDB" , dbSQL: null , - //dbSQL: openDatabase(this.dbName, '1.0', 'DropBox Muic Database', 2 * 1024 * 1024), searchLimitResults : 500 , initDatabase : function() { // TODO : choose the id : url / device ID / combo of columns ? Tomahawk.log("Init webSQL Db : "); - if (!this.dbSQL) this.dbSQL = openDatabase(this.dbName, '1.0', 'DropBox Muic Database', 2 * 1024 * 1024) ; + if (!this.dbSQL) this.dbSQL = openDatabase(this.dbName, '1.0', 'Muic Database', 2 * 1024 * 1024) ; this.dbSQL.transaction(function (tx) { - tx.executeSql('CREATE TABLE IF NOT EXISTS track (id integer primary key autoincrement, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url)'); + tx.executeSql('CREATE TABLE IF NOT EXISTS track (id primary key, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url)'); }); }, @@ -64,6 +63,7 @@ var musicManager = { addTrack : function(tabTrackDetails) { + var id = tabTrackDetails["id"]; var title = tabTrackDetails["title"]; var artist = tabTrackDetails["artist"]; var album = tabTrackDetails["album"] ; @@ -76,26 +76,30 @@ var musicManager = { var bitrate = tabTrackDetails["bitrate"] ; var url = tabTrackDetails["url"] ; - // Checking presence in the database before adding - // TODO : request :) - + // Check presence in the database before adding + this.dbSQL.transaction(function (tx) { + tx.executeSql('SELECT id FROM track where id=?', [id], function (tx, resultsQuery ) { + if (resultsQuery.rows.length > 0) { + Tomahawk.log("Insertion abort : data already inside the "+this.dbName+""); + return ; + } + }); + }); // Track Insertion this.dbSQL.transaction(function (tx) { - tx.executeSql('INSERT INTO track (title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', - [title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url]); + tx.executeSql('INSERT INTO track (id, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + [id, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url]); }); Tomahawk.log("Insertion inside "+this.dbName+""); }, deleteTrack: function (tabTrackDetails) { + // just need the ID TODO this.dbSQL.transaction(function (tx) { - tx.executeSql('DELETE FROM track (title, artist, album, url) VALUES (?, ?, ?, ?)', - [tabTrackDetails["title"], - tabTrackDetails["artist"], - tabTrackDetails["album"] , - tabTrackDetails["url"]]); - }); + tx.executeSql('DELETE FROM track (title, artist, album, url) VALUES (?, ?, ?, ?)', [tabTrackDetails["title"], tabTrackDetails["artist"], tabTrackDetails["album"] , tabTrackDetails["url"]]); + //tx.executeSql('DELETE FROM track WHERE id = ?', [id], function (tx,resultsQuery){}); + }); Tomahawk.log("Deletion inside "+this.dbName+""); }, @@ -180,7 +184,7 @@ var musicManager = { { var results = [] ; this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT * FROM track WHERE album=? and artist=? and title=? ', [album,artist,title], // Select first or limit mechanisim ? + tx.executeSql('SELECT * FROM track WHERE album=? and artist=? and title=? ', [album,artist,title], // Select first or limit mechanisim ? function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; //Tomahawk.log("Number of track results for resolve : "+results.length); diff --git a/googledrive/musicManager.js b/googledrive/musicManager.js index 6a5d403fe..7e1200396 100644 --- a/googledrive/musicManager.js +++ b/googledrive/musicManager.js @@ -25,16 +25,15 @@ var musicManager = { dbName : "GoogleDriveDB" , dbSQL: null , - //dbSQL: openDatabase(this.dbName, '1.0', 'DropBox Muic Database', 2 * 1024 * 1024), searchLimitResults : 500 , initDatabase : function() { // TODO : choose the id : url / device ID / combo of columns ? Tomahawk.log("Init webSQL Db : "); - if (!this.dbSQL) this.dbSQL = openDatabase(this.dbName, '1.0', 'DropBox Muic Database', 2 * 1024 * 1024) ; + if (!this.dbSQL) this.dbSQL = openDatabase(this.dbName, '1.0', 'Muic Database', 2 * 1024 * 1024) ; this.dbSQL.transaction(function (tx) { - tx.executeSql('CREATE TABLE IF NOT EXISTS track (id integer primary key autoincrement, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url)'); + tx.executeSql('CREATE TABLE IF NOT EXISTS track (id primary key, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url)'); }); }, @@ -64,6 +63,7 @@ var musicManager = { addTrack : function(tabTrackDetails) { + var id = tabTrackDetails["id"]; var title = tabTrackDetails["title"]; var artist = tabTrackDetails["artist"]; var album = tabTrackDetails["album"] ; @@ -76,26 +76,30 @@ var musicManager = { var bitrate = tabTrackDetails["bitrate"] ; var url = tabTrackDetails["url"] ; - // Checking presence in the database before adding - // TODO : request :) - + // Check presence in the database before adding + this.dbSQL.transaction(function (tx) { + tx.executeSql('SELECT id FROM track where id=?', [id], function (tx, resultsQuery ) { + if (resultsQuery.rows.length > 0) { + Tomahawk.log("Insertion abort : data already inside the "+this.dbName+""); + return ; + } + }); + }); // Track Insertion this.dbSQL.transaction(function (tx) { - tx.executeSql('INSERT INTO track (title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', - [title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url]); + tx.executeSql('INSERT INTO track (id, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + [id, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url]); }); Tomahawk.log("Insertion inside "+this.dbName+""); }, deleteTrack: function (tabTrackDetails) { + // just need the ID TODO this.dbSQL.transaction(function (tx) { - tx.executeSql('DELETE FROM track (title, artist, album, url) VALUES (?, ?, ?, ?)', - [tabTrackDetails["title"], - tabTrackDetails["artist"], - tabTrackDetails["album"] , - tabTrackDetails["url"]]); - }); + tx.executeSql('DELETE FROM track (title, artist, album, url) VALUES (?, ?, ?, ?)', [tabTrackDetails["title"], tabTrackDetails["artist"], tabTrackDetails["album"] , tabTrackDetails["url"]]); + //tx.executeSql('DELETE FROM track WHERE id = ?', [id], function (tx,resultsQuery){}); + }); Tomahawk.log("Deletion inside "+this.dbName+""); }, @@ -180,7 +184,7 @@ var musicManager = { { var results = [] ; this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT * FROM track WHERE album=? and artist=? and title=? ', [album,artist,title], // Select first or limit mechanisim ? + tx.executeSql('SELECT * FROM track WHERE album=? and artist=? and title=? ', [album,artist,title], // Select first or limit mechanisim ? function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; //Tomahawk.log("Number of track results for resolve : "+results.length); From a47a28a81b9e3b71c3998e1b738c10f68fd4ac26 Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Tue, 26 Feb 2013 16:58:10 +0100 Subject: [PATCH 026/118] Google drive : add itself inside scriptcollection , Music Manager : ID add & delete, searchQuery done with like clause. --- googledrive/googledrive.js | 83 +++++++++++++++++++++++++++---------- googledrive/musicManager.js | 59 +++++++++++++++----------- 2 files changed, 96 insertions(+), 46 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index f3ee9eeb4..ecc7a613e 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -80,7 +80,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, init: function () { - Tomahawk.log("Beginnning INIT of Google Drive resovler"); + Tomahawk.log("Beginnning INIT of Google Drive resovler"); + Tomahawk.reportCapabilities( TomahawkResolverCapability.Browsable | TomahawkResolverCapability.AccountFactory ); //dbLocal.setItem("expiresOn","1"); Tomahawk.addLocalJSFile("musicManager.js"); @@ -89,8 +90,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.log("That is cursor : "+ this.cursor); this.oauth.init(); - musicManager.initDatabase() ; + musicManager.initDatabase() ; this.googleDriveMusicManagerTests() ; Tomahawk.log((Math.floor(Date.now()/1000) ).toString()); @@ -138,7 +139,6 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { } } } - if(response.nextPageToken){ this.updateDatabase(response.nextPageToken); }else{ @@ -146,48 +146,87 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { dbLocal.setItem('cursor', this.cursor); } }, - + resolve: function (qid, artist, album, title) { - //this.doSearchOrResolve(qid, title, 1); + musicManager.resolve(artist, album, title, function(results) { + var return_songs = { + qid: qid, + results: results + }; + //Tomahawk.log("google drive resolved query returned: "); + Tomahawk.addTrackResults(return_songs); + }); + }, search: function (qid, searchString) { - //this.doSearchOrResolve(qid, searchString, 15); + // set up a limit for the musicManager search Query + Tomahawk.log("search query"); + musicManager.searchQuery(searchString,function(results){ + var return_songs = { + qid: qid, + results: results + }; + Tomahawk.log("google drive search query returned: "); + Tomahawk.addTrackResults(return_songs); + }); }, artists: function( qid ) { - + Tomahawk.log("artists query"); + musicManager.allArtistsQuery(function(results){ + var return_artists = { + qid: qid, + artists: results + }; + Tomahawk.log("google drive artists returned: "); + //Tomahawk.addArtistResults(return_artists); + }); }, albums: function( qid, artist ) { - + Tomahawk.log("albums query"); + musicManager.albumsQuery(artist, function(results){ + var return_albums = { + qid: qid, + artist: artist, + albums: results + }; + Tomahawk.log("google drive albums returned: "); + //Tomahawk.addAlbumResults(return_albums); + }); }, tracks: function( qid, artist, album ) { - + Tomahawk.log("tracks query"); + musicManager.tracksQuery(artist, album, function(results){ + var return_tracks = { + qid: qid, + artist: artist, + album: album, + results: results + }; + Tomahawk.log("Google Drive tracks returned:"); + //Tomahawk.addAlbumTrackResults(return_tracks); + }); }, googleDriveMusicManagerTests: function() { - //~ musicManagerTester.flushDatabaseTest() ; - //~ musicManagerTester.init() ; - //~ musicManagerTester.addTrackTest() ; - //~ musicManagerTester.deleteTrackTest() ; + musicManagerTester.flushDatabaseTest() ; + musicManagerTester.init() ; + //musicManagerTester.populateDatabase(9) ; + //musicManagerTester.searchQueryTest() ; //~ musicManagerTester.resolveTest() ; //~ musicManagerTester.allArtistsQueryTest() ; //~ musicManagerTester.tracksQueryTest() ; - //~ musicManagerTester.albumsQueryTest() ; - //~ musicManagerTester.populateDatabase(9) ; - //~ musicManagerTester.showDatabase() ; + //~ musicManagerTester.albumsQueryTest() ; + //musicManagerTester.searchQueryTest() ; + //musicManagerTester.showDatabase() ; }, - - getID3Tag: function(fileUrl, callback) - { - - }, - + onID3TagCallback: function(fileId, tags) { //Add track to database diff --git a/googledrive/musicManager.js b/googledrive/musicManager.js index 7e1200396..a3a8cfaa3 100644 --- a/googledrive/musicManager.js +++ b/googledrive/musicManager.js @@ -39,13 +39,13 @@ var musicManager = { showDatabase: function() { + Tomahawk.log("Displaying Content of Database"); this.dbSQL.transaction(function (tx) { tx.executeSql('SELECT * FROM track', [], function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; var len = results.length ; var i = 0 ; - for (i ; i < len ; i ++) { - Tomahawk.log("Displaying Content of Database"); - Tomahawk.log("title: "+results[i].title+", artist: "+results[i].artist+", album: "+results[i].album+", url: "+results[i].url+""); + for (i ; i < len ; i ++) { + Tomahawk.log("id:"+results[i].id+", title:"+results[i].title+", artist:"+results[i].artist+", album:"+results[i].album+", url:"+results[i].url+""); } }); }); @@ -95,10 +95,9 @@ var musicManager = { deleteTrack: function (tabTrackDetails) { - // just need the ID TODO this.dbSQL.transaction(function (tx) { - tx.executeSql('DELETE FROM track (title, artist, album, url) VALUES (?, ?, ?, ?)', [tabTrackDetails["title"], tabTrackDetails["artist"], tabTrackDetails["album"] , tabTrackDetails["url"]]); - //tx.executeSql('DELETE FROM track WHERE id = ?', [id], function (tx,resultsQuery){}); + //tx.executeSql('DELETE FROM track (title, artist, album, url) VALUES (?, ?, ?, ?)', [tabTrackDetails["title"], tabTrackDetails["artist"], tabTrackDetails["album"] , tabTrackDetails["url"]]); + tx.executeSql('DELETE FROM track WHERE id = ?', [tabTrackDetails["id"]], function (tx,resultsQuery){}); }); Tomahawk.log("Deletion inside "+this.dbName+""); }, @@ -110,7 +109,8 @@ var musicManager = { var results = [] ; var song ; var len = resultsQuery.rows.length for (i = 0; i < len; i++) { - song = { + song = { + id: resultsQuery.rows.item(i).id , title: resultsQuery.rows.item(i).title , artist: resultsQuery.rows.item(i).artist , album: resultsQuery.rows.item(i).album , @@ -174,9 +174,18 @@ var musicManager = { }, // Parse Title, Album , Artist - searchQuery : function (searchString,callBack) + searchQuery: function (searchString,callBack) { - // TODO + this.dbSQL.transaction(function (tx) { + // Select first or limit mechanisim ? + tx.executeSql("SELECT * FROM track WHERE (album LIKE ?) or (artist LIKE ?) or (title LIKE ?)", ["%"+searchString+"%","%"+searchString+"%","%"+searchString+"%"], + function (tx, resultsQuery ) { + var len = resultsQuery.rows.length, i; + var results = musicManager.parseSongAttriutes(resultsQuery) ; + //Tomahawk.log("Number of track results for query : "+results.length); + callBack(results) ; + }); + }); }, // Only one Track matching @@ -196,26 +205,16 @@ var musicManager = { }; // Testing Object - var musicManagerTester = { tabTrackDetails: [] , + var musicManagerTester = { + tabTrackDetails: [] , + init: function() { - this.tabTrackDetails = ["title", "artist", "album", "albumpos","year","genre" ,"size","duration","mimetype","bitrate","url" ] ; - // OMG Javascript SUCKS ! ! ! - this.tabTrackDetails["title"] = "title1" ; - this.tabTrackDetails["artist"] = "artist1" ; - this.tabTrackDetails["album"] = "album1" ; - this.tabTrackDetails["albumpos"] = "Track1" ; - this.tabTrackDetails["year"] = "1990" ; - this.tabTrackDetails["genre"] = "Jazz" ; - this.tabTrackDetails["size"] = "1024" ; - this.tabTrackDetails["duration"] = "3:06" ; - this.tabTrackDetails["mimetype"] = "mp3" ; - this.tabTrackDetails["bitrate"] = "128 kps" ; - this.tabTrackDetails["url"] = "http://dropbox.com/user/jimmy/music/mysong.mp3" ; + // Example of structure + this.tabTrackDetails = {"id": "22" , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; }, populateDatabase: function (rows){ musicManager.flushDatabase() ; - //this.tabTrackDetails = ["title", "artist", "album", "albumpos","year","genre" ,"size","duration","mimetype","bitrate","url" ] ; var i = 0 ; for (i ; i < rows ; i++) { for (index in this.tabTrackDetails){ @@ -279,5 +278,17 @@ var musicManager = { Tomahawk.log("Return album title name num "+i+" : "+results[i]); } }); + }, + + searchQueryTest: function() { + var qString = "art"; + musicManager.searchQuery(qString, function(results){ + var len = results.length ; var i = 0; + for (i ; i < len ; i++) { + //Tomahawk.log("Return of a search query size : "+i+" : "+results[i]); + } + }); }, + + }; From d7488b2d98feeed861b880c7ba0ec7ee87c8f86a Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Tue, 26 Feb 2013 17:01:48 +0100 Subject: [PATCH 027/118] MusicManager of dropbox updated from google'one --- dropbox/musicManager.js | 59 ++++++++++++++++++++++--------------- googledrive/musicManager.js | 1 - 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/dropbox/musicManager.js b/dropbox/musicManager.js index 2a1bd409a..669b53d15 100644 --- a/dropbox/musicManager.js +++ b/dropbox/musicManager.js @@ -25,6 +25,7 @@ var musicManager = { dbSQL: null , searchLimitResults : 500 , + initDatabase : function() { // TODO : choose the id : url / device ID / combo of columns ? @@ -37,13 +38,13 @@ var musicManager = { showDatabase: function() { + Tomahawk.log("Displaying Content of Database"); this.dbSQL.transaction(function (tx) { tx.executeSql('SELECT * FROM track', [], function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; var len = results.length ; var i = 0 ; - for (i ; i < len ; i ++) { - Tomahawk.log("Displaying Content of Database"); - Tomahawk.log("title: "+results[i].title+", artist: "+results[i].artist+", album: "+results[i].album+", url: "+results[i].url+""); + for (i ; i < len ; i ++) { + Tomahawk.log("id:"+results[i].id+", title:"+results[i].title+", artist:"+results[i].artist+", album:"+results[i].album+", url:"+results[i].url+""); } }); }); @@ -93,10 +94,9 @@ var musicManager = { deleteTrack: function (tabTrackDetails) { - // just need the ID TODO this.dbSQL.transaction(function (tx) { - tx.executeSql('DELETE FROM track (title, artist, album, url) VALUES (?, ?, ?, ?)', [tabTrackDetails["title"], tabTrackDetails["artist"], tabTrackDetails["album"] , tabTrackDetails["url"]]); - //tx.executeSql('DELETE FROM track WHERE id = ?', [id], function (tx,resultsQuery){}); + //tx.executeSql('DELETE FROM track (title, artist, album, url) VALUES (?, ?, ?, ?)', [tabTrackDetails["title"], tabTrackDetails["artist"], tabTrackDetails["album"] , tabTrackDetails["url"]]); + tx.executeSql('DELETE FROM track WHERE id = ?', [tabTrackDetails["id"]], function (tx,resultsQuery){}); }); Tomahawk.log("Deletion inside "+this.dbName+""); }, @@ -108,7 +108,8 @@ var musicManager = { var results = [] ; var song ; var len = resultsQuery.rows.length for (i = 0; i < len; i++) { - song = { + song = { + id: resultsQuery.rows.item(i).id , title: resultsQuery.rows.item(i).title , artist: resultsQuery.rows.item(i).artist , album: resultsQuery.rows.item(i).album , @@ -172,9 +173,18 @@ var musicManager = { }, // Parse Title, Album , Artist - searchQuery : function (searchString,callBack) + searchQuery: function (searchString,callBack) { - // TODO + this.dbSQL.transaction(function (tx) { + // Select first or limit mechanisim ? + tx.executeSql("SELECT * FROM track WHERE (album LIKE ?) or (artist LIKE ?) or (title LIKE ?)", ["%"+searchString+"%","%"+searchString+"%","%"+searchString+"%"], + function (tx, resultsQuery ) { + var len = resultsQuery.rows.length, i; + var results = musicManager.parseSongAttriutes(resultsQuery) ; + //Tomahawk.log("Number of track results for query : "+results.length); + callBack(results) ; + }); + }); }, // Only one Track matching @@ -194,26 +204,16 @@ var musicManager = { }; // Testing Object - var musicManagerTester = { tabTrackDetails: [] , + var musicManagerTester = { + tabTrackDetails: [] , + init: function() { - this.tabTrackDetails = ["title", "artist", "album", "albumpos","year","genre" ,"size","duration","mimetype","bitrate","url" ] ; - // OMG Javascript SUCKS ! ! ! - this.tabTrackDetails["title"] = "title1" ; - this.tabTrackDetails["artist"] = "artist1" ; - this.tabTrackDetails["album"] = "album1" ; - this.tabTrackDetails["albumpos"] = "Track1" ; - this.tabTrackDetails["year"] = "1990" ; - this.tabTrackDetails["genre"] = "Jazz" ; - this.tabTrackDetails["size"] = "1024" ; - this.tabTrackDetails["duration"] = "3:06" ; - this.tabTrackDetails["mimetype"] = "mp3" ; - this.tabTrackDetails["bitrate"] = "128 kps" ; - this.tabTrackDetails["url"] = "http://dropbox.com/user/jimmy/music/mysong.mp3" ; + // Example of structure + this.tabTrackDetails = {"id": "22" , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; }, populateDatabase: function (rows){ musicManager.flushDatabase() ; - //this.tabTrackDetails = ["title", "artist", "album", "albumpos","year","genre" ,"size","duration","mimetype","bitrate","url" ] ; var i = 0 ; for (i ; i < rows ; i++) { for (index in this.tabTrackDetails){ @@ -277,5 +277,16 @@ var musicManager = { Tomahawk.log("Return album title name num "+i+" : "+results[i]); } }); + }, + + searchQueryTest: function() { + var qString = "art"; + musicManager.searchQuery(qString, function(results){ + var len = results.length ; var i = 0; + for (i ; i < len ; i++) { + //Tomahawk.log("Return of a search query size : "+i+" : "+results[i]); + } + }); }, + }; diff --git a/googledrive/musicManager.js b/googledrive/musicManager.js index a3a8cfaa3..cd18a1289 100644 --- a/googledrive/musicManager.js +++ b/googledrive/musicManager.js @@ -290,5 +290,4 @@ var musicManager = { }); }, - }; From dfeeb91d8f2a99237ba8b6260bea4bc1ce7388a4 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Tue, 26 Feb 2013 21:38:28 +0100 Subject: [PATCH 028/118] Add custom url handler for google drive resolver. --- googledrive/googledrive.js | 66 ++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index f3ee9eeb4..56e7b5213 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -19,7 +19,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { uid: '', cursor: '', - maxResults: '15', + maxResults: '150', + getFileUrl: '', settings: { name: 'Google Drive', @@ -69,7 +70,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.log("Delete was clicked"); this.cursor = ''; - dbLocal.setItem('cursor',''); + dbLocal.setItem('googledrive.cursor',''); this.oauth.deleteAssociation(); @@ -81,16 +82,18 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { init: function () { Tomahawk.log("Beginnning INIT of Google Drive resovler"); - //dbLocal.setItem("expiresOn","1"); + //dbLocal.setItem("googledrive.expiresOn","1"); + //dbLocal.setItem("googledrive.cursor",""); Tomahawk.addLocalJSFile("musicManager.js"); - this.cursor = dbLocal.getItem('cursor',''); - Tomahawk.log("That is cursor : "+ this.cursor); + this.cursor = dbLocal.getItem('googledrive.cursor',''); this.oauth.init(); musicManager.initDatabase() ; + Tomahawk.addCustomUrlHandler( "googledrive", "getStreamUrl" ); + this.googleDriveMusicManagerTests() ; Tomahawk.log((Math.floor(Date.now()/1000) ).toString()); @@ -130,7 +133,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //Tomahawk.log("File : " + item['file']['title']+ " is supported : " + this.isMimeTypeSupported(item['file']['mimeType'])); if(this.isMimeTypeSupported(item['file']['mimeType'])){ - //Tomahawk.log(DumpObjectIndented(item)); + Tomahawk.log(DumpObjectIndented(item)); //Get ID3 Tag Tomahawk.log("Get ID3Tag from : " + item['file']['originalFilename']); //Tomahawk.getID3Tag(this.oauth.createOauthUrl(item['file']['downloadUrl']), this.onID3TagCallback(item['fileId'], tags).bind(this) @@ -143,7 +146,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { this.updateDatabase(response.nextPageToken); }else{ this.cursor = parseInt(response.largestChangeId) + 1; - dbLocal.setItem('cursor', this.cursor); + dbLocal.setItem('googledrive.cursor', this.cursor); } }, @@ -168,6 +171,13 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { tracks: function( qid, artist, album ) { + }, + + getStreamUrl: function (ourUrl) { + var songId = ourUrl.replace("googledrive://", ""); + + return(this.oauth.createOauthUrl('https://docs.google.com/uc?export=download&id=' + songId)) ; + }, googleDriveMusicManagerTests: function() { @@ -206,9 +216,9 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { oauth: { init: function(){ - this.accessToken = dbLocal.getItem('accessToken',''); - this.refreshToken = dbLocal.getItem('refreshToken',''); - this.expiresOn = dbLocal.getItem('expiresOn',''); + this.accessToken = dbLocal.getItem('googledrive.accessToken',''); + this.refreshToken = dbLocal.getItem('googledrive.refreshToken',''); + this.expiresOn = dbLocal.getItem('googledrive.expiresOn',''); }, //associate a new User @@ -222,9 +232,9 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, deleteAssociation: function(){ - dbLocal.setItem('accessToken',''); - dbLocal.setItem('refreshToken',''); - dbLocal.setItem('expiresOn',''); + dbLocal.setItem('googledrive.accessToken',''); + dbLocal.setItem('googledrive.refreshToken',''); + dbLocal.setItem('googledrive.expiresOn',''); this.accessToken = ''; this.refreshToken = ''; @@ -232,8 +242,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, isAssociated: function(){ - var accessToken = dbLocal.getItem('accessToken',''); - var refreshToken = dbLocal.getItem('refreshToken',''); + var accessToken = dbLocal.getItem('googledrive.accessToken',''); + var refreshToken = dbLocal.getItem('googledrive.refreshToken',''); return( !(accessToken === '') && !(refreshToken === '') ); }, @@ -273,6 +283,20 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { } }, + createOauthUrl: function(url){ + if(!this.isAssociated()){ + //TODO throw error NoAccountAssociated ? + Tomahawk.log("REFUSED Creation to "+ url + " : No account associated"); + }else{ + if(this.tokenExpired()){ + Tomahawk.log("Token expired"); + this.getRefreshedAccessToken(function (){this.createOauthUrl(url);}.bind(this)); + }else{ + return (url + '&access_token=' + this.accessToken); + } + } + }, + //Private member clientId: '440397511251.apps.googleusercontent.com', @@ -334,9 +358,9 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { this.refreshToken = ret.refresh_token; this.expiresOn = Math.floor(Date.now()/1000) + ret.expires_in; - dbLocal.setItem('accessToken',this.accessToken); - dbLocal.setItem('refreshToken',this.refreshToken); - dbLocal.setItem('expiresOn',this.expiresOn); + dbLocal.setItem('googledrive.accessToken',this.accessToken); + dbLocal.setItem('googledrive.refreshToken',this.refreshToken); + dbLocal.setItem('googledrive.expiresOn',this.expiresOn); if(! (typeof callback === 'undefined')){ callback(); @@ -353,8 +377,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { this.accessToken = ret.access_token; this.expiresOn = Math.floor(Date.now()/1000) + ret.expires_in; - dbLocal.setItem('accessToken',this.accessToken); - dbLocal.setItem('expiresOn',this.expiresOn); + dbLocal.setItem('googledrive.accessToken',this.accessToken); + dbLocal.setItem('googledrive.expiresOn',this.expiresOn); if(! (typeof callback === 'undefined')){ callback(); @@ -393,7 +417,7 @@ var dbLocal = { result = (result == null)? defaultResponse : result; Tomahawk.log("DB: loaded "+key+" : '"+ result+"' "); - + return result; } }; From 9a535d190efc8e5dc7eafcab646202aa75291fd3 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Tue, 26 Feb 2013 22:02:17 +0100 Subject: [PATCH 029/118] Dropbox resolver: Complete Delta support. Secure localStorage usage. Add custom Url handler. --- dropbox/dropbox.js | 81 ++++++++++++++++++++++++++++-------- dropbox/jsOAuth-1.3.6.min.js | 2 +- 2 files changed, 65 insertions(+), 18 deletions(-) diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index 3718cd3e6..6473c30f7 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -19,6 +19,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { uid: '', cursor: '', + getFileUrl: 'https://api-content.dropbox.com/1/files/dropbox', settings: { name: 'Dropbox', @@ -68,7 +69,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.log("Delete was clicked"); this.cursor = ''; - db.setItem('cursor',''); + dbLocal.setItem('dropbox.cursor',''); this.oauth.deleteAssociation(); @@ -83,10 +84,14 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.addLocalJSFile('jsOAuth-1.3.6.min.js'); Tomahawk.addLocalJSFile("musicManager.js"); - this.cursor = db.getItem('cursor',''); + this.cursor = dbLocal.getItem('dropbox.cursor',''); this.oauth.init(); musicManager.initDatabase() ; + + Tomahawk.addCustomUrlHandler( "dropbox", "getStreamUrl" ); + + //Tomahawk.log(DumpObjectIndented(this.oauth.oAuthGetUrl('https://api-content.dropbox.com/1/files/dropbox/photos/sample album/boston city flow.jpg',function(){},function(){}))); //TODO updateDatabase every 30 min (and handle if a user asked for a DB refresh before) //TODO update only if asscociated to an account @@ -95,17 +100,42 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { updateDatabase: function(){ Tomahawk.log("Sending Delta Query : "); - this.oauth.opostJSON('https://api.dropbox.com/1/delta', {'cursor': ''}, this.deltaCallback, this.queryFailure); + Tomahawk.log("with cursor : "+ this.cursor); + + var url = 'https://api.dropbox.com/1/delta' + (this.cursor === '' ? '' : '?cursor='+this.cursor); + + this.oauth.opostJSON(url, {'cursor' : this.cursor}, this.deltaCallback.bind(this), this.queryFailure.bind(this)); }, deltaCallback: function(response){ - //TODO set cursor in DB Tomahawk.log("Delta returned!"); Tomahawk.log("Cursor : " + response.cursor); Tomahawk.log("Hasmore : " + response.has_more); Tomahawk.log("Entries length : " + response.entries.length); - for(var i = 0; i < 5; i++){ - Tomahawk.log("Entry n°" + i + " : " + response.entries[i][0] + " : " + DumpObjectIndented(response.entries[i][1])); + for(var i = 0; i < response.entries.length; i++){ + var path = response.entries[i][0]; + var meta = response.entries[i][1]; + //Tomahawk.log("Entry n°" + i + ", Path: " + path /*+ ", Meta: " + DumpObjectIndented(meta)*/); + if(!meta){ + Tomahawk.log("Deleting : " + path); + //dbSQL.deleteTrack(path); + }else{ + if(!meta['is_dir'] && this.isMimeTypeSupported(meta['mime_type'])){ + //Tomahawk.log(DumpObjectIndented(meta)); + //Get ID3 Tag + Tomahawk.log("Get ID3Tag for : " + path); + //Tomahawk.getID3Tag(this.oauth.createOauthUrl(item['file']['downloadUrl']), this.onID3TagCallback(item['fileId'], tags).bind(this) + //); + } + } + } + + this.cursor = response.cursor; + dbLocal.setItem('dropbox.cursor', response.cursor); + + if(response.has_more){ + Tomahawk.log("Updating again"); + this.updateDatabase(); } }, @@ -136,13 +166,26 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { tracks: function( qid, artist, album ) { + }, + + isMimeTypeSupported: function(mimeType) + { + //Tomahawk.log("Checking : "+ mimeType); + var mimes = [ "audio/mpeg" , "application/ogg" , "application/ogg" , "audio/x-musepack" , "audio/x-ms-wma" , "audio/mp4" , "audio/mp4" , "audio/mp4" , "audio/flac" , "audio/aiff" , "audio/aiff" , "audio/x-wavpack" ]; + return (mimes.lastIndexOf(mimeType) != -1); + }, + + getStreamUrl: function (ourUrl) { + var path = ourUrl.replace("dropbox://", ""); + + return this.oauth.oAuthGetUrl(this.getFileUrl + path); }, oauth: { init: function(){ - this.oauthSettings.accessTokenKey = db.getItem('accessTokenKey',''); - this.oauthSettings.accessTokenSecret = db.getItem('accessTokenSecret',''); + this.oauthSettings.accessTokenKey = dbLocal.getItem('dropbox.accessTokenKey',''); + this.oauthSettings.accessTokenSecret = dbLocal.getItem('dropbox.accessTokenSecret',''); this.oauthEngine = OAuth(this.oauthSettings); }, @@ -156,8 +199,8 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { }, deleteAssociation: function(){ - db.setItem('accessTokenKey',''); - db.setItem('accessTokenSecret',''); + dbLocal.setItem('dropbox.accessTokenKey',''); + dbLocal.setItem('dropbox.accessTokenSecret',''); this.oauthSettings.accessTokenKey = ''; this.oauthSettings.accessTokenSecret = ''; @@ -167,8 +210,8 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { }, isAssociated: function(){ - var accessKey = db.getItem('accessTokenKey',''); - var accessSecret = db.getItem('accessTokenSecret',''); + var accessKey = dbLocal.getItem('dropbox.accessTokenKey',''); + var accessSecret = dbLocal.getItem('dropbox.accessTokenSecret',''); return( !(accessKey === '') && !(accessSecret === '') ); }, @@ -190,6 +233,10 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { } }, + oAuthGetUrl: function (url, success, failure) { + return this.oauthEngine.oAuthGetUrl(url,success, failure); + }, + //Private member oauthEngine: null, @@ -243,8 +290,8 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { this.oauthSettings.accessTokenKey = obj.oauth_token; this.oauthSettings.accessTokenSecret = obj.oauth_token_secret; - db.setItem('accessTokenKey',obj.oauth_token); - db.setItem('accessTokenSecret',obj.oauth_token_secret); + dbLocal.setItem('dropbox.accessTokenKey',obj.oauth_token); + dbLocal.setItem('dropbox.accessTokenSecret',obj.oauth_token_secret); if(! (typeof callback === 'undefined')){ callback.call(Tomahawk.resolver.instance); @@ -258,7 +305,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { } }); -var db = { +var dbLocal = { setItem: function(a1, a2){ window.localStorage.setItem(a1,a2); }, @@ -266,8 +313,8 @@ var db = { var result = window.localStorage.getItem(key); result = (result == null)? defaultResponse : result; - Tomahawk.log("DB: loaded "+key+" : '"+ result+"' "); - + Tomahawk.log("DB: loaded "+key+" : '"+ result+"' "); + return result; } }; diff --git a/dropbox/jsOAuth-1.3.6.min.js b/dropbox/jsOAuth-1.3.6.min.js index bb6388541..dad0930b7 100644 --- a/dropbox/jsOAuth-1.3.6.min.js +++ b/dropbox/jsOAuth-1.3.6.min.js @@ -1 +1 @@ -var exports=exports||this;exports.OAuth=function(e){function t(e){var t=arguments,n=t.callee,r=t.length,i,s=this;if(this instanceof n){for(i in e)e.hasOwnProperty(i)&&(s[i]=e[i]);return s}return new n(e)}function n(){}function r(e){var t=arguments,n=t.callee,r,s,o,u,a,f,l,c=/^([^:\/?#]+?:\/\/)*([^\/:?#]*)?(:[^\/?#]*)*([^?#]*)(\?[^#]*)?(#(.*))*/,h=this;if(!(this instanceof n))return new n(e);h.scheme="",h.host="",h.port="",h.path="",h.query=new i,h.anchor="";if(e!==null){r=e.match(c),s=r[1],o=r[2],u=r[3],a=r[4],f=r[5],l=r[6],s=s!==undefined?s.replace("://","").toLowerCase():"http",u=u?u.replace(":",""):s==="https"?"443":"80",s=s=="http"&&u==="443"?"https":s,f=f?f.replace("?",""):"",l=l?l.replace("#",""):"";if(s==="https"&&u!=="443"||s==="http"&&u!=="80")o=o+":"+u;h.scheme=s,h.host=o,h.port=u,h.path=a||"/",h.query.setQueryParams(f),h.anchor=l||""}}function i(e){var t=arguments,n=t.callee,r=t.length,i,s=this,u=o.urlDecode;if(this instanceof n){if(e!=undefined)for(i in e)e.hasOwnProperty(i)&&(s[i]=e[i]);return s}return new n(e)}function o(e){return this instanceof o?this.init(e):new o(e)}function u(e){var t=[],n,r;for(n in e)e[n]&&e[n]!==undefined&&e[n]!==""&&(n==="realm"?r=n+'="'+e[n]+'"':t.push(n+'="'+o.urlEncode(e[n]+"")+'"'));return t.sort(),r&&t.unshift(r),t.join(", ")}function a(e,t,n,r){var i=[],s,u=o.urlEncode;for(s in n)n[s]!==undefined&&n[s]!==""&&i.push([o.urlEncode(s),o.urlEncode(n[s]+"")]);for(s in r)r[s]!==undefined&&r[s]!==""&&(n[s]||i.push([u(s),u(r[s]+"")]));return i=i.sort(function(e,t){return e[0]t[0]?1:e[1]t[1]?1:0}).map(function(e){return e.join("=")}),[e,u(t),u(i.join("&"))].join("&")}function f(){return parseInt(+(new Date)/1e3,10)}function l(e){function t(){return Math.floor(Math.random()*u.length)}e=e||64;var n=e/8,r="",i=n/4,s=n%4,o,u=["20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F","30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F","40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F","50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F","60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F","70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E"];for(o=0;o>6),128+(n&63)):n<65536?t.push(224+(n>>12),128+(n>>6&63),128+(n&63)):n<2097152&&t.push(240+(n>>18),128+(n>>12&63),128+(n>>6&63),128+(n&63));return t}function d(e){var t=[],n;for(n=0;n>>5]>>>24-n%32&255);return t}function v(e){var t=[],n=e.length,r;for(r=0;r>>4).toString(16)),t.push((e[r]&15).toString(16));return t.join("")}function m(e){var t="",n=e.length,r;for(r=0;r>>32-t}function y(e){if(e!==undefined){var t=e,n,r;return t.constructor===String&&(t=p(t)),this instanceof y?n=this:n=new y(e),r=n.hash(t),v(r)}return this instanceof y?this:new y}function b(e,t,n,r){var i=p(t),s=p(n),o=i.length,u,a,f,l;o>e.blocksize&&(i=e.hash(i),o=i.length),i=i.concat(h(e.blocksize-o)),a=i.slice(0),f=i.slice(0);for(l=0;l0&&(r=n.join("&")),r},i.prototype.setQueryParams=function(e){var t=arguments,n=t.length,r,i,s,u=this,a,f=o.urlDecode;if(n==1){if(typeof e=="object")for(r in e)e.hasOwnProperty(r)&&(u[r]=f(e[r]));else if(typeof e=="string"){i=e.split("&");for(r=0,s=i.length;r=200&&m.status<=226||m.status==304||m.status===0?d(a):m.status>=400&&m.status!==0&&v(a)}},y={oauth_callback:n.callbackUrl,oauth_consumer_key:n.consumerKey,oauth_token:n.accessTokenKey,oauth_signature_method:n.signatureMethod,oauth_timestamp:f(),oauth_nonce:l(),oauth_verifier:n.verifier,oauth_version:s},b=n.signatureMethod,N=i.query.toObject();for(g in N)T[g]=N[g];if((!("Content-Type"in p)||p["Content-Type"]=="application/x-www-form-urlencoded")&&!C)for(g in h)T[g]=h[g];k=i.scheme+"://"+i.host+i.path,w=a(t,k,y,T),E=o.signatureMethod[b](n.consumerSecret,n.accessTokenSecret,w),y.oauth_signature=E,this.realm&&(y.realm=this.realm),n.proxyUrl&&(i=r(n.proxyUrl+i.path));if(x||t=="GET")i.query.setQueryParams(h),S=null;else if(!C)if(typeof h=="string")S=h,"Content-Type"in p||(p["Content-Type"]="text/plain");else{for(g in h)S.push(o.urlEncode(g)+"="+o.urlEncode(h[g]+""));S=S.sort().join("&"),"Content-Type"in p||(p["Content-Type"]="application/x-www-form-urlencoded")}else if(C){S=new FormData;for(g in h)S.append(g,h[g])}m.open(t,i+"",!0),m.setRequestHeader("Authorization","OAuth "+u(y)),m.setRequestHeader("X-Requested-With","XMLHttpRequest");for(g in p)m.setRequestHeader(g,p[g]);m.send(S)},this},get:function(e,t,n){this.request({url:e,success:t,failure:n})},post:function(e,t,n,r){this.request({method:"POST",url:e,data:t,success:n,failure:r})},getJSON:function(e,t,n){this.get(e,function(e){t(JSON.parse(e.text))},n)},postJSON:function(e,t,n,r){this.request({method:"POST",url:e,data:JSON.stringify(t),success:function(e){n(JSON.parse(e.text))},failure:r,headers:{"Content-Type":"application/json"}})},parseTokenRequest:function(e,t){switch(t){case"text/xml":var n=e.xml.getElementsByTagName("token"),r=e.xml.getElementsByTagName("secret");a[o.urlDecode(n[0])]=o.urlDecode(r[0]);break;default:var i=0,s=e.text.split("&"),u=s.length,a={};for(;i{}|`^\\\u0080-\uffff]/,r=e.length,i,s=e.split(""),o;for(i=0;i>6))+t(128+(o&63)):o<65536?s[i]=t(224+(o>>12))+t(128+(o>>6&63))+t(128+(o&63)):o<2097152&&(s[i]=t(240+(o>>18))+t(128+(o>>12&63))+t(128+(o>>6&63))+t(128+(o&63)));return s.join("")},o.urlDecode=function(e){return e?e.replace(/%[a-fA-F0-9]{2}/ig,function(e){return String.fromCharCode(parseInt(e.replace("%",""),16))}):""},y.prototype=new y,y.prototype.blocksize=64,y.prototype.hash=function(e){function C(e,t,n,r){switch(e){case 0:return t&n|~t&r;case 1:case 3:return t^n^r;case 2:return t&n|t&r|n&r}return-1}var t=[1732584193,4023233417,2562383102,271733878,3285377520],n=[1518500249,1859775393,2400959708,3395469782],r,i,s,o,u,a,f,l,c,v,m,y,b,w,E,S,x,T,N;e.constructor===String&&(e=p(e.encodeUTF8())),s=e.length,o=Math.ceil((s+9)/this.blocksize)*this.blocksize-(s+9),i=Math.floor(s/4294967296),r=Math.floor(s%4294967296),u=[i*8>>24&255,i*8>>16&255,i*8>>8&255,i*8&255,r*8>>24&255,r*8>>16&255,r*8>>8&255,r*8&255],e=e.concat([128],h(o),u),a=Math.ceil(e.length/this.blocksize);for(f=0;f>>2]|=l[m]<<24-(m-(m>>2)*4)*8;y=t[0],b=t[1],w=t[2],E=t[3],S=t[4];for(x=0;x<80;x++)x>=16&&(v[x]=g(v[x-3]^v[x-8]^v[x-14]^v[x-16],1)),T=Math.floor(x/20),N=g(y,5)+C(T,b,w,E)+S+n[T]+v[x],S=E,E=w,w=g(b,30),b=y,y=N;t[0]+=y,t[1]+=b,t[2]+=w,t[3]+=E,t[4]+=S}return d(t)},o}(exports);var exports=exports||this;(function(e){var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";e.btoa=e.btoa||function(e){var n=0,r=e.length,i,s,o="";for(;n>2,(i[0]&3)<<4|i[1]>>4,(i[1]&15)<<2|i[2]>>6,i[2]&63],isNaN(i[1])&&(s[2]=64),isNaN(i[2])&&(s[3]=64),o+=t.charAt(s[0])+t.charAt(s[1])+t.charAt(s[2])+t.charAt(s[3]);return o}})(exports) \ No newline at end of file +var exports=exports||this;exports.OAuth=function(a){function b(a){var e,b=arguments,c=b.callee,f=(b.length,this);if(!(this instanceof c))return new c(a);for(e in a)a.hasOwnProperty(e)&&(f[e]=a[e]);return f}function c(){}function d(a){var d,f,g,h,i,j,k,b=arguments,c=b.callee,l=/^([^:\/?#]+?:\/\/)*([^\/:?#]*)?(:[^\/?#]*)*([^?#]*)(\?[^#]*)?(#(.*))*/,m=this;return this instanceof c?(m.scheme="",m.host="",m.port="",m.path="",m.query=new e,m.anchor="",null!==a&&(d=a.match(l),f=d[1],g=d[2],h=d[3],i=d[4],j=d[5],k=d[6],f=void 0!==f?f.replace("://","").toLowerCase():"http",h=h?h.replace(":",""):"https"===f?"443":"80",f="http"==f&&"443"===h?"https":f,j=j?j.replace("?",""):"",k=k?k.replace("#",""):"",("https"===f&&"443"!==h||"http"===f&&"80"!==h)&&(g=g+":"+h),m.scheme=f,m.host=g,m.port=h,m.path=i||"/",m.query.setQueryParams(j),m.anchor=k||""),void 0):new c(a)}function e(a){var e,b=arguments,c=b.callee,f=(b.length,this);if(g.urlDecode,!(this instanceof c))return new c(a);if(void 0!=a)for(e in a)a.hasOwnProperty(e)&&(f[e]=a[e]);return f}function g(a){return this instanceof g?this.init(a):new g(a)}function h(a){var c,d,b=[];for(c in a)a[c]&&void 0!==a[c]&&""!==a[c]&&("realm"===c?d=c+'="'+a[c]+'"':b.push(c+'="'+g.urlEncode(a[c]+"")+'"'));return b.sort(),d&&b.unshift(d),b.join(", ")}function i(a,b,c,d){var f,e=[],h=g.urlEncode;for(f in c)void 0!==c[f]&&""!==c[f]&&e.push([g.urlEncode(f),g.urlEncode(c[f]+"")]);for(f in d)void 0!==d[f]&&""!==d[f]&&(c[f]||e.push([h(f),h(d[f]+"")]));return e=e.sort(function(a,b){return a[0]b[0]?1:a[1]b[1]?1:0}).map(function(a){return a.join("=")}),[a,h(b),h(e.join("&"))].join("&")}function j(){return parseInt(+new Date/1e3,10)}function k(a){function b(){return Math.floor(Math.random()*h.length)}a=a||64;var g,c=a/8,d="",e=c/4,f=c%4,h=["20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F","30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F","40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F","50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F","60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F","70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E"];for(g=0;e>g;g++)d+=h[b()]+h[b()]+h[b()]+h[b()];for(g=0;f>g;g++)d+=h[b()];return d}function l(){var b;if(a.Titanium!==void 0&&a.Titanium.Network.createHTTPClient!==void 0)b=a.Titanium.Network.createHTTPClient();else if("undefined"!=typeof require)try{b=new require("xhr").XMLHttpRequest()}catch(c){if(void 0===a.XMLHttpRequest)throw"No valid request transport found.";b=new a.XMLHttpRequest}else{if(void 0===a.XMLHttpRequest)throw"No valid request transport found.";b=new a.XMLHttpRequest}return b}function m(a){var b=Array(++a);return b.join(0).split("")}function n(a){var c,d,b=[];for(d=0;a.length>d;d++)c=a.charCodeAt(d),128>c?b.push(c):2048>c?b.push(192+(c>>6),128+(63&c)):65536>c?b.push(224+(c>>12),128+(63&c>>6),128+(63&c)):2097152>c&&b.push(240+(c>>18),128+(63&c>>12),128+(63&c>>6),128+(63&c));return b}function o(a){var c,b=[];for(c=0;32*a.length>c;c+=8)b.push(255&a[c>>>5]>>>24-c%32);return b}function p(a){var d,b=[],c=a.length;for(d=0;c>d;d++)b.push((a[d]>>>4).toString(16)),b.push((15&a[d]).toString(16));return b.join("")}function q(a){var d,b="",c=a.length;for(d=0;c>d;d++)b+=String.fromCharCode(a[d]);return b}function r(a,b){return a<>>32-b}function s(a){if(void 0!==a){var c,d,b=a;return b.constructor===String&&(b=n(b)),c=this instanceof s?this:new s(a),d=c.hash(b),p(d)}return this instanceof s?this:new s}function t(a,b,c,d){var h,i,j,k,e=n(b),f=n(c),g=e.length;for(g>a.blocksize&&(e=a.hash(e),g=e.length),e=e.concat(m(a.blocksize-g)),i=e.slice(0),j=e.slice(0),k=0;a.blocksize>k;k++)i[k]^=92,j[k]^=54;return h=a.hash(i.concat(a.hash(j.concat(f)))),d?p(h):q(h)}c.prototype={join:function(a){return a=a||"",this.values().join(a)},keys:function(){var a,b=[],c=this;for(a in c)c.hasOwnProperty(a)&&b.push(a);return b},values:function(){var a,b=[],c=this;for(a in c)c.hasOwnProperty(a)&&b.push(c[a]);return b},shift:function(){throw"not implimented"},unshift:function(){throw"not implimented"},push:function(){throw"not implimented"},pop:function(){throw"not implimented"},sort:function(){throw"not implimented"},ksort:function(a){var d,e,f,b=this,c=b.keys();for(void 0==a?c.sort():c.sort(a),d=0;c.length>d;d++)f=c[d],e=b[f],delete b[f],b[f]=e;return b},toObject:function(){var b,a={},c=this;for(b in c)c.hasOwnProperty(b)&&(a[b]=c[b]);return a}},b.prototype=new c,d.prototype={scheme:"",host:"",port:"",path:"",query:"",anchor:"",toString:function(){var a=this,b=a.query+"";return a.scheme+"://"+a.host+a.path+(""!=b?"?"+b:"")+(""!==a.anchor?"#"+a.anchor:"")}},e.prototype=new b,e.prototype.toString=function(){var a,b=this,c=[],d="",e="",f=g.urlEncode;b.ksort();for(a in b)b.hasOwnProperty(a)&&void 0!=a&&void 0!=b[a]&&(e=f(a)+"="+f(b[a]),c.push(e));return c.length>0&&(d=c.join("&")),d},e.prototype.setQueryParams=function(a){var d,e,f,i,b=arguments,c=b.length,h=this,j=g.urlDecode;if(1==c){if("object"==typeof a)for(d in a)a.hasOwnProperty(d)&&(h[d]=j(a[d]));else if("string"==typeof a)for(e=a.split("&"),d=0,f=e.length;f>d;d++)i=e[d].split("="),""!=i[0]&&(h[i[0]]=j(i[1]))}else for(d=0;c>d;d+=2)h[b[d]]=j(b[d+1])};var f="1.0";return g.prototype={realm:"",requestTokenUrl:"",authorizationUrl:"",accessTokenUrl:"",init:function(a){var b="",c={enablePrivilege:a.enablePrivilege||!1,proxyUrl:a.proxyUrl,callbackUrl:a.callbackUrl||"oob",consumerKey:a.consumerKey,consumerSecret:a.consumerSecret,accessTokenKey:a.accessTokenKey||b,accessTokenSecret:a.accessTokenSecret||b,verifier:b,signatureMethod:a.signatureMethod||"HMAC-SHA1"};return this.realm=a.realm||b,this.requestTokenUrl=a.requestTokenUrl||b,this.authorizationUrl=a.authorizationUrl||b,this.accessTokenUrl=a.accessTokenUrl||b,this.getAccessToken=function(){return[c.accessTokenKey,c.accessTokenSecret]},this.getAccessTokenKey=function(){return c.accessTokenKey},this.getAccessTokenSecret=function(){return c.accessTokenSecret},this.setAccessToken=function(a,b){b&&(a=[a,b]),c.accessTokenKey=a[0],c.accessTokenSecret=a[1]},this.getVerifier=function(){return c.verifier},this.setVerifier=function(a){c.verifier=a},this.setCallbackUrl=function(a){c.callbackUrl=a},this.request=function(a){var b,e,m,n,o,p,q,r,s,t,u,v,x,z,A,B,w=[],y={};b=a.method||"GET",e=d(a.url),m=a.data||{},n=a.headers||{},o=a.success||function(){},p=a.failure||function(){},A=function(){var a=!1;for(var b in m)(m[b]instanceof File||m[b].fileName!==void 0)&&(a=!0);return a}(),x=a.appendQueryString?a.appendQueryString:!1,c.enablePrivilege&&netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead UniversalBrowserWrite"),q=l(),q.onreadystatechange=function(){if(4===q.readyState){var e,a=/^(.*?):\s*(.*?)\r?$/gm,b=n,c={},d="";if(q.getAllResponseHeaders)for(d=q.getAllResponseHeaders();e=a.exec(d);)c[e[1]]=e[2];else if(q.getResponseHeaders){d=q.getResponseHeaders();for(var f=0,g=d.length;g>f;++f)c[d[f][0]]=d[f][1]}var h=!1;"Content-Type"in c&&"text/xml"==c["Content-Type"]&&(h=!0);var i={text:q.responseText,xml:h?q.responseXML:"",requestHeaders:b,responseHeaders:c};q.status>=200&&226>=q.status||304==q.status||0===q.status?o(i):q.status>=400&&0!==q.status&&p(i)}},s={oauth_callback:c.callbackUrl,oauth_consumer_key:c.consumerKey,oauth_token:c.accessTokenKey,oauth_signature_method:c.signatureMethod,oauth_timestamp:j(),oauth_nonce:k(),oauth_verifier:c.verifier,oauth_version:f},t=c.signatureMethod,z=e.query.toObject();for(r in z)y[r]=z[r];if(!("Content-Type"in n&&"application/x-www-form-urlencoded"!=n["Content-Type"]||A))for(r in m)y[r]=m[r];if(B=e.scheme+"://"+e.host+e.path,u=i(b,B,s,y),v=g.signatureMethod[t](c.consumerSecret,c.accessTokenSecret,u),s.oauth_signature=v,this.realm&&(s.realm=this.realm),c.proxyUrl&&(e=d(c.proxyUrl+e.path)),x||"GET"==b)e.query.setQueryParams(m),w=null;else if(A){if(A){w=new FormData;for(r in m)w.append(r,m[r])}}else if("string"==typeof m)w=m,"Content-Type"in n||(n["Content-Type"]="text/plain");else{for(r in m)w.push(g.urlEncode(r)+"="+g.urlEncode(m[r]+""));w=w.sort().join("&"),"Content-Type"in n||(n["Content-Type"]="application/x-www-form-urlencoded")}q.open(b,e+"",!0),q.setRequestHeader("Authorization","OAuth "+h(s)),q.setRequestHeader("X-Requested-With","XMLHttpRequest");for(r in n)q.setRequestHeader(r,n[r]);q.send(w)},this.createOauthUrl=function(a){var b,e,l,m,n,o,q,r,s,t,u,w,y,z,A,v=[],x={};b=a.method||"GET",e=d(a.url),l=a.data||{},m=a.headers||{},n=a.success||function(){},o=a.failure||function(){},z=function(){var a=!1;for(var b in l)(l[b]instanceof File||l[b].fileName!==void 0)&&(a=!0);return a}(),w=a.appendQueryString?a.appendQueryString:!1,c.enablePrivilege&&netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead UniversalBrowserWrite"),r={oauth_callback:c.callbackUrl,oauth_consumer_key:c.consumerKey,oauth_token:c.accessTokenKey,oauth_signature_method:c.signatureMethod,oauth_timestamp:j(),oauth_nonce:k(),oauth_verifier:c.verifier,oauth_version:f},s=c.signatureMethod,y=e.query.toObject();for(q in y)x[q]=y[q];if(!("Content-Type"in m&&"application/x-www-form-urlencoded"!=m["Content-Type"]||z))for(q in l)x[q]=l[q];if(A=e.scheme+"://"+e.host+e.path,t=i(b,A,r,x),u=g.signatureMethod[s](c.consumerSecret,c.accessTokenSecret,t),r.oauth_signature=u,this.realm&&(r.realm=this.realm),c.proxyUrl&&(e=d(c.proxyUrl+e.path)),w||"GET"==b)e.query.setQueryParams(l),v=null;else if(z){if(z){v=new FormData;for(q in l)v.append(q,l[q])}}else if("string"==typeof l)v=l,"Content-Type"in m||(m["Content-Type"]="text/plain");else{for(q in l)v.push(g.urlEncode(q)+"="+g.urlEncode(l[q]+""));v=v.sort().join("&"),"Content-Type"in m||(m["Content-Type"]="application/x-www-form-urlencoded")}var B={};B.Authorization="OAuth "+h(r);for(q in m)B[q]=m[q];return{url:""+e,headers:B}},this},get:function(a,b,c){this.request({url:a,success:b,failure:c})},post:function(a,b,c,d){this.request({method:"POST",url:a,data:b,success:c,failure:d})},getJSON:function(a,b,c){this.get(a,function(a){b(JSON.parse(a.text))},c)},postJSON:function(a,b,c,d){this.request({method:"POST",url:a,data:JSON.stringify(b),success:function(a){c(JSON.parse(a.text))},failure:d,headers:{"Content-Type":"application/json"}})},oAuthGetUrl:function(a,b,c){return this.createOauthUrl({url:a,success:b,failure:c})},oAuthPostUrl:function(a,b,c,d){return this.createOauthUrl({method:"POST",url:a,data:b,success:c,failure:d})},parseTokenRequest:function(a,b){switch(b){case"text/xml":var c=a.xml.getElementsByTagName("token"),d=a.xml.getElementsByTagName("secret");i[g.urlDecode(c[0])]=g.urlDecode(d[0]);break;default:for(var e=0,f=a.text.split("&"),h=f.length,i={};h>e;++e){var j=f[e].split("=");i[g.urlDecode(j[0])]=g.urlDecode(j[1])}}return i},fetchRequestToken:function(a,b){var c=this;c.setAccessToken("","");var d=c.authorizationUrl;this.get(this.requestTokenUrl,function(b){var e=c.parseTokenRequest(b,b.responseHeaders["Content-Type"]||void 0);c.setAccessToken([e.oauth_token,e.oauth_token_secret]),a(d+"?"+b.text)},b)},fetchAccessToken:function(a,b){var c=this;this.get(this.accessTokenUrl,function(b){var d=c.parseTokenRequest(b,b.responseHeaders["Content-Type"]||void 0);c.setAccessToken([d.oauth_token,d.oauth_token_secret]),c.setVerifier(""),a(b)},b)}},g.signatureMethod={"HMAC-SHA1":function(b,c,d){var e,f,h=g.urlEncode;return b=h(b),c=h(c||""),e=b+"&"+c,f=t(s.prototype,e,d),a.btoa(f)}},g.urlEncode=function(a){function b(a){var b=a.toString(16).toUpperCase();return 2>b.length&&(b=0+b),"%"+b}if(!a)return"";a+="";var e,g,c=/[ \r\n!*"'();:@&=+$,\/?%#\[\]<>{}|`^\\\u0080-\uffff]/,d=a.length,f=a.split("");for(e=0;d>e;e++)(g=f[e].match(c))&&(g=g[0].charCodeAt(0),128>g?f[e]=b(g):2048>g?f[e]=b(192+(g>>6))+b(128+(63&g)):65536>g?f[e]=b(224+(g>>12))+b(128+(63&g>>6))+b(128+(63&g)):2097152>g&&(f[e]=b(240+(g>>18))+b(128+(63&g>>12))+b(128+(63&g>>6))+b(128+(63&g))));return f.join("")},g.urlDecode=function(a){return a?a.replace(/%[a-fA-F0-9]{2}/gi,function(a){return String.fromCharCode(parseInt(a.replace("%",""),16))}):""},s.prototype=new s,s.prototype.blocksize=64,s.prototype.hash=function(a){function A(a,b,c,d){switch(a){case 0:return b&c|~b&d;case 1:case 3:return b^c^d;case 2:return b&c|b&d|c&d}return-1}var d,e,f,g,h,i,j,k,l,p,q,s,t,u,v,w,x,y,z,b=[1732584193,4023233417,2562383102,271733878,3285377520],c=[1518500249,1859775393,2400959708,3395469782];for(a.constructor===String&&(a=n(a.encodeUTF8())),f=a.length,g=Math.ceil((f+9)/this.blocksize)*this.blocksize-(f+9),e=Math.floor(f/4294967296),d=Math.floor(f%4294967296),h=[255&8*e>>24,255&8*e>>16,255&8*e>>8,255&8*e,255&8*d>>24,255&8*d>>16,255&8*d>>8,255&8*d],a=a.concat([128],m(g),h),i=Math.ceil(a.length/this.blocksize),j=0;i>j;j++){for(k=a.slice(j*this.blocksize,(j+1)*this.blocksize),l=k.length,p=[],q=0;l>q;q++)p[q>>>2]|=k[q]<<24-8*(q-4*(q>>2));for(s=b[0],t=b[1],u=b[2],v=b[3],w=b[4],x=0;80>x;x++)x>=16&&(p[x]=r(p[x-3]^p[x-8]^p[x-14]^p[x-16],1)),y=Math.floor(x/20),z=r(s,5)+A(y,t,u,v)+w+c[y]+p[x],w=v,v=u,u=r(t,30),t=s,s=z;b[0]+=s,b[1]+=t,b[2]+=u,b[3]+=v,b[4]+=w}return o(b)},g}(exports);var exports=exports||this;(function(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";a.btoa=a.btoa||function(a){for(var e,f,c=0,d=a.length,g="";d>c;c+=3)e=[a.charCodeAt(c),a.charCodeAt(c+1),a.charCodeAt(c+2)],f=[e[0]>>2,(3&e[0])<<4|e[1]>>4,(15&e[1])<<2|e[2]>>6,63&e[2]],isNaN(e[1])&&(f[2]=64),isNaN(e[2])&&(f[3]=64),g+=b.charAt(f[0])+b.charAt(f[1])+b.charAt(f[2])+b.charAt(f[3]);return g}})(exports); \ No newline at end of file From 88bf98421fa9955261892cb4453490fb9fc2307d Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Tue, 26 Feb 2013 23:17:36 +0100 Subject: [PATCH 030/118] Log info for ID3 tags in dropbox and google drive. --- dropbox/dropbox.js | 14 +++++++++++++- googledrive/googledrive.js | 4 +++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index b625dab31..b3353e032 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -84,6 +84,8 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.addLocalJSFile('jsOAuth-1.3.6.min.js'); Tomahawk.addLocalJSFile("musicManager.js"); + //dbLocal.setItem("dropbox.cursor",""); + this.cursor = dbLocal.getItem('dropbox.cursor',''); this.oauth.init(); @@ -125,7 +127,10 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { //Tomahawk.log(DumpObjectIndented(meta)); //Get ID3 Tag Tomahawk.log("Get ID3Tag for : " + path); - //Tomahawk.getID3Tag(this.oauth.createOauthUrl(item['file']['downloadUrl']), this.onID3TagCallback(item['fileId'], tags).bind(this) + Tomahawk.log("size : " + meta['bytes']); + Tomahawk.log("mime : " + meta['mime_type']); + Tomahawk.log('request : ' + DumpObjectIndented( this.getStreamUrl(path) )); + //Tomahawk.getID3Tag(args, this.onID3TagCallback(item['fileId'], tags).bind(this) //); } } @@ -140,6 +145,13 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { } }, + onID3TagCallback: function(fileId, tags) + { + //Add track to database + //var url = 'googledrive://' + fileId; + //dbSql.addTrack + }, + resolve: function (qid, artist, album, title) { //this.doSearchOrResolve(qid, title, 1); }, diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 8b558fd1c..12c35ebdb 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -119,7 +119,6 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { deltaCallback: function(response){ //TODO set cursor in DB Tomahawk.log("Delta returned!"); - Tomahawk.log("selfLink : " + response.selfLink); Tomahawk.log("nextPageToken : " + response.nextPageToken); Tomahawk.log("largestChangeId : " + response.largestChangeId); //Tomahawk.log(DumpObjectIndented(response)); @@ -137,6 +136,9 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.log(DumpObjectIndented(item)); //Get ID3 Tag Tomahawk.log("Get ID3Tag from : " + item['file']['originalFilename']); + Tomahawk.log("size : " + item['file']['fileSize']); + Tomahawk.log("mime : " + item['file']['mimeType']); + Tomahawk.log('url : ' + this.getStreamUrl(item['file']['id'])); //Tomahawk.getID3Tag(this.oauth.createOauthUrl(item['file']['downloadUrl']), this.onID3TagCallback(item['fileId'], tags).bind(this) //); } From 469f974416845f2ab2e450680f218857aeb7deeb Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Tue, 26 Feb 2013 23:26:20 +0100 Subject: [PATCH 031/118] Add reportCapabilities to resolvers. --- dropbox/dropbox.js | 3 +-- googledrive/googledrive.js | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index b3353e032..c0320c7bd 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -92,8 +92,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { musicManager.initDatabase() ; Tomahawk.addCustomUrlHandler( "dropbox", "getStreamUrl" ); - - //Tomahawk.log(DumpObjectIndented(this.oauth.oAuthGetUrl('https://api-content.dropbox.com/1/files/dropbox/photos/sample album/boston city flow.jpg',function(){},function(){}))); + Tomahawk.reportCapabilities( TomahawkResolverCapability.Browsable | TomahawkResolverCapability.AccountFactory ); //TODO updateDatabase every 30 min (and handle if a user asked for a DB refresh before) //TODO update only if asscociated to an account diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 12c35ebdb..edacc9eb8 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -82,7 +82,6 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { init: function () { Tomahawk.log("Beginnning INIT of Google Drive resovler"); - Tomahawk.reportCapabilities( TomahawkResolverCapability.Browsable | TomahawkResolverCapability.AccountFactory ); //dbLocal.setItem("googledrive.expiresOn","1"); //dbLocal.setItem("googledrive.cursor",""); @@ -96,11 +95,9 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { this.googleDriveMusicManagerTests() ; Tomahawk.addCustomUrlHandler( "googledrive", "getStreamUrl" ); + Tomahawk.reportCapabilities( TomahawkResolverCapability.Browsable | TomahawkResolverCapability.AccountFactory ); - Tomahawk.log((Math.floor(Date.now()/1000) ).toString()); - //TODO updateDatabase when? - this.updateDatabase(); }, From 54682f4e444513721b42266262b5cc0844dad91b Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Wed, 27 Feb 2013 13:21:07 +0100 Subject: [PATCH 032/118] Add the parsing of id3 tags. --- dropbox/dropbox.js | 16 +++++++++------- googledrive/googledrive.js | 24 ++++++++++++++---------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index c0320c7bd..72e2c52b7 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -84,7 +84,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.addLocalJSFile('jsOAuth-1.3.6.min.js'); Tomahawk.addLocalJSFile("musicManager.js"); - //dbLocal.setItem("dropbox.cursor",""); + dbLocal.setItem("dropbox.cursor",""); this.cursor = dbLocal.getItem('dropbox.cursor',''); @@ -126,11 +126,11 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { //Tomahawk.log(DumpObjectIndented(meta)); //Get ID3 Tag Tomahawk.log("Get ID3Tag for : " + path); - Tomahawk.log("size : " + meta['bytes']); - Tomahawk.log("mime : " + meta['mime_type']); - Tomahawk.log('request : ' + DumpObjectIndented( this.getStreamUrl(path) )); - //Tomahawk.getID3Tag(args, this.onID3TagCallback(item['fileId'], tags).bind(this) - //); + //Tomahawk.log("size : " + meta['bytes']); + //Tomahawk.log("mime : " + meta['mime_type']); + //Tomahawk.log('request : ' + DumpObjectIndented( this.getStreamUrl(path) )); + Tomahawk.ReadCloudFile(path, meta['bytes'], meta['mime_type'], this.getStreamUrl(path), "onID3TagCallback" + ); } } } @@ -144,11 +144,13 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { } }, - onID3TagCallback: function(fileId, tags) + onID3TagCallback: function(tags) { //Add track to database //var url = 'googledrive://' + fileId; //dbSql.addTrack + Tomahawk.log("Tags : "); + Tomahawk.log(DumpObjectIndented(tags)); }, resolve: function (qid, artist, album, title) { diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index edacc9eb8..e10831300 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -83,7 +83,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { init: function () { Tomahawk.log("Beginnning INIT of Google Drive resovler"); //dbLocal.setItem("googledrive.expiresOn","1"); - //dbLocal.setItem("googledrive.cursor",""); + dbLocal.setItem("googledrive.cursor",""); Tomahawk.addLocalJSFile("musicManager.js"); @@ -127,17 +127,18 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.log("Deleting : " + item['fileId']); //dbSQL.deleteTrack(item.file.id); }else{ + var file = item['file']; //Tomahawk.log("File : " + item['file']['title']+ " is supported : " + this.isMimeTypeSupported(item['file']['mimeType'])); - if(this.isMimeTypeSupported(item['file']['mimeType'])){ - Tomahawk.log(DumpObjectIndented(item)); + if(this.isMimeTypeSupported(file['mimeType'])){ + //Tomahawk.log(DumpObjectIndented(item)); //Get ID3 Tag - Tomahawk.log("Get ID3Tag from : " + item['file']['originalFilename']); - Tomahawk.log("size : " + item['file']['fileSize']); - Tomahawk.log("mime : " + item['file']['mimeType']); - Tomahawk.log('url : ' + this.getStreamUrl(item['file']['id'])); - //Tomahawk.getID3Tag(this.oauth.createOauthUrl(item['file']['downloadUrl']), this.onID3TagCallback(item['fileId'], tags).bind(this) - //); + Tomahawk.log("Get ID3Tag from : " + file['originalFilename']); + //Tomahawk.log("size : " + item['file']['fileSize']); + //Tomahawk.log("mime : " + item['file']['mimeType']); + //Tomahawk.log('url : ' + this.getStreamUrl(item['file']['id'])); + Tomahawk.ReadCloudFile(file['originalFilename'], file['fileSize'], file['mimeType'], this.getStreamUrl(file['id']), "onID3TagCallback" + ); } } } @@ -236,11 +237,14 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //musicManagerTester.showDatabase() ; }, - onID3TagCallback: function(fileId, tags) + onID3TagCallback: function(tags) { //Add track to database //var url = 'googledrive://' + fileId; //dbSql.addTrack + Tomahawk.log("Tags : "); + Tomahawk.log(DumpObjectIndented(tags)); + }, //TODO: put that in QTScriptResolverHelper From 07374f233c4b79256fd665e8a305e6f8921817d8 Mon Sep 17 00:00:00 2001 From: loclamor Date: Wed, 27 Feb 2013 18:20:01 +0100 Subject: [PATCH 033/118] ca marche avec la downloadUrl + le token --- googledrive/googledrive.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index e10831300..3f279d6d4 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -137,7 +137,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //Tomahawk.log("size : " + item['file']['fileSize']); //Tomahawk.log("mime : " + item['file']['mimeType']); //Tomahawk.log('url : ' + this.getStreamUrl(item['file']['id'])); - Tomahawk.ReadCloudFile(file['originalFilename'], file['fileSize'], file['mimeType'], this.getStreamUrl(file['id']), "onID3TagCallback" + Tomahawk.ReadCloudFile(file['originalFilename'], file['fileSize'], file['mimeType'], this.oauth.createOauthUrl(file['downloadUrl']), "onID3TagCallback" ); } } From 576e63ab74aa7f7d1e60bfbb0143f676a345a625 Mon Sep 17 00:00:00 2001 From: loclamor Date: Thu, 28 Feb 2013 10:58:46 +0100 Subject: [PATCH 034/118] ajout du parametre ID lors de l'appel a readCloudFile --- dropbox/dropbox.js | 2 +- googledrive/googledrive.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index 72e2c52b7..9979eacba 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -129,7 +129,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { //Tomahawk.log("size : " + meta['bytes']); //Tomahawk.log("mime : " + meta['mime_type']); //Tomahawk.log('request : ' + DumpObjectIndented( this.getStreamUrl(path) )); - Tomahawk.ReadCloudFile(path, meta['bytes'], meta['mime_type'], this.getStreamUrl(path), "onID3TagCallback" + Tomahawk.ReadCloudFile(path, path, meta['bytes'], meta['mime_type'], this.getStreamUrl(path), "onID3TagCallback" ); } } diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 3f279d6d4..92b3765a1 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -137,7 +137,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //Tomahawk.log("size : " + item['file']['fileSize']); //Tomahawk.log("mime : " + item['file']['mimeType']); //Tomahawk.log('url : ' + this.getStreamUrl(item['file']['id'])); - Tomahawk.ReadCloudFile(file['originalFilename'], file['fileSize'], file['mimeType'], this.oauth.createOauthUrl(file['downloadUrl']), "onID3TagCallback" + Tomahawk.ReadCloudFile(file['originalFilename'], file['id'], file['fileSize'], file['mimeType'], this.oauth.createOauthUrl(file['downloadUrl']), "onID3TagCallback" ); } } From 5c763c7d2d7f8f90a87c0d42573809841bc6a3f9 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Thu, 28 Feb 2013 22:17:02 +0100 Subject: [PATCH 035/118] Make token refresh synchronous in googleDrive. --- googledrive/googledrive.js | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 92b3765a1..5c689a2ff 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -83,7 +83,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { init: function () { Tomahawk.log("Beginnning INIT of Google Drive resovler"); //dbLocal.setItem("googledrive.expiresOn","1"); - dbLocal.setItem("googledrive.cursor",""); + //dbLocal.setItem("googledrive.cursor",""); Tomahawk.addLocalJSFile("musicManager.js"); @@ -409,8 +409,22 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { } }, - onRefreshedTokenReceived: function(data, callback){ + tokenExpired: function(){ + return (Math.floor(Date.now()/1000) > this.expiresOn); + }, + + getRefreshedAccessToken: function(callback){ + var that = this; + var params = 'grant_type=refresh_token' + + '&refresh_token=' + this.refreshToken + + '&client_id=' + this.clientId + + '&client_secret=' + this.clientSecret; + //parse response + var data = Tomahawk.syncPostRequest(this.tokenUrl, params); + + //Tomahawk.log(DumpObjectIndented(data.responseText)); + var ret = JSON.parse(data.responseText); Tomahawk.log('Old access token : ' + this.accessToken); @@ -426,22 +440,6 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { callback(); } }, - - tokenExpired: function(){ - return (Math.floor(Date.now()/1000) > this.expiresOn); - }, - - getRefreshedAccessToken: function(callback){ - var that = this; - var params = 'grant_type=refresh_token' - + '&refresh_token=' + this.refreshToken - + '&client_id=' + this.clientId - + '&client_secret=' + this.clientSecret; - - Tomahawk.asyncPostRequest(this.tokenUrl, params, function(data){ - this.onRefreshedTokenReceived(data, callback); - }.bind(this)); - }, queryFailure: function(data) { Tomahawk.log("Request Failed : " + data.text); From 5042c0cf793f185240306499c65b07f15b25d1ad Mon Sep 17 00:00:00 2001 From: Jason Herskowitz Date: Sun, 3 Mar 2013 09:11:45 -0500 Subject: [PATCH 036/118] Update README --- README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index 6746a6551..6c9f4c515 100644 --- a/README +++ b/README @@ -1,3 +1,3 @@ -Here go the resolvers :-) +To manually intstall a resolver: either 1) clone this repo, or 2) download the .zip, or 3) download the individual files within the individual resolver folder you are installing. -http://tomahawk-player.org/ +After you have the files installed locally, open Tomahawk's preferences and from the "Services" tab click "Install from File" and select the .js file for the resolver you are installing. From d8d940c454e48f4afe7eb7a0dd74e60564749e9f Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Mon, 4 Mar 2013 01:55:57 +0100 Subject: [PATCH 037/118] Auto refresh token in Google drive resolver. Deactivated ID3 tag paring until google.sparsetable crashed is resolved. --- googledrive/googledrive.js | 76 ++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 5c689a2ff..7fd5d7a11 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -84,6 +84,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.log("Beginnning INIT of Google Drive resovler"); //dbLocal.setItem("googledrive.expiresOn","1"); //dbLocal.setItem("googledrive.cursor",""); + + //Tomahawk.showWebInspector(); Tomahawk.addLocalJSFile("musicManager.js"); @@ -137,8 +139,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //Tomahawk.log("size : " + item['file']['fileSize']); //Tomahawk.log("mime : " + item['file']['mimeType']); //Tomahawk.log('url : ' + this.getStreamUrl(item['file']['id'])); - Tomahawk.ReadCloudFile(file['originalFilename'], file['id'], file['fileSize'], file['mimeType'], this.oauth.createOauthUrl(file['downloadUrl']), "onID3TagCallback" - ); + //Tomahawk.ReadCloudFile(file['originalFilename'], file['id'], file['fileSize'], file['mimeType'], this.oauth.createOauthUrl(file['downloadUrl']), "onID3TagCallback"); } } } @@ -261,6 +262,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { this.accessToken = dbLocal.getItem('googledrive.accessToken',''); this.refreshToken = dbLocal.getItem('googledrive.refreshToken',''); this.expiresOn = dbLocal.getItem('googledrive.expiresOn',''); + + this.setupAutoRefreshToken(); }, //associate a new User @@ -331,8 +334,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.log("REFUSED Creation to "+ url + " : No account associated"); }else{ if(this.tokenExpired()){ - Tomahawk.log("Token expired"); - this.getRefreshedAccessToken(function (){this.createOauthUrl(url);}.bind(this)); + Tomahawk.log("REFUSED Creation to "+ url + " : token expired"); + this.getRefreshedAccessToken(); }else{ return (url + '&access_token=' + this.accessToken); } @@ -366,7 +369,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, onTitleChanged: function(title, callback){ - Tomahawk.log("Title changed : \'" + title+"\'"); + //Tomahawk.log("Title changed : \'" + title+"\'"); var result = title.split('='); @@ -390,54 +393,57 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { } }, - onAccessTokenReceived: function(data, callback){ + onAccessTokenReceived: function(data, callback){ //parse response var ret = JSON.parse(data.responseText); - //TODO close webpage + //TODO close webpage, or not? this.accessToken = ret.access_token; - this.refreshToken = ret.refresh_token; - this.expiresOn = Math.floor(Date.now()/1000) + ret.expires_in; + this.expiresOn = Date.now() + (ret.expires_in*1000); dbLocal.setItem('googledrive.accessToken',this.accessToken); - dbLocal.setItem('googledrive.refreshToken',this.refreshToken); dbLocal.setItem('googledrive.expiresOn',this.expiresOn); + + if(typeof ret.refresh_token !=='undefined'){ + Tomahawk.log("Setting refresh token : " + ret.refresh_token); + this.refreshToken = ret.refresh_token; + dbLocal.setItem('googledrive.refreshToken',this.refreshToken); + } + + this.setupAutoRefreshToken(); - if(! (typeof callback === 'undefined')){ + if(typeof callback !== 'undefined'){ callback(); } }, tokenExpired: function(){ - return (Math.floor(Date.now()/1000) > this.expiresOn); + return (Date.now() > this.expiresOn); }, getRefreshedAccessToken: function(callback){ - var that = this; - var params = 'grant_type=refresh_token' - + '&refresh_token=' + this.refreshToken - + '&client_id=' + this.clientId - + '&client_secret=' + this.clientSecret; - - //parse response - var data = Tomahawk.syncPostRequest(this.tokenUrl, params); - - //Tomahawk.log(DumpObjectIndented(data.responseText)); - - var ret = JSON.parse(data.responseText); - - Tomahawk.log('Old access token : ' + this.accessToken); - Tomahawk.log('New access token : ' + ret.access_token); - - this.accessToken = ret.access_token; - this.expiresOn = Math.floor(Date.now()/1000) + ret.expires_in; - - dbLocal.setItem('googledrive.accessToken',this.accessToken); - dbLocal.setItem('googledrive.expiresOn',this.expiresOn); + Tomahawk.log("Refrshing access token."); + var params = 'grant_type=refresh_token' + + '&refresh_token=' + this.refreshToken + + '&client_id=' + this.clientId + + '&client_secret=' + this.clientSecret; + + Tomahawk.asyncPostRequest(this.tokenUrl, params, function(data){ + this.onAccessTokenReceived(data, callback); + }.bind(this)); + }, - if(! (typeof callback === 'undefined')){ - callback(); + setupAutoRefreshToken : function(){ + if(this.isAssociated()){ + if(this.tokenExpired()){ + Tomahawk.log("Token expired on auto"); + this.getRefreshedAccessToken(); + }else{ + Tomahawk.log("Setting timeout in " + (this.expiresOn - Date.now() - 2000) + "ms to getRefreshToken from init"); + //Tomahawk.log(this.getRefreshedAccessToken.bind(this)); + window.setTimeout(this.getRefreshedAccessToken.bind(this), (this.expiresOn - Date.now() - 2000)); + } } }, From dd3fdc47363c82a468a1bd70ff08f121fb3f4483 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Mon, 4 Mar 2013 17:03:57 +0100 Subject: [PATCH 038/118] Set a prettyName for Subsonic/Runners-ID. --- subsonic/subsonic.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/subsonic/subsonic.js b/subsonic/subsonic.js index d789c6c81..d05f0aea9 100644 --- a/subsonic/subsonic.js +++ b/subsonic/subsonic.js @@ -412,8 +412,17 @@ var SubsonicResolver = Tomahawk.extend(TomahawkResolver, { var desc = this.subsonic_url.replace(/^http:\/\//,"") .replace(/\/$/, "") .replace(/\/remote.php\/submedia/, ""); + + var collectionName = "Subsonic"; + + if (desc.indexOf("runners-id.com") !== -1 || + desc.indexOf("runners-id.org") !== -1 ) + { + collectionName = "Runners-ID"; + } + return { - prettyname: "Subsonic", + prettyname: collectionName, description: desc }; } From 93301c956439333f3bc88487ce471dba7711c92e Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 5 Mar 2013 10:17:52 +0100 Subject: [PATCH 039/118] Add different text/icon support to Ampache resolver for ownCloud. --- ampache/ampache-icon.png | Bin 13389 -> 12169 bytes ampache/ampache-resolver.js | 8 ++++++++ 2 files changed, 8 insertions(+) diff --git a/ampache/ampache-icon.png b/ampache/ampache-icon.png index 36db67e1badbccf81d889aae335166edba5d43a1..6c4155f069422cda3d198d550d841dcb501387fb 100644 GIT binary patch literal 12169 zcmWk!byO7J7aw4OrB}LHl$LI!mZiG|1O;hOS_Gt)P6=s{?xh62pmevClr%`JbV=85 ze{;^v`)AI1ciy~v?)RRV?@&r#uKa_m zMTakpH1e&JT&=>R<#p z0Q(dNF9Bdm7>Mk2Hhmxu1Xzq%S#AJ2Jb(pz;Pw=N$iB+(#Q;o`nJF;x5&G{jQIg_TlHQE;5QGzuWDqg0(|=pbdEs?>Hshyz^@w_#tDFY0gJ(B&%A-q z41iqe)JW>&c{K#Zge?ySxc^P9{M*?dA@^%)C&RqY$Hj4QPP4n|xo14GYdf}#ThmHIn?7Gc6 zjqcxH2T0vrp0Bn4VF?m^9i$ApTI>G#PotQA{0m;F<3E%3$~=@|3-{!n#mrhZuk8{BsEa zr!6jB(;Q$dgnh{RxYy&6?7eaxD}b<7{o)1yZxmQ~4TkGw2fzTJkQc=DO^)tg7d3Y$ z4t*E)QWwFUg=i?8rMDXnf#X{v=-n+iD}&)2;iKOexGealVGP2Zy7u8ouEf0EhChg< zT}f`8>&=5Fk$^cATypaFKfd6 zKU(Qn(R|cIg+0kayo~$+f9GFnT%q3g{Ji}=@LF+hydzrWbljhm(nk1y=Obz z4W5X^zk*lgH|o{sMwF2WduB?EhES@i7grUeOwrm?*n{N`-EP@?M*0^+9QNNt#QCX<0xvbUi7O%WtaW|GV{;*N4+k91Ga@g4F z9QI1Wq}bT-)$4kts_ZJ(*_Nu7(kG=&T1i?JIkR>>-%c8b8q2@aeB1hsvsm5e)ad`# z&XUURdtY_WVNzR?f3yGRdud#vhOLr2tT_}tbU2Jy%Ka&v%b8;$_! zIS_~G1pJ+yzHhihl`37IR z`s9yw{|hUnEaxTVevt~(h}05KK9+-Ul~KmBo|1X7#^L*PGj!WM<(m|pjQlNc#>J?0 zs=}rD>C1j%tB4OvpHMOPR#PZ@c|xlOk;Zb?iyX?#k5DH;=@)GRAzu;`+~7!N&7?-V zUAt}Dk0X^fVRa9E&N1Kl7*lYE-qj~mVw>>bH^NK)8oc6|yd1NUg|u zK6>!8et0oK?CVkP;{jH3$(;&62%9tPv>wn|5dIw?1wMf?p4?C0SxaVn*LL^pCd z&1hE~7^PJQw6T5Cd>8blYdE;80pr~sfg%1@nE&3=+`(&YV?LABhPOB2*>o}#QPI`p zi&SY8fxkJHytn8gT!uR`mXiM~ujp;E9=H8vyR*H*lVeJpicH&1BX%a5U-*w`_2qvD z=NF2Ld}*T`i!C9I@=b*uQa@U4N{7ZqC1nkY4E`D17>FMJT5fndcjY{JNax#nA-q4c zXxe&tFEiA>Xoz8`Ib%CxbE|q=e<@oXh1|JHy>)tBrRC&yFo5+7>mK(RapPRm^bEr< zX#>6Z+2?!8!~;z257|dvJVc^IhM&Lo|9R%B;Ip}NiMM*mNc3XiW2|rGI_?zHM+Q3v zK1X=wX{J(^e&(&IrD?PFPnpTt-IY&w%8N`SUxlSieALbih8z}lf~S(~PRC=jQ?mU7 zc(0c%77H4EQC4HCjwCKe&5#f4zZ4&1P?D{ZV`is6KAhGqZjl-NFv_fXVeYj1VOQ!Q zX-a#bW6S^Ad`>7IXJ>LGq?g;yKDk`>U7oK}E(f@? z-;a&7%zLpPR<&xkn*W0x$j!?yN6g5YJ}mt{S_*XR^vXM%TvEQo2@4s2NIZ`xk;jhD zh#v_j3g62SmywY8BkO*@b5|-qZavPHL-kPbFj7rL$ro@nvo|+3nLe4HcAA#d;pA6* zzuUP-Q?uCL-Ot!Q^;Ub}azlMLGabxqLD2Qvv{%|5O#^ z47?Y5eSMN&8)h8290{#l&wi-j`YysizH+QbwdOpnB}n)Ukr-Fr~L+mj@IvWFUjXVVZ2{Fzo~4PD{nTm zTRpqKIJ&(Ma|-TwPy{BBEnkMLV>5*8cB`tY`lrkF8{Ugn^l!L1X0kDdcAiN&EH?h# z+uLAZUCQ_p^>^QC-uUUu}! zK^egyh8B0;4rX2 zKZF@Xt|<335h@}g!je0FcD^@96?mGIOX&6S4VQB&P^d)TsPH}=(m zkeE2yvX()gR!9cCR%b(8OF`ElQL8xmv*zb}bWA(L zw)F!tiOqmIDAOaDtg!wa1aB(#DoSCAj*)R}e}1abb*}n#DWjCDtFHO#Nz_)I;RY^7 zQ8EN>@G?z4pZvtTK-|CoUkEDK>tQ7Ab-;Xhe}73k6kH$&nb7fGy&S+n(VuvK6&4el za$0PZFn_$6yZv~$WOAkc8}@)XT!G5=dNV3dB0W95v{dQk>FEX(l$7-E{{5SN^3Nr= zdH0~obbK6jIvS0H8F~VR@Oa`ls6~PvLJvE$BuEc`&Qq5+C1FVTU*J}S`Tb>0zs=6nHlRf106I+C>ww_hLe%;d^!aAxvNYEdS=_Ms6xr zy!|LcJ|sjlJ3HH>rKJUh8_PPiL#t4r`#Uu(C@6s2y#4O;?UDKAL3nsLGoZ^HY8~5k z>F=F`JASs-%qul6FU80{|309EXiLVP12Ux3Y*fB^`HAH;ejKRp(IQD zSI490P%xAltJ97CM>T<=p@7qZu+9C=dDvccOZDQV|Is)`&|On^;GXHK|z(7qk z6q29^S5pNuqqBvxSOdK7ve@YKt4;P{lILiD$wyUm5mR%@_3p~;XRg<;F=eLP^YcU% z1%rJO03jfX6YR9;N{cE z*q+ZPfd!rv$k^`JMcVOBor(p^ zY)q!>xOc^gPo&~OaBm^Y;5cx#q*a6yL)>LsNBGno1$#F>(DAK3Dj2)M<)M&lX(9A z{^-w`v?tfp)ZBW!ia&qH_~~!{J33lH4sv|sZ?0W8Er-pw19rLoA5C=0dD2EW<>lpv z*VghDR#$8Oou50PE5UAOCqhtMylnf-r?1h8_V6+XRo+}Zc{V2b=+x!oe6~IMyr7mk zYGC8{^_b+@nD|DlSXO4%ZBepggHSOCKKYisKrj?0lbc5M#`|rNF}LO3Y}Lhpg!=G+ zkJsqv=m~oAMnyGMg0SFNr9zd`sY+w+*~jJ8`(+Z((MW-Q{#w?S>%*3#>r#Df=^515 zid37#hlhZM!i}=Y*+wz+zFWCE*^suiv$Okv8oS(WZf^d!zRv7qZ?D3cqBead_4Ii) z6lG@qan|IBJVvqB|Mp^P<3wC)+z1EfhAhpjZdY-v>CJ&^I1~c!mpPLnX>{5^SNzZa zufY$sRs&0q+yFkXfs%dn`MC3|cyeXs&66kvNKBuOzP^?8&0x)J>v4AsYG!t(>vCyn z)VyP>TAjD4X!T60%8WM&9qCqQ5Y}X4qx9s#;;MK>ON;;f!~MWbJmW!`c5&tS<;8_4 zgT$|_cj$|gGUnHr*-kTWqTX&7YWohB`MmE%FnFR2$cJ`|Z~baF3s9*%Ktk=e0L~I^S*fJ!~p%FD#TVLq;2O zhkHx$LW>_RACF1AaAIeCb7G3sQ>6l?M#Ua65c6|$r5`_j+`YXxh-qwSVD;Mf{%+e1 z+6aCxy8LTSRwwYU4#{mdii%I>=<7E2Wwr0tUppD0qk5+nS)G;^+z5u!%2YMhSG;NE zHYU+X(ob;t8N8m=RlP-XZh6xF~-`xlosd6whUKrOku!W?p`7z|xKMD(8L+ zT`;`5g0Y_|$1{qcyQ=-+d_8;nySdwPhNITBoqZ|M17rnN;BH_gGPn6=xbH0I%4soi zCT%pQ#Zs49(to>m|MR z6)vu>9{H03AjGG$Q8BxhHE*)_cXkp>9G+6fFq1~X3=L6Xs7LShiW;Xk)sD2gyN-+1 zx2Hyo^$eyi?-m&r8}{xux93(f`T3_kck67(`0g&mcz^sYusKiqcCw^8`C4^8^B1eJbDD>{jMeksk0L+*Q!)B?K4;!iQCR2^^_E(g zG^&%I&^{9f65Q35zp(mv=tVU350Q z^}Z?9<2(zeb5^;$yi`}?B%liH8lrHMKb_(03yNz)w(dy;@vo1=Z|D};G`Q3(Wz)_>Vmh{$g7y%Un zIh;BlzYK~0dhRVXj^C=Xxq0r7f4|f>)Kj^mI?%8~?z|c{ASqp8RHLPtA*lE~MNRN) z(VrT1;FXt`SA7A;+SkJJ^6TG&gORf)8Xgb0o*a8`@h9>lbswgzCu5 z2;)oKL5k%yRL-lq-&%>@SSQ4Vy0TXKJ-JBqTJ!2aG&WTsSW9O{s1bsJb~FdO)A+>?t9F+h=V6k7q*;XzO^49xt0)K~s3$AGRCi7I;t zT!9Nxf+^Ptv~dv!;Cd) zN1UD=u_4ZpqBh~l00*OksakC0Io#jZ5a=(0Fx^No6MT3bfkaZ%(8`+29RU}ZYqNy_#ibnv!u(7etu#i?~UI{-wE>T zR<7XMpBTQly=Er7Rk>Lyq9vfa17h@#q+@<~KJp#@0s*%@guaBx#*$;PmV z?7(WZz_(Aum?LgoBZSA;k*dnr6u=}xB^s89|D&{%N1cBp;zP(JL*}urtv!9Hp2|}> zFk%V9ChA~6*t>OVqwY4}N5JoC`Gx+FvAfwbYbcJPWlt!hAH&eF%3gTaA+x`Sni&Ms zB`3$nZt^~{6w21xyY^eDS;0Zu5Ay%2TMm(zQt<#9;)gk8P6&@4y!cqTH9T&1UH`e} z{fpx2>Nv+tQCn+rMGPy98yxPtLqob?jOW`rAWGaY%mQ6lS|ocx0=c(m%V#@LN&&rO zdxzP?Sbf*{kR}XkD6}c`pZE_d00S~3yuVX$da`;svgq<6Y32Bu)mo_}etPOYU81k2 zui{k-QH`fb2-X{AO-(^GOyEvYi<&RFXHzB6z{3iMV_HOW3I+~>5aK6#pDzPE4%np{ zCC5KNA{4#vH1=;`YmH17f95}ja3uTfOImJxel4mrOgiex^^~hqikRkD7wU)Mjk$yy z9)VCd(kd1b1Z`E1e*3f%VoDqOUyMqhy7ghf`;nVfM#-;QGla8qbJ(7qo>HVygJc*w zrl#s%M=J-;tL<%su-Nj>{rP%NMO|npP%Io)2ZpN&~Lrp3?W+xs-BNN@0wX-_C#@zFfNghO_~<{y%IimY@W3tR9SyN8i8MbVLZf z@?;?l>fFftf2?u!PjnOGPAN8T(Q94u>{|CgHi-Ux3#lMc8*p%T()zheM=*RN!q@h zJOeo!NV7z4{{9isg_bMat%bNgP;hL%kNrTLZ=4o32o>nUCyD9(G@aeQeU+5D>_z%n<5Vf`O_i== zsy`TB3ZdDTiMe^r#PEttKSJTDoct#vMhoA|!)!xt3RPj+ioZ?b%vi_`cR;7Sv+E6$ zKXzPdGBGjs7lPzlwTaS|poKnjtQn<_1&MYl`5J#b)nY(|6r%_fiNM63Fa*=WRKl6b?Lu5;?_OYg!1>1~_2g#hPC4YaQZJ?PGCd{bgHg%(q5bTFvGR(XcvLZxl z0?`hc(~VAo+u)26)iB6R6!!e$;$koL<6sKYcrZyW#bAnf97=*58v!}SXC3@Kufp3- zV}=>OuO4;84kDFg$^fG(|CwTp=GCjj3uVuJR{pfN3C8Bo`M&|9$1t^Ei5E z+$if#U6K%QN8#x74e#iqTLrLNx1U{Eb#rwR8Mb_&`+RC~1WDLNA+^ru|B^8SpgQgt zoPMsV>nZg1Q{xdVu<=^0O?Qc(nIZ&FIpl_NuxbNk(i@mwapS-_Lf633T1XBHM?!7s zYl7DLbI<+7?%8=rXtyY*!yzCe zG^AOMXDE~l38khZT=MGj!;}`GIBIJlDAvQPX}{reZaEMY|45UgBeyrEV9^AHqniPk zn3KB5V(q7VH;ee=9l`NtlD6g1N*kKy2=Swt>*kpROoamuW7c~Dhm1*FmxUE1$2r9S z)`I{#S&aG{MJ8K|FRls8yt~y8{r3oyq)O`78#M~st$D<_QjCbR|DJ^*!^H5cPmMbuM zUnt~@cw9y5h)uB>?-Ux~Qz$0R5Ez_*!#2d98erhTF3!*06m^j=>4uAIcfC(D|!XYWF1KC_AYPhF}!!f?W&yw4(6^P#30gxz+#<4EJ*dh;M@=u zyu?R99!ox5!VZJ5C)CCyAri*9zp223r#%i?Ja;`FWbqmu6s$)ywI5k8S$$ikh?V2<6y`;Bann zw+>iCGlZY}YAayr?%Z^8*@qhakALjfjeN78e2NyWm=99qihw8NUkG3-U|wc_jFjDp zD&j;4R`-E4%krNmB{%YVx=nw_nRwb<=BRMuLB!xF`n}yu@>K?#6K`$+QLbOwjHdgc zP&DR2U*95cn1O?XgZ5qS1r&Rh>AV`jfwCc8t45~MN4z-Y{8Y0g= zWDM+epnQ(+0Ww-WV~^%=JRUZB)pa-g3VQjs$CuPnH>4M-nuINGPDjO4ef z0II;70(0k2=MC6zk(?PCaW>`^HHnE&K(T)o(~8}0ZOB=aRlTkI9$PA|!e1(nxab-JF!u(`e$kK$o+-9O;6`nK7c zuH2_XpLz;L!?(>eMuCXIj@9)1MuPXzIUv zw}(S|(wlRCdzo#(LAgh5g;s(vHqa3Jf|_2e(~h##b-bM3(+#s+m*WM-%ud95RYGC& z0RdPWeyVF>_8h>Y|LJh*dTsLgDve5-f3csYUi0o#R`4RD4B*O?36}$hfr7{&y&tew zJNV;nK-gB8UsPc#Dr`?a|NZ?zM|w9pT$*Q|t+cUGG+o$%^m<1-Ff$M>K=wF)ku4`k zXm6MC>7y`WLCYR9-?rZjmD1!KQBYGkxrJzp+b9+EeU!SQhbmaUiHR~bqWp%}c%Go4Ir@}vmWNZ^ zY|3h2Z;8%&76TO(Qv?-;BdLlC%+lakO(~}gluQ~412lp;fOW(N>>K6x!X+H(J#Is0 z!K*9j-Qz2+Cog@0#k9d*PG{NW-ct7GgB0QhDv&VvXI+?@0tJPyZ%X$`tB>_|D>Yi9 z7ZVlzGMXi}7(vWXSD|jbVTExr_$+?YrD-cQQ-uXCJ)V?!808Wr7FK-4LQy{M4|Ch z@AG@o!&a3LlX!zdZ(wRh(=s6_#Li>_K1olbN1)9UsCehX?h?1Cc6VD#Sf} zE$WOncb`~*x^0sa=n!xIGTMEh$1!~8n%2iJWVsL-1 z@GK7*y(-n_nx30$nJUptLJPw6V()+JP@6-GH?k#wyY|~dx*^n=6lF}JUb%ueN|5&R zY4gIX4%V!L#{Xy>4L5 zmvpZYBrXVdJ7RtDG~rlUV3-&atQ{;_DE|qj!pre#ah%auVin2XAn|h~STFX8US_b&Md^L<3Eb$mg+;w({&p6ztEIous1} z{RMmbOG&p2-x$>Rfm60XRkD*qZT)9~lOCaU~@v2tzl$ap;SJLWH?Wxm9I$3DKuQ5qMBySZVSXTqZvq(|TLYKga7mUj=Xgw0*&v zJHFRsrbS0fD|mww9-FffV*9wJ^UEXp+^ug+xW8>XN+8ui&xEULFme+UAKNK5#`|6H zj3_eIHf@B1(qFt7cQHH=}87KA-9LpWB!NU0Qbg2k)`3O)vfZ z+xS8g8lB|9K|@LGQ|PXJgjUgbQ$}oF>|KR$O1CBQ5&j3-?rwA{M{;4n{8mfjHp9dJ(QRri(YvaB4Oc@1pTaQ9v8*jhP`d+?|1)- zu{^eaa*BwFwE!$AGd(o{&s_tXo^YbEOp$l#D4!>Qmg2GA7U~2QFY^Szf>q)ptixyy zcV{Xhn7r45()XIt#{@zOIM6z0vR(lPelRqzdQWe$(Qxr&nN14CVk5=)8Q3ZoM-C=E zUWg8!j(V6TBL1AkXZ>nF<>ZgUh~wQ(hHyL*C$bnRXR5jvc%x%YQ10ZvG2M5DQ>vZ& z#@WHa4c&4t{h1mX8V0QeH&=X*8ai&5k22wrv;ZSO2g}Dq7+&vpfMCr9q%Q!k;bhL` zc&XFKI@fjhJ=$#OK9dTyIos`zR+D{#7mVQVS7Ei&Hk&Kna?gm1jkUkO_qR3D&h`0G z!LIw0Xik5dt%y9CY-aN3=J9_+Jn~be8voVJS0)WvoAvOcH+Ui$yA}(2+n`mj*_Hns zra-`CG=dj#7f69{q)>SYs2IKv!AF!M7koE9i%~jv++UQvr7rsZ-RP!Wb~ckVd}@Zh z8`&%ol}uW!7e!1$QV|jovM@1`kUEZCdRfa`NZxj~(}mCfaD_1Glgf7*Vl>?ypuXqR;BD;Yd;LReFwP&ZMnxHlA! z%p#Lb)OqRevJWcz6fK*MrYH&^U;Z$l=|j#uYSVO`I6{IUHMF((f0S(WaA8fgwI^4a zV#~dmxW*!igGes@#-l(VlW#_OZ3Y zdHIDK+TnNsG*G05V`S?;X*3gouMbQ;TA|q=0UYu){kPfHLSTh2dwNCSPblWug-nXQ8V3BNFV+~ z-hr*Bo8s$z;t*s|8D**wO|z_t=d}PFnX9v36`*6FsP9KFl*lVk++;mD_nc?% zefCL=sns2VOCCPs4DnxqQ?l~1nT6WqCcHk^e?C0_FDLkHa}oCua5jw zo(8P03fQf!rt-4++z&Td5(+r;@pmb}&M)DICKQ{dIB#-(LYjh&`9}LjgJU{!n(Xf5 z8PW0@sQ1ylqL%>?hr`-_7kctU@^@lFv_Qzkn zqJ=00K){4W|BB(hh{;BdM>{$#75V8lFkvB`J_LzmHM7l0v)^JyND*AOdGnU-x{okZ zheX-;8@0LpS`g2|QyGA-{6bz1=H^ zwrH6e5;Ee89q^vqEkG`m96apjHPhS>!hJ7-3A$&#oanPi)r+H^hpylj-np zKia{lkHS}=2Qm0VxVX>N3Y5zr3&+6C`c-yX)YX4c_mJQYZ9~nn^uO3uh#;t%uoFzf zR*X`YEWz#H$E(rOOGf%J)KtJVDytIULQzv4b3aZQSACj2epqwcseCm0>S5Df|91y9 z8~_k`7WC&_0j0i#XjU~Tp)ITl;z!XzdV1`W7!AnKhYPjBZi49nWu2VA5|$nCj|fs$ zrr2cZSE|cJ#Ni|oaD0n<7|lLtLl_Zt7W~&8(V$&MpH;1>k=?Q#v&yGTSXQde77)nn zYxD*hnHn`J@rU{;>eyc??P-`=-H19Nk`2H&31nLXs3fqL5_5tc+V|U1e`ttWwF35k z+0-l+YXwTW;lOR?m~kXoh-&hDq^!a4*?w>h71|oWgILM!3ngfoV zFAqYwh}d|n`fZiN-RnRElV(N!Y)bvDw& z3+GhL3#UaDjHDQlt`5B#lQ$~Zj)O(4|BFoqNsd;E=jXs{rfr8kUzjqeI}0I^4AYh7Ez5ZRIfm_+$UVfj>Qx8r?c2>cG&RpmF;=Q$`2gBItn@eBIV|vfxfpY+CSSFNG zVY#C`A;K7adRzbYyZs#Li_*L&m1kYD@z1G({@G{FkMkJZcaM=Yn`s9=^OZA1K*Qw7wDF&ZfDuW_!SAXp^ac98CbH&ttRwb zfIJ*h!u2D~sWtMusu%ax4D<}uE?1daO)0ip)hg7w>8I}zz_1q54es2wlaD!9`9DwN zpD!m#VDcjaO4%!p$%6ywfYc!J*h?gRly900;DK0+X_2Q$E>?PjRJtGKzCI6Vh{5OW z2J{ZMR8)ytia}{^1!TYE()Tor)I*inzz2apPDY@Yql9c2^vx6WL@&jJi5&IOxx9dII7;(hkLB% zaKp)a>vP@eoP2b^G2n~Xq##-n&ii(6Rit`mWcSx_&I%*X9v?5Z`n96Z%vSoFw+`D! z%Dno4F=0vb!JU zy5XE^!o9Vu*H8Yz6-rwkuz;UK)!l)AnVyqBG9Yu^Y#|S5Vx;nQsIJ*`6$oY59^~XE zOu!Xf(!$F;cr`gb7|<*Z#NcwgB5W%!H)T6gotBrPj$R`%(FPtZHa65SP+^8T$VV^= z3}(}8G$!w(=uItFi+&`56_Kho%Qh;OHd^a8UWbaxQrszFG{9;~`dV{p|K{7cu4ZSP zR)5O@nv7D-uEMit2dJX6BUad*s31epyB&37aF!DHD6gEfZ14P=qnDL@6z{!%B9Ra_q@X2v5;xCBg2$tzm_!wIV4MQXuMz z6?3%Y|EQJ`HWn>X6(!0{nY2nCm#S>236nei()qPD4%ehjhbONujF3+gl=Wa7g5A;^ z*3)0r?x+ycMuexht}XI}+<+G{f0;#1WbY!@UGb!i^P+_Bbc(5wSwN+4qQ1}MY zv2H|EO3E}5<0U3gujA-eMm~o&RkS1#Zk-d^iX%{Jg11BM0*EtPs6wwuC?c0{c0kulAZN!!p>HERC%(X^HH4|a{5e13#Ku3B8GZvrDZNsL-Em+wCK*vV;P z9u-EUuaB!3;l~fpy(5v=o;`r?H$uohjp?2Vfvc9fVPpShBBp06A71l%A7W!PT6ucNgNxU{aghzaQ8d_Q?~UI7Un;aV08KP)3pk z+OON1W^+%F=^Pnb0KKTo>x3C7qkSQ_Do5zX%wFr)DHHd=U`-ZJQEhj_*>;j)c+UQ0 zKQ=i>pG6}_?v$Ea@00sq(t=IlGh9b`7Wzg(Ic z`;1W>Q_F9e*m|khmNB%^=<|og4@U^-817duyv5)Ya@hIZB15eP!GN(p~p#^p0+uT`NH@zBw>{2vtRd`g#8thVT??n zKMG=jf8wS=6Vb&*eq~)@6Sf+xj+qxXJ2HhP8jbhdNd1=BA9Z8?>_&kPN(=jLn-niHbJLHbXm4=vqfYW*6Zf5U zk=EU-${k`V?Nvm>NZYFrd$y~*p|L{I!sI-h!jc1*Ys=;G87Eni*O&j)t0X;ITRTpF zx_fWo|M58n-#&-Y*VsD6Rnymp1lw3&R}r`fze za=9aZ+Ib{o84h_#+fZxq~rHwOr zdfqd&ecQWAt9y4U-6S$vKNIK3~-39G&;2KR$kGfM6(#cGs1RKyrG zTpCQkCUYxxe4@tX%jd^-6kq`?X;jj3?I0)<9MEF3Q${URb#xRMwd=}|XDSv>NarduBk331|$H zaEsbY8jcW8Y1^`5>~Y>Sz+BmJ>qNrrPPNNfquJ>fF^Kv=dE@SFx<=(ZLBzBaf+WMF zQlBv-lQn|b)UhIpiNPG%KC}Jmj$#l}X^DE!u=9g|)&#@C!s`I)fJ3iqNtEJIW0$TJD$%~ND^SGHo z;Kd{v#SmbCJa^J$?l89qP_()G@|FA9!sO}PPy{6ZH{z$yi>??x^GzMj-1?Nsny8>> zM^0105{hy9+G4C0?CSP3frqiAOwJcj-;Ej6bD;xfLOZo$8Z@`?q{95g<@9;M0(cpM zkI{0hZ**Rx<{B4ZdB&8{;?C`77H|v`d4I(HuaftRnGl9CUSD5b&kRv_G6b#$|BP!FwfexxyXFNO z#smh){=zL=cl>*WW#<2T4kZi&-HIN0^W2?`vOcR-1^mU1owi~vpb?fkodv+i=IU57 z9}D_ASeVAuaJDRu8O5BI7psn^B3je!3f9~U2D^9l=(R*3xs#aAKmNaMwZu0OVj|+&rk7@2|OzCKr z%}x-oMO)-hS%#tv`3U63j>nXt@gX!^aD*I?0y#I4vYUT;=60~qMYXemij&JVoKUtO`DHU#(|*sVE_Tn4*ssMAh+A2oCX z!cR}_0RQ&ob`ZFsQl5ou=sE_ZGT-0uJNCznA;FqfnHCooRJn7-l$d2Y4J@upZT~o^ zTy=97jwGx?m8mmb%gs5z9J3h*tmdHuQl93FsS5GaUSsh>-Ez13YeMWmhPfq)Z^MWM?8d4;())V>QMxl zE44rWTdIZ`eaJHalsJ_RuqaGlc=Wj<*%qiO4j91WOw~aH#_avu4MK>2oEz zYexMSTIBc*qLAt%GHHZ5I6rPXS&ri$KHQ|&TOK*@1l-(I&@JoV48G+3?Pl{#gApqU zFzO~x=o7zxEP_aE<{j9TBNP;y-#NOuYc^Wg)^>}eJNz+)PRlAt6eT~7b4(_{VUdl z@U02H?Hyk4>hr9(*9*gxl-e5F=9O1Q{m>yM@DKS=wQ}}Me?Yoey<^)a#OLp4M?{_r zLYMC)Re%r`!N(dRpzE5j{w)APd9y&&Q}KBnzc1pM$)WBvK1b*2w6?DjZ;sGEs_+hc zVU4nG(@-|$*Jj8OALA0#%F`aSo6JbIBq$J0UAy97a9V&e*VlT1>p~Lmjf!>1qXlnk z9iH|!?uxeluM&9H;b49Sqd)b7?^eshQ>Y3nU@kX46*FrE0KYTN?ad-s z5m7fMYffvLLk&Hht7VcqYJ1Su1%Vt^+&E+G(gSsL9k!W~8Vs3$qf6udVF>Wz60+&1j}MP&m2EcWy%m1V*Z+BEMy_e9H$;*bX*)eUVqtbSc)#(rei3z`HcWcl6|w)N}par(MKO$ljS2XtVvQOpuu7X`Y`m*N)VybO%2D zl(b~6*{6h??of*za0nfF^9Tsf04}o%Y3b|qE3#z&M1siwxlRw-I8;_72^(P|S*LPQ z3E!?WHs7bnw1Z6ulI&eoPhydvM9bJNdJnB;5T`FJ~^!raiWVmoX0P}q29OfC(xD-(3b)cz%wPvCp#Q&cd#O zi9)+%=dRbTo?OW54%Q@{H*hXM!j7*tbZ4Z#}Ubw1v~LlUXNXSWWunbl!Po6 zgRkLk3jqsZ1h?FGy9W1s-p*!=q?R^p@63FYmC{CFx%v(gTG2a$*HeEOT|S?b74Jt6 zD2M`9LY{9}>Qy2z2UO;{)0rv$W8d|^14%wVU};eiI7&y;zWLr@``gyAP?;3IT$rN~ zMlIcr+d#pL^DF(##qCyn2#|iIb|U)w29`+{cDPYqsRV|1s^)7Sq zj}RvAo8B`3gU57(=6S>v*86@m=FejjqRXX}4$M8RPR(X{ofovi3T+-Ytozh!TLI#y zCPAMAtZ|S%{ZVl=4*}c6h+zB@IfX;h4cw6HYA&YLNMjpLJgGpexkn{ch4DmDZgafm zZ|2|Wnj`!J;rp<%k5voG_9)`T6aJblYEn)6S=ow_n|i-7rn~Q}wR+hJaBImJ4I6qp zvGn}|HIjroPYDQ4U2a|~%-)1hz48#4A>A9XnbtATFMYPv1mB-246Z*?8FFG-;iz0H z_Eg@ye(%y+E4<1MkdKjZ=D8Y-fcvQoPao!q1$;nm`Ztvs_s_rgtwOP6-xML=YT!@1)xR^2X)rMG(0TWm8#`k6|%XO;2pz3e0X@d$0xFtnw`eP zWjUS#jQ24*?7D{V5L^`;2S16&F$=$a%bPyX@2t>erM)LgkwzkY_t7*v8;j!wb;3AW zP6MT%9!Q+nwq%9ihQzQYYE=%p1VpMw$hUZr8-yNYl8|qKT09e!sRb~YPwg{*qpltn z+~F``O~!0U$Cr^dwG}_iQn32U6`A~0AgNk=g6+DjF%Ifcu2I9%a@6V>IZE2fVN?X~ zFsz7tL$mz}cM$OscoS{UD^u_~Zz4N(M6M*Cw=42G_LTF(KtO%}%)w&%zMt)V@X#(M z$(|$YhBU83kANK^c<_d6x^#YJT7o{vdWHJ5r@z%rc9YfF6~8p|NRTA-AV{Ocm*x4- zmXLtWzY-m3J~A3E&d3{D_hUnW?J3eH@6ew(V2;oG$BujD=z+J12^envo1vnR3HPJmK5y6iSS}qsx$MPT z|CY#zlt?cMp<|DLQ|}QulA}F1BnUo$g(Ut&d$iL-p|phx4s4S==sP7z%eyteg2b>y zVeG-kwp)8=rX5$~oY5ztd#DDz^~B2pqgwAPXa6-+mj3vLf?!h#edMnV{}+OdZz9H! z-pb5iGnI0FD-y=tbEYI@fU~s8QOGW>@uh5qLb*_^i56IiIY0Sm>5`5c6Y8w!nZM%VI#S~?}dw~X^RA}a|g!z zqt1)%E5;fe?BT%!EV%WIe+F=?N8~cpyHnQN6B6Pd62-|ib8YIlViy;KC)|Sk@!`W{ z_(GDw9EAE$s2ePpTq&Wdg{?-SwtNKU9Pp;oc(J5!cAk~;{G8efA~=2>PyN7~n;eh7 zQYk*%V*REdQNaW1{v}UZ&59(;Fpm`%6&bb6#;J1DYR0-wn8KP&R|)LSm@5O5%cUz) z2AM1E&-Y5X&Z_`qGiN(=51cc)L0k1KYWu5Sn;ZY<3Iai<#NSZvG zWivkLZGzJ?T}yZYZd)L(Bg3s6SVuVx>=I2%D3Dpm-uc4}a-w@fAugUk?2p-JVIuXP zT_)M4yP7RRQ_)7up6j1~u&0qdWY;FiR-7f^1jP=Fbr)L1Dg5jW6~#;4z|tJ(2s)Z; zV4o&)I(R2*H{94*LHPXiI>cowvezq$1aB^_arH;BNIVSis7w;BX{S1syb#(l; zxU_T%6HC<$5wCy0RkTHzSE`(hAi8IY%@&qLCtvA8ZyH*vNP`&6XG|9wUD;M1Iex(I zy1IRk5JQ(MWx&jFzBh)z%t4tuiIF*O;F%-oMi8tx=ov$b;UsJfhF(-(pHcMKHzL<8 zc*Jf#QJDZ(Pjdv^;CjmF+sCO1R73ag9I2f-Z;aYXX6DHasil>P7e(_Xri>qe?zg^eAcuuxt}z3wk34q5#s1&>JEpvV3k-vx?$?(yfOk8 zifwhl1Q@tuT3-6u)TQ-hl~yh;LEE^PmcdL~Q!?Ye0c+!Ougp4eL&tAF+)AKDgO#0^ z()g(rtlV~_J*ozLlk6|QjeLjnc)Bkx>Om23{Gwj71Uk-aiS#82elm66zOMhRmTB0x zE4nNYE^uFJcLfTemZ&n(Ba8VSqIUg;MOXbLmJLoP(aBvi07ettH)J!IR%1$sOIU-P#X zj1X0ry>b13kYb07?C}v@KmLdWBKubkrYD!=t$4-Ana$M*jUEp?VgEB%L6`N#6~{48 zUW;C#>w$Ouo6(;Yjl+kzr?^yNQ91Z$YXUc)yU@{1=wk+t+YRZ!V`XGCLwuFFZ&{`_NAzAgz|?Ij8o#PMEZ_7A6eL1p~v}`)?LtoVoA1sP1{g zYLE4+{tV!GGQZ+6)^>b+9{G>h-T-C8kH9I%3l&rl6C3*cT9tyof|BFFun?s7-T1m5 z-n+f;Rz?2neVXR7IEI`t3y^|zC8>_Fukccf7jL%N2+)3M=VKUA)z}!8IqrrN#qB+D z%4x&pg=m7`2ByQH?LJeUniVg|=NzT$<2~Sc>PE(7*J`hE^_gwu$GeRpo(KZwh*PNP zpgw5p@Iw4c5aJTJxRRm=n;~m`KRde`LD%u#Gof z(3lKwNI)c}e}eb5)V=Xehi0!xpkXlk$S`(m;*Y)xx2leQ*z51_wR+3U+ntW_9$<4k zY-YRo6CjHQ(0|R%6!_{i(YbGD;68tGd^JrO+k}Vr*E}_aaJN9eerUJiYD8NDWu&pF zE~JF2jV*+fmX>}@nmbUml+()G9C9<@Ch+|>Czs8#u!N0O_1efE9IUJ(-kI0~?lB(_ zC%M@}5v+dvlrP$GLBe7F)m^@O273{a;VMwvY6;ic#_89e8WCqS;yI5x7?-peIepbA z0_vOW(5nCl5(H4e@S8iIv)Y(4?~DxqKyFUNdpzcszao&?_1;Z3D9L1 zUu59l6N_koVV&<1soj<_QwEbr{qxBxul*Fu?277@Qay3H1nyd*@~Q*OrO;;hW1@1` z!$$Xyo$301mikZP@A^4vI{JvFbl|M=uJ~MhH`c#aVsd`V&0R%R84S?!^Z#)jZx!jk z4@;7ekjQVEwBW{&hjZ(M8`thi%Dw79bq{o5zkLzs|6+qS$s$_uipYcK0WPUtq4H0HhflSX**Wj#nOZ3*Xx#}h>% z3*BLiX<2X9q*bHc!xng@&G)jBX?dNMoO|ftUAJs*LJ=6y<``YfM7`ELYN|QC>GgD9 zWMIX)u!xRcR8*f>-*NfWvF%5j%~|adN8BVF(K@za*{nw(+=4x>Q!mY(%Oxn+XU6K* zNn`{PDKzn<32p``-%W*zfv;rpb*@$;E3<^=tFccp?BKqkfj*svilGHiAN_LBdety6 zw;Pd6qcZgvd{IXwrB{dr4l&i3Dv9-+3w%&3QVNtq z(g_=Iu6&O~)5(Fs9d)hQ%k^iCz)r(|-8QyP`=ui{C%7G1od`aM`N(Kuv=KjL5tsi2 zmoaWi=-YD;5GtMPu};BY!$Cs&fc88Z5D`W4XyxkBH&aXrVet|*P@W224Y9}zeWYWZ zkgt(A?J6Py{#P@N*F9UsHGhE8#s=>*6@~qOkL5U3v+*B1T0u>er0r7YDRDpROcmU0 zKj_ki22#KCHcFDfbK8A4bWq#Y1q5a0k14Pv%U#UO(59GnUvt{Idk^iI5UL>!w7A{j zA5S@_&R5AzJ#ccEMfq3Z7WTYVs8Q@3udufr4@s!oA`LHW!mk#NW|GZ>#}{Y7bP*v~ z+|Tpx2M!@AlMHVHfg3hgrbxucV(uE0Yu|GhHZQx$E)X(0ex< z_onZ?;(jw7glSPVK>>t^Ms6s=dh?0AiJ9SMsIZDj(opHKu(1-z|S5o+}xk=k;*sF!LTWk7jL&umYw z#Tv=UwcFI$JIE5`kK^m>i=C)S@(C=g9hAy6OtNGV`4#R@*6<2isJvyZ;c`gWV|FB; zbpYWTu_r<#C-++LLabJe>q~3xryQs_pXXSpEnRpq!x|Hy13ODTC87qsL!nuQZDybNTJi zPQSieCB@>dC-Z%xs!RgFh_a7d-01O36nga2F7%<5u- zIf?+9bv}Qt%G=KLan+I0VU9r}*st~mQjmh)?cz}GOI&wOI3!nkzP>8lP6{##W~}dq zR!TsIN45&J1~rOSYzB9Dza}vMb3kkyYJsq%f$;)Y0Z=+$uiTv6oG#pFFNcqC{$zy} zk+1xDUWYL&9uj*iF^j2aW5 zj!~6nteQrudCEAgH2V(PVx2A%KAz-btCtI{9l^Xfpwbf;Y2S?-Ut+$2c*7rj*evDj z?36CH>5?}u&E*kwzu(e}CO4r8H0|?1v*8ps$~O(_jrECcI#I))mMy_V^`&SFwc0u5W!17J3^9S6l#^Z0i(GVM)h@=ic)lKIVZRw=3xBL)3Hf( zh+znGHHzzrt}{~=^efY^t!7C>F>Zt2cxLJ>e#PV!!+gBe%$Dz&H$+51LFTVk{||U{q@>l%LPJwr64|6Kz_GB7>{R2cOaE92g9*C`}40L?6xnUZ$LxOLh!pp z%gRpQb9Li2l}|X?9kPjB7l|r*w(MUG9xHPO6F|RQ@G}2=DSK{&38vU&MtTH7z1izv zFR??JcKNi=I{pg_pY&gBu%GtD1J!_RslfcQ{xpnE3D$(P3NvV91DP*A=;_B;qHhh( z>2svQ9V3-4)Q=Tn7uKBvQPAQ#>7#_A8Fm<#!!#GeM8ZQEO20VXZ;m-N6A02e zPT7%@JqS_j%XT&5Y0wFoR>K1VV-RZM8GqE;y>@rhw2EIZCb#)x@hg3@p7la7(&-)= zN{aEpZ*;Yd($4+Rzk~a&!V^ckIKUPR8mYbq$Exd}XP`2rCmrgm=yxFdm9z^%(m1^* zzr%Eb3E(ep%A(`l=i%JUZs|dgb1&F+D@MM398F*-`{Kw7P9v}?N*C@%cvr;Hs1_oT zO!s4$0WMaF>aZMj<(!~SLBL2bchl5qR=4*@e>l|7TX)jkj5A%xKb!$ij8g*xJpW=_ zRLl);62l(kRX&9kIIIUeDu}zJ7@1qWy;+uJDY<`zUl*5r4l=Rt`7+2Ve+23{w*o;JxO9<1hj0~ju5xu9YJKoDwuVhNM>9LhkWJH>z z7L-a;8)q;f5(}O=oVtxW7(>g)(Wz%zsNA-(vX4{C#9u2(o|Jln3M`x0FmLEM z$4Mfw>YZN0-p!*F=)87JWfA1gx+}#+ZbcqhhX$kkHx$?JUH^6{79s4*^M+s4Ln3QA9qG*Rt`pk$%V3sB=r|ThPr9h}>*=hr~>+2L;d1KV5c-fZEa`kY%8XGpD4)vI$oixab{bzLO!`2LaZ5#|oy@2D%UnUWawyK>aAQK+ z3mVCU7&u4Qk}G{6!^e_s7DWUM$h2B>WEiRJ=aDWib1(Rt(q{aWfKS1}v~26pwoHWu z2IjV5==^yenppeh{xC{hr8G>P6GJC6&gWD|}^kpIf46#7$Xr4dM@oF@Af^= z9_z0QCZ%?jC2o*EMm5H9jMz*cS1r|$zJ_LW&6YxgYaP~D&{B*}e$GOVP(}QAl2(8h z28nlQbh?JtTU{b@&}J_W$ly{b6~sOBK_rL3SrJ)rSNLrh zAraSd)?*54y|z*m`ZpC_f&|xmp}$^>l+ZIWDjy~m^&RC&3|>pOAZJyT!(e~9tqWc; zD*HurRTO!obK?egk(%3Pt~mRFK%h=a|wAS;Qgv ziY!yCYE0hvT+c>B;3Cbgj2;gp|NQ94`+kWd$2HHw89al+6fXUM3rqVuJusNr7C>fc zR60CvDc;1q?_#2Q;r8=tN{u+80Wp(Z%*B)y=b$ZD^k;ScCmHp`P*!buGeNA-ekvcQ zZRR?S-gC^7x==Pn+d+MM(U{sV?EGNr^|A8bf^Z3?JL&=VGMnWCmku7;DIEV+kwsB7 z>7 zd*3HOqx=&PO_$kHK58~Il!iHYF&2)K(Pc8P+|SKn)!K@5ZvV|@Z{OCsT1)aP2;8Dg X;lQy&J_PiCATT*8WyyMRlhFSG>t#bB diff --git a/ampache/ampache-resolver.js b/ampache/ampache-resolver.js index 59e32516b..59ddbe706 100644 --- a/ampache/ampache-resolver.js +++ b/ampache/ampache-resolver.js @@ -406,11 +406,19 @@ var AmpacheResolver = Tomahawk.extend(TomahawkResolver, { var return_object = { prettyname: "Ampache", description: desc, + iconfile: "ampache-icon.png" }; if ( typeof( this.trackCount ) !== 'undefined' ) return_object["trackcount"] = this.trackCount; + //stupid check if it's an ownCloud instance + if (this.ampache.indexOf("/remote.php/ampache") !== -1) + { + return_object["prettyname"] = "ownCloud"; + return_object["iconfile"] = "owncloud-icon.png"; + } + return return_object; } }); From e625a9dea68f416a0b660eee310cccb50c932f15 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 5 Mar 2013 10:26:14 +0100 Subject: [PATCH 040/118] Add different text/icon support to Subsonic resolver for Runners-ID i.e. Submedia. --- subsonic/runnersid-icon.png | Bin 0 -> 92393 bytes subsonic/subsonic.js | 15 +++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) create mode 100644 subsonic/runnersid-icon.png diff --git a/subsonic/runnersid-icon.png b/subsonic/runnersid-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ef2379d45f149541bd7765dffc33728b1cd05d0d GIT binary patch literal 92393 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

lWZa6LyXAsJq!kjc5B&V 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

8uh9gQQ%p7dM38~&_JwRn6$~BRIS8c2 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 Y0I5oHcGL@4)Bpeg07*qoM6N<$g2f+i#Q*>R literal 0 HcmV?d00001 diff --git a/subsonic/subsonic.js b/subsonic/subsonic.js index d05f0aea9..d9e0f62b4 100644 --- a/subsonic/subsonic.js +++ b/subsonic/subsonic.js @@ -413,18 +413,21 @@ var SubsonicResolver = Tomahawk.extend(TomahawkResolver, { .replace(/\/$/, "") .replace(/\/remote.php\/submedia/, ""); - var collectionName = "Subsonic"; + var return_object = { + prettyname: "Subsonic", + description: desc, + iconfile: "subsonic-icon.png" + }; + //Icon and text specific for Runners-ID if (desc.indexOf("runners-id.com") !== -1 || desc.indexOf("runners-id.org") !== -1 ) { - collectionName = "Runners-ID"; + return_object["prettyname"] = "Runners-ID"; + return_object["iconfile"] = "runnersid-icon.png"; } - return { - prettyname: collectionName, - description: desc - }; + return return_object; } }); From 5deb9a576e1de323515265345cb0f0b7068bad29 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 5 Mar 2013 10:34:17 +0100 Subject: [PATCH 041/118] Oops, forgot the icon. --- ampache/owncloud-icon.png | Bin 0 -> 13389 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 ampache/owncloud-icon.png diff --git a/ampache/owncloud-icon.png b/ampache/owncloud-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..36db67e1badbccf81d889aae335166edba5d43a1 GIT binary patch literal 13389 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 X;lQy&J_PiCATT*8WyyMRlhFSG>t#bB literal 0 HcmV?d00001 From c1aa0d23741c894d424322d5d0475421165ef3cc Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 5 Mar 2013 15:15:08 +0100 Subject: [PATCH 042/118] Use new Ampache logo in resolver config dialog. --- ampache/ampache.png | Bin 7595 -> 20319 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/ampache/ampache.png b/ampache/ampache.png index a106239a8355aedde39c3dcd32956bb46576e06a..f1cb5e748c6f40381a8af11d6626eb33ad79889f 100644 GIT binary patch literal 20319 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 OV=^^F8B`-&qyG=Ephma= literal 7595 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 N002ovPDHLkV1mGe(zO5p From 166efe40cd73c550616daa19104d0df9ff3c9321 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 5 Mar 2013 15:20:58 +0100 Subject: [PATCH 043/118] Resize a bit. --- ampache/ampache.png | Bin 20319 -> 20271 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/ampache/ampache.png b/ampache/ampache.png index f1cb5e748c6f40381a8af11d6626eb33ad79889f..b943c16369b7467de0f7a1d4628c1b9a6ab01e95 100644 GIT binary patch delta 4810 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 delta 4832 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 From b853e0a4386b2321efcef4a918d32320b4bce549 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 5 Mar 2013 16:14:38 +0100 Subject: [PATCH 044/118] Made it transparent with the apex of my GIMP skills. --- ampache/ampache.png | Bin 20271 -> 20443 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/ampache/ampache.png b/ampache/ampache.png index b943c16369b7467de0f7a1d4628c1b9a6ab01e95..2866642449c11a66f53ae97ea7b9bde1efef0c2c 100644 GIT binary patch literal 20443 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 AvH$=8 From daac349e018efcb142411bf28a76ab4744852050 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Tue, 5 Mar 2013 16:40:56 +0100 Subject: [PATCH 045/118] Add tracks tags in musicManager DB for google drive resolver. --- googledrive/googledrive.js | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 7fd5d7a11..60eac6104 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -93,6 +93,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { this.oauth.init(); musicManager.initDatabase() ; + + musicManager.showDatabase(); this.googleDriveMusicManagerTests() ; @@ -139,7 +141,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //Tomahawk.log("size : " + item['file']['fileSize']); //Tomahawk.log("mime : " + item['file']['mimeType']); //Tomahawk.log('url : ' + this.getStreamUrl(item['file']['id'])); - //Tomahawk.ReadCloudFile(file['originalFilename'], file['id'], file['fileSize'], file['mimeType'], this.oauth.createOauthUrl(file['downloadUrl']), "onID3TagCallback"); + Tomahawk.ReadCloudFile(file['originalFilename'], file['id'], file['fileSize'], file['mimeType'], this.oauth.createOauthUrl(file['downloadUrl']), "onID3TagCallback"); } } } @@ -239,13 +241,22 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, onID3TagCallback: function(tags) - { - //Add track to database - //var url = 'googledrive://' + fileId; - //dbSql.addTrack - Tomahawk.log("Tags : "); - Tomahawk.log(DumpObjectIndented(tags)); + { + var trackInfo = { + 'id' : tags['fileId'], + 'url' : 'googledrive://' + tags['fileId'], + 'title' : tags['track'], + 'artist' : tags['artist'], + 'album' : tags['album'], + 'albumpos' : tags['albumpos'], + 'year' : tags['year'], + 'bitrate' : tags['bitrate'], + 'size' : tags['size'], + 'duration' : tags['duration'], + }; + Tomahawk.log("Adding : " + DumpObjectIndented(trackInfo)); + musicManager.addTrack(trackInfo); }, //TODO: put that in QTScriptResolverHelper From a42410e299a8bd3f394748233d008d3f4b6be7bb Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Tue, 5 Mar 2013 20:26:56 +0100 Subject: [PATCH 046/118] Cahnge custom url handler to show a hostname. --- googledrive/googledrive.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 60eac6104..7e77be0c2 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -159,7 +159,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { qid: qid, results: results }; - //Tomahawk.log("google drive resolved query returned: "); + Tomahawk.log("google drive resolved query : " + artist + ", "+ album+ ", "+ title+" returned: " + DumpObjectIndented(return_songs.results)); Tomahawk.addTrackResults(return_songs); }); @@ -173,8 +173,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { qid: qid, results: results }; - Tomahawk.log("google drive search query returned: "); - Tomahawk.addTrackResults(return_songs); + Tomahawk.log("google drive search query : " + searchString +" , result: " + DumpObjectIndented(return_songs.results)); + Tomahawk.addTrackResults(return_songs); }); }, @@ -221,8 +221,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, getStreamUrl: function (ourUrl) { - var songId = ourUrl.replace("googledrive://", ""); - + var songId = ourUrl.replace("googledrive://id/", ""); + return(this.oauth.createOauthUrl('https://docs.google.com/uc?export=download&id=' + songId)) ; }, @@ -244,13 +244,14 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { { var trackInfo = { 'id' : tags['fileId'], - 'url' : 'googledrive://' + tags['fileId'], + 'url' : 'googledrive://id/' + tags['fileId'], 'title' : tags['track'], 'artist' : tags['artist'], 'album' : tags['album'], 'albumpos' : tags['albumpos'], 'year' : tags['year'], 'bitrate' : tags['bitrate'], + 'mimetype' : tags['mimetype'], 'size' : tags['size'], 'duration' : tags['duration'], }; From 2ff8dfd15f97c3f55d98aca32d4643fc7b79eb82 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Tue, 5 Mar 2013 20:27:26 +0100 Subject: [PATCH 047/118] Fix if not all tags are given when adding track. --- googledrive/musicManager.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/googledrive/musicManager.js b/googledrive/musicManager.js index cd18a1289..8206f71fe 100644 --- a/googledrive/musicManager.js +++ b/googledrive/musicManager.js @@ -44,7 +44,7 @@ var musicManager = { tx.executeSql('SELECT * FROM track', [], function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; var len = results.length ; var i = 0 ; - for (i ; i < len ; i ++) { + for (i ; i < len ; i ++) { Tomahawk.log("id:"+results[i].id+", title:"+results[i].title+", artist:"+results[i].artist+", album:"+results[i].album+", url:"+results[i].url+""); } }); @@ -63,18 +63,18 @@ var musicManager = { addTrack : function(tabTrackDetails) { - var id = tabTrackDetails["id"]; - var title = tabTrackDetails["title"]; - var artist = tabTrackDetails["artist"]; - var album = tabTrackDetails["album"] ; - var albumpos = tabTrackDetails["albumpos"]; - var year = tabTrackDetails["year"] ; - var genre = tabTrackDetails["genre"] ; - var size = tabTrackDetails["size"] ; - var duration = tabTrackDetails["duration"] ; - var mimetype = tabTrackDetails["mimetype"] ; - var bitrate = tabTrackDetails["bitrate"] ; - var url = tabTrackDetails["url"] ; + var id = tabTrackDetails["id"] || ''; + var title = tabTrackDetails["title"] || ''; + var artist = tabTrackDetails["artist"] || ''; + var album = tabTrackDetails["album"] || ''; + var albumpos = tabTrackDetails["albumpos"] || ''; + var year = tabTrackDetails["year"] || ''; + var genre = tabTrackDetails["genre"] || '' ; + var size = tabTrackDetails["size"] || '' ; + var duration = tabTrackDetails["duration"] || '' ; + var mimetype = tabTrackDetails["mimetype"] || '' ; + var bitrate = tabTrackDetails["bitrate"] || '' ; + var url = tabTrackDetails["url"] || '' ; // Check presence in the database before adding this.dbSQL.transaction(function (tx) { @@ -111,7 +111,7 @@ var musicManager = { for (i = 0; i < len; i++) { song = { id: resultsQuery.rows.item(i).id , - title: resultsQuery.rows.item(i).title , + track: resultsQuery.rows.item(i).title , artist: resultsQuery.rows.item(i).artist , album: resultsQuery.rows.item(i).album , albumpos: resultsQuery.rows.item(i).albumpos , From a0f379f81948b7ebd9e028850873ef0e1ee24758 Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Wed, 6 Mar 2013 13:03:47 +0100 Subject: [PATCH 048/118] -- --- googledrive/googledrive.js | 14 ++++++++------ googledrive/musicManager.js | 33 +++++++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index ecc7a613e..6cf3b2372 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -167,7 +167,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { qid: qid, results: results }; - Tomahawk.log("google drive search query returned: "); + //Tomahawk.log("google drive search query returned: "); Tomahawk.addTrackResults(return_songs); }); }, @@ -180,7 +180,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { qid: qid, artists: results }; - Tomahawk.log("google drive artists returned: "); + //Tomahawk.log("google drive artists returned: "); //Tomahawk.addArtistResults(return_artists); }); }, @@ -194,7 +194,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { artist: artist, albums: results }; - Tomahawk.log("google drive albums returned: "); + //Tomahawk.log("google drive albums returned: "); //Tomahawk.addAlbumResults(return_albums); }); }, @@ -209,7 +209,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { album: album, results: results }; - Tomahawk.log("Google Drive tracks returned:"); + //Tomahawk.log("Google Drive tracks returned:"); //Tomahawk.addAlbumTrackResults(return_tracks); }); }, @@ -217,14 +217,16 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { googleDriveMusicManagerTests: function() { musicManagerTester.flushDatabaseTest() ; musicManagerTester.init() ; - //musicManagerTester.populateDatabase(9) ; + //musicManagerTester.addTrackTest() ; + // musicManager.deletionWithoutKeyTest(); + musicManagerTester.populateDatabase(9) ; //musicManagerTester.searchQueryTest() ; //~ musicManagerTester.resolveTest() ; //~ musicManagerTester.allArtistsQueryTest() ; //~ musicManagerTester.tracksQueryTest() ; //~ musicManagerTester.albumsQueryTest() ; //musicManagerTester.searchQueryTest() ; - //musicManagerTester.showDatabase() ; + musicManagerTester.showDatabase() ; }, onID3TagCallback: function(fileId, tags) diff --git a/googledrive/musicManager.js b/googledrive/musicManager.js index cd18a1289..d3376da30 100644 --- a/googledrive/musicManager.js +++ b/googledrive/musicManager.js @@ -75,15 +75,16 @@ var musicManager = { var mimetype = tabTrackDetails["mimetype"] ; var bitrate = tabTrackDetails["bitrate"] ; var url = tabTrackDetails["url"] ; - + // Check presence in the database before adding + if (id == "" || !id) { Tomahawk.log("Insertion intented without an id key"); return ; } this.dbSQL.transaction(function (tx) { tx.executeSql('SELECT id FROM track where id=?', [id], function (tx, resultsQuery ) { if (resultsQuery.rows.length > 0) { Tomahawk.log("Insertion abort : data already inside the "+this.dbName+""); return ; } - }); + }); }); // Track Insertion this.dbSQL.transaction(function (tx) { @@ -95,6 +96,7 @@ var musicManager = { deleteTrack: function (tabTrackDetails) { + if (id == "" || !id) { Tomahawk.log("Deletion intented without an id key"); return ; } this.dbSQL.transaction(function (tx) { //tx.executeSql('DELETE FROM track (title, artist, album, url) VALUES (?, ?, ?, ?)', [tabTrackDetails["title"], tabTrackDetails["artist"], tabTrackDetails["album"] , tabTrackDetails["url"]]); tx.executeSql('DELETE FROM track WHERE id = ?', [tabTrackDetails["id"]], function (tx,resultsQuery){}); @@ -209,8 +211,7 @@ var musicManager = { tabTrackDetails: [] , init: function() { - // Example of structure - this.tabTrackDetails = {"id": "22" , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + this.tabTrackDetails = {"id":"22" , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; }, populateDatabase: function (rows){ @@ -289,5 +290,29 @@ var musicManager = { } }); }, + +/* + // Test Scenario + insertionDuplicateTest() { + this.tabTrackDetails = {"id":"22" , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + var test = this.tabTrackDetails ; + musicManager.addTrack(test) ; + //musicManager.addTrack(this.tabTrackDetails) ; + }, + + insertionWithoutKeyTest() { + this.tabTrackDetails = {"id":"" , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + musicManager.addTrack(this.tabTrackDetails) ; + this.tabTrackDetails = {"id":null , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + musicManager.addTrack(this.tabTrackDetails) ; + }, + + deletionWithoutKeyTest() { + this.tabTrackDetails = {"id":"" , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + musicManager.deleteTrack(this.tabTrackDetails) ; + this.tabTrackDetails = {"id":null , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + musicManager.deleteTrack(this.tabTrackDetails) ; + }, +* */ }; From fa3531e785283f6afc8b2e82254a0882bd61986e Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Wed, 6 Mar 2013 16:26:17 +0100 Subject: [PATCH 049/118] Use downloadLink to play google drive files --- googledrive/googledrive.js | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 7e77be0c2..6c81a868b 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -96,7 +96,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { musicManager.showDatabase(); - this.googleDriveMusicManagerTests() ; + //this.googleDriveMusicManagerTests() ; Tomahawk.addCustomUrlHandler( "googledrive", "getStreamUrl" ); Tomahawk.reportCapabilities( TomahawkResolverCapability.Browsable | TomahawkResolverCapability.AccountFactory ); @@ -130,6 +130,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { if(item['deleted']){ Tomahawk.log("Deleting : " + item['fileId']); //dbSQL.deleteTrack(item.file.id); + musicManager.deleteTrack({'id' : item['fileId']}); }else{ var file = item['file']; //Tomahawk.log("File : " + item['file']['title']+ " is supported : " + this.isMimeTypeSupported(item['file']['mimeType'])); @@ -222,8 +223,9 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { getStreamUrl: function (ourUrl) { var songId = ourUrl.replace("googledrive://id/", ""); + var meta = JSON.parse(this.oauth.ogetSyncJSON('https://www.googleapis.com/drive/v2/files/' + songId)); - return(this.oauth.createOauthUrl('https://docs.google.com/uc?export=download&id=' + songId)) ; + return(this.oauth.createOauthUrl(meta['downloadUrl'])) ; }, @@ -323,7 +325,6 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, ogetJSON: function(url, success){ - //var that = this; if(!this.isAssociated()){ //TODO throw error NoAccountAssociated ? Tomahawk.log("REFUSED Get to "+ url + " : No account associated"); @@ -340,6 +341,21 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { } }, + ogetSyncJSON: function(url){ + if(!this.isAssociated()){ + //TODO throw error NoAccountAssociated ? + Tomahawk.log("REFUSED Get to "+ url + " : No account associated"); + }else{ + if(this.tokenExpired()){ + Tomahawk.log("Token expired"); + this.getRefreshedAccessToken(); + }else{ + //TODO treat case no parameters given + return Tomahawk.syncRequest(url, {'Authorization': 'Bearer '+ this.accessToken}); + } + } + }, + createOauthUrl: function(url){ if(!this.isAssociated()){ //TODO throw error NoAccountAssociated ? From 7340dcf62885602f469b1d1e5927c5756304eb64 Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Wed, 6 Mar 2013 16:34:34 +0100 Subject: [PATCH 050/118] Safer Addtrack and test to proove it --- googledrive/config.ui | 0 googledrive/googledrive.js | 12 ++--- googledrive/musicManager.js | 104 +++++++++++++++++++++++------------- 3 files changed, 74 insertions(+), 42 deletions(-) mode change 100644 => 100755 googledrive/config.ui diff --git a/googledrive/config.ui b/googledrive/config.ui old mode 100644 new mode 100755 diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 3356fb875..910a098d8 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -94,7 +94,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { this.oauth.init(); musicManager.initDatabase() ; - musicManager.showDatabase(); + //musicManager.showDatabase(); this.googleDriveMusicManagerTests() ; @@ -229,18 +229,19 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, googleDriveMusicManagerTests: function() { - musicManagerTester.flushDatabaseTest() ; + //musicManagerTester.flushDatabaseTest() ; musicManagerTester.init() ; //musicManagerTester.addTrackTest() ; - // musicManager.deletionWithoutKeyTest(); - musicManagerTester.populateDatabase(9) ; + //musicManager.deletionWithoutKeyTest(); + //musicManagerTester.populateDatabase(1) ; //musicManagerTester.searchQueryTest() ; //~ musicManagerTester.resolveTest() ; //~ musicManagerTester.allArtistsQueryTest() ; //~ musicManagerTester.tracksQueryTest() ; //~ musicManagerTester.albumsQueryTest() ; //musicManagerTester.searchQueryTest() ; - musicManagerTester.showDatabase() ; + musicManagerTester.retrieveRowEmptyGenreTest() ; + //musicManagerTester.showDatabase() ; }, onID3TagCallback: function(tags) @@ -465,7 +466,6 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { queryFailure: function(data) { Tomahawk.log("Request Failed : " + data.text); } - } }); diff --git a/googledrive/musicManager.js b/googledrive/musicManager.js index 06acf80a9..75ea3e7f1 100644 --- a/googledrive/musicManager.js +++ b/googledrive/musicManager.js @@ -33,19 +33,23 @@ var musicManager = { Tomahawk.log("Init webSQL Db : "); if (!this.dbSQL) this.dbSQL = openDatabase(this.dbName, '1.0', 'Muic Database', 2 * 1024 * 1024) ; this.dbSQL.transaction(function (tx) { - tx.executeSql('CREATE TABLE IF NOT EXISTS track (id primary key, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url)'); - }); + tx.executeSql('CREATE TABLE IF NOT EXISTS track (id primary key, track, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url)'); + }); }, showDatabase: function() { - Tomahawk.log("Displaying Content of Database"); + Tomahawk.log("Displaying Content of Database"); var log = "" ; this.dbSQL.transaction(function (tx) { tx.executeSql('SELECT * FROM track', [], function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; + // Parsing to display information on each music var len = results.length ; var i = 0 ; for (i ; i < len ; i ++) { - Tomahawk.log("id:"+results[i].id+", title:"+results[i].title+", artist:"+results[i].artist+", album:"+results[i].album+", url:"+results[i].url+""); + for (row in results[i]) { + log += ""+row+": "+ results[i][row] +"," ; + } + Tomahawk.log (log) ; } }); }); @@ -64,7 +68,7 @@ var musicManager = { addTrack : function(tabTrackDetails) { var id = tabTrackDetails["id"] || ''; - var title = tabTrackDetails["title"] || ''; + var track = tabTrackDetails["track"] || ''; var artist = tabTrackDetails["artist"] || ''; var album = tabTrackDetails["album"] || ''; var albumpos = tabTrackDetails["albumpos"] || ''; @@ -76,20 +80,28 @@ var musicManager = { var bitrate = tabTrackDetails["bitrate"] || '' ; var url = tabTrackDetails["url"] || '' ; - // Check presence in the database before adding - if (id == "" || !id) { Tomahawk.log("Insertion intented without an id key"); return ; } - this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT id FROM track where id=?', [id], function (tx, resultsQuery ) { - if (resultsQuery.rows.length > 0) { - Tomahawk.log("Insertion abort : data already inside the "+this.dbName+""); - return ; - } - }); - }); + + // check core information provided + if (id == "" || track == "" || album=="" || artist =="" || url=="") { + Tomahawk.log("Insertion Failed : core information track isn't provided to "+this.dbName); + return ; + } + else + { + // Check presence in the database before adding + this.dbSQL.transaction(function (tx) { + tx.executeSql('SELECT id FROM track where id=?', [id], function (tx, resultsQuery ) { + if (resultsQuery.rows.length > 0) { + Tomahawk.log("Insertion abort : data already inside the "+this.dbName+""); + return ; + } + }); + }); + } // Track Insertion this.dbSQL.transaction(function (tx) { - tx.executeSql('INSERT INTO track (id, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', - [id, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url]); + tx.executeSql('INSERT INTO track (id, track, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + [id, track, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url]); }); Tomahawk.log("Insertion inside "+this.dbName+""); }, @@ -98,7 +110,6 @@ var musicManager = { { if (id == "" || !id) { Tomahawk.log("Deletion intented without an id key"); return ; } this.dbSQL.transaction(function (tx) { - //tx.executeSql('DELETE FROM track (title, artist, album, url) VALUES (?, ?, ?, ?)', [tabTrackDetails["title"], tabTrackDetails["artist"], tabTrackDetails["album"] , tabTrackDetails["url"]]); tx.executeSql('DELETE FROM track WHERE id = ?', [tabTrackDetails["id"]], function (tx,resultsQuery){}); }); Tomahawk.log("Deletion inside "+this.dbName+""); @@ -113,7 +124,7 @@ var musicManager = { for (i = 0; i < len; i++) { song = { id: resultsQuery.rows.item(i).id , - track: resultsQuery.rows.item(i).title , + track: resultsQuery.rows.item(i).track , artist: resultsQuery.rows.item(i).artist , album: resultsQuery.rows.item(i).album , albumpos: resultsQuery.rows.item(i).albumpos , @@ -175,12 +186,12 @@ var musicManager = { }); }, - // Parse Title, Album , Artist + // Parse track, Album , Artist searchQuery: function (searchString,callBack) { this.dbSQL.transaction(function (tx) { // Select first or limit mechanisim ? - tx.executeSql("SELECT * FROM track WHERE (album LIKE ?) or (artist LIKE ?) or (title LIKE ?)", ["%"+searchString+"%","%"+searchString+"%","%"+searchString+"%"], + tx.executeSql("SELECT * FROM track WHERE (album LIKE ?) or (artist LIKE ?) or (track LIKE ?)", ["%"+searchString+"%","%"+searchString+"%","%"+searchString+"%"], function (tx, resultsQuery ) { var len = resultsQuery.rows.length, i; var results = musicManager.parseSongAttriutes(resultsQuery) ; @@ -191,11 +202,11 @@ var musicManager = { }, // Only one Track matching - resolve: function(artist, album, title, callBack) + resolve: function(artist, album, track, callBack) { var results = [] ; this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT * FROM track WHERE album=? and artist=? and title=? ', [album,artist,title], // Select first or limit mechanisim ? + tx.executeSql('SELECT * FROM track WHERE album=? and artist=? and track=? ', [album,artist,track], // Select first or limit mechanisim ? function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; //Tomahawk.log("Number of track results for resolve : "+results.length); @@ -211,7 +222,8 @@ var musicManager = { tabTrackDetails: [] , init: function() { - this.tabTrackDetails = {"id":"22" , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + this.tabTrackDetails = {"id":"22" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + //musicManager.addTrack(this.tabTrackDetails) ; }, populateDatabase: function (rows){ @@ -244,9 +256,9 @@ var musicManager = { resolveTest: function() { var artist = this.tabTrackDetails["artist"]; var album = this.tabTrackDetails["album"]; - var title = this.tabTrackDetails["title"]; - musicManager.resolve(artist,album,title, function(results){ - Tomahawk.log("Return songs title "+results.title); + var track = this.tabTrackDetails["track"]; + musicManager.resolve(artist,album,track, function(results){ + Tomahawk.log("Return songs track "+results.track); }); }, @@ -266,7 +278,7 @@ var musicManager = { musicManager.tracksQuery(artist, album , function(results){ var len = results.length ; var i = 0; for (i ; i < len ; i++) { - Tomahawk.log("Return track title name num "+i+" : "+results[i].title); + Tomahawk.log("Return track track name num "+i+" : "+results[i].track); } }); }, @@ -276,7 +288,7 @@ var musicManager = { musicManager.albumsQuery(artist, function(results){ var len = results.length ; var i = 0; for (i ; i < len ; i++) { - Tomahawk.log("Return album title name num "+i+" : "+results[i]); + Tomahawk.log("Return album track name num "+i+" : "+results[i]); } }); }, @@ -294,25 +306,45 @@ var musicManager = { /* // Test Scenario insertionDuplicateTest() { - this.tabTrackDetails = {"id":"22" , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + this.tabTrackDetails = {"id":"22" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; var test = this.tabTrackDetails ; musicManager.addTrack(test) ; //musicManager.addTrack(this.tabTrackDetails) ; }, - insertionWithoutKeyTest() { - this.tabTrackDetails = {"id":"" , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + insertionWithoutCoreTest() { + this.tabTrackDetails = {"id":"" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; musicManager.addTrack(this.tabTrackDetails) ; - this.tabTrackDetails = {"id":null , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + this.tabTrackDetails = {"id":null , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; musicManager.addTrack(this.tabTrackDetails) ; }, deletionWithoutKeyTest() { - this.tabTrackDetails = {"id":"" , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + this.tabTrackDetails = {"id":"" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; musicManager.deleteTrack(this.tabTrackDetails) ; - this.tabTrackDetails = {"id":null , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + this.tabTrackDetails = {"track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; musicManager.deleteTrack(this.tabTrackDetails) ; }, -* */ + */ + + retrieveRowEmptyGenreTest:function() { + + this.tabTrackDetails = {"id":"23" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + musicManager.addTrack(this.tabTrackDetails) ; + + this.tabTrackDetails = {"id":"24" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + musicManager.addTrack(this.tabTrackDetails) ; + + var qString = "Division" ; var log ; + musicManager.searchQuery(qString, function(results){ + var len = results.length ; var i = 0; + for (i ; i < len ; i++) { + for (row in results[i]){ + log += ""+row+": "+ results[i][row] +"," ; + } + } + Tomahawk.log(log); + }); + }, }; From 0466358c2b079a00775da9a1c0166edb7916f3f0 Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Wed, 6 Mar 2013 16:55:43 +0100 Subject: [PATCH 051/118] Test scenario DuplicateInsertion add --- googledrive/googledrive.js | 16 +++++++++------- googledrive/musicManager.js | 18 ++++++++++-------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 910a098d8..88feb4557 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -187,8 +187,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { qid: qid, artists: results }; - //Tomahawk.log("google drive artists returned: "); - //Tomahawk.addArtistResults(return_artists); + Tomahawk.log("google drive artists returned: "); + Tomahawk.addArtistResults(return_artists); }); }, @@ -201,8 +201,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { artist: artist, albums: results }; - //Tomahawk.log("google drive albums returned: "); - //Tomahawk.addAlbumResults(return_albums); + Tomahawk.log("google drive albums returned: "); + Tomahawk.addAlbumResults(return_albums); }); }, @@ -216,8 +216,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { album: album, results: results }; - //Tomahawk.log("Google Drive tracks returned:"); - //Tomahawk.addAlbumTrackResults(return_tracks); + Tomahawk.log("Google Drive tracks returned:"); + Tomahawk.addAlbumTrackResults(return_tracks); }); }, @@ -240,7 +240,9 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //~ musicManagerTester.tracksQueryTest() ; //~ musicManagerTester.albumsQueryTest() ; //musicManagerTester.searchQueryTest() ; - musicManagerTester.retrieveRowEmptyGenreTest() ; + //musicManagerTester.retrieveRowEmptyGenreTest() ; + //musicManagerTester.insertionDuplicateTest() ; + //musicManagerTester.retrieveRowEmptyGenreTest() ; //musicManagerTester.showDatabase() ; }, diff --git a/googledrive/musicManager.js b/googledrive/musicManager.js index 75ea3e7f1..cef1ad91f 100644 --- a/googledrive/musicManager.js +++ b/googledrive/musicManager.js @@ -89,10 +89,11 @@ var musicManager = { else { // Check presence in the database before adding + var db = this.dbName ; this.dbSQL.transaction(function (tx) { tx.executeSql('SELECT id FROM track where id=?', [id], function (tx, resultsQuery ) { if (resultsQuery.rows.length > 0) { - Tomahawk.log("Insertion abort : data already inside the "+this.dbName+""); + Tomahawk.log("Insertion abort : data already inside the "+db+""); return ; } }); @@ -303,23 +304,24 @@ var musicManager = { }); }, -/* + // Test Scenario - insertionDuplicateTest() { + insertionDuplicateTest:function() { + Tomahawk.log("Test Scenario : duplicate insertion"); this.tabTrackDetails = {"id":"22" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; - var test = this.tabTrackDetails ; - musicManager.addTrack(test) ; - //musicManager.addTrack(this.tabTrackDetails) ; + musicManager.addTrack(this.tabTrackDetails) ; // should log a duplicate error + musicManager.addTrack(this.tabTrackDetails) ; }, - insertionWithoutCoreTest() { +/* + insertionWithoutCoreTest:function() { this.tabTrackDetails = {"id":"" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; musicManager.addTrack(this.tabTrackDetails) ; this.tabTrackDetails = {"id":null , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; musicManager.addTrack(this.tabTrackDetails) ; }, - deletionWithoutKeyTest() { + deletionWithoutKeyTest:function() { this.tabTrackDetails = {"id":"" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; musicManager.deleteTrack(this.tabTrackDetails) ; this.tabTrackDetails = {"track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; From 9c0a318605caf3218441eb976ce2e5d2cd6cb632 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Wed, 6 Mar 2013 16:55:45 +0100 Subject: [PATCH 052/118] Enable add results in GD --- googledrive/googledrive.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 6c10b6ab0..be136ce13 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -189,7 +189,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { artists: results }; //Tomahawk.log("google drive artists returned: "); - //Tomahawk.addArtistResults(return_artists); + Tomahawk.addArtistResults(return_artists); }); }, @@ -203,7 +203,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { albums: results }; //Tomahawk.log("google drive albums returned: "); - //Tomahawk.addAlbumResults(return_albums); + Tomahawk.addAlbumResults(return_albums); }); }, @@ -218,7 +218,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { results: results }; //Tomahawk.log("Google Drive tracks returned:"); - //Tomahawk.addAlbumTrackResults(return_tracks); + Tomahawk.addAlbumTrackResults(return_tracks); }); }, From 8c17523cbba646d1de2ffda829c733778934b1a9 Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Wed, 6 Mar 2013 17:00:31 +0100 Subject: [PATCH 053/118] Test scenario Insertion without the core information track add --- googledrive/googledrive.js | 1 + googledrive/musicManager.js | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 88feb4557..1bf4ccf77 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -243,6 +243,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //musicManagerTester.retrieveRowEmptyGenreTest() ; //musicManagerTester.insertionDuplicateTest() ; //musicManagerTester.retrieveRowEmptyGenreTest() ; + //musicManagerTester.insertionWithoutCoreTest() ; //musicManagerTester.showDatabase() ; }, diff --git a/googledrive/musicManager.js b/googledrive/musicManager.js index cef1ad91f..a1230d41f 100644 --- a/googledrive/musicManager.js +++ b/googledrive/musicManager.js @@ -313,14 +313,14 @@ var musicManager = { musicManager.addTrack(this.tabTrackDetails) ; }, -/* + insertionWithoutCoreTest:function() { this.tabTrackDetails = {"id":"" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; - musicManager.addTrack(this.tabTrackDetails) ; + musicManager.addTrack(this.tabTrackDetails) ; // should log a core unprovided error this.tabTrackDetails = {"id":null , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; - musicManager.addTrack(this.tabTrackDetails) ; + musicManager.addTrack(this.tabTrackDetails) ; // should log a core unprovided error }, - + /* deletionWithoutKeyTest:function() { this.tabTrackDetails = {"id":"" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; musicManager.deleteTrack(this.tabTrackDetails) ; From 4867a373a5fcc36cc42ff10660dfc40d97c3685e Mon Sep 17 00:00:00 2001 From: GuillaumeJ Date: Wed, 6 Mar 2013 17:04:57 +0100 Subject: [PATCH 054/118] ajout fonction collection dans gd.js --- googledrive/googledrive.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 6c10b6ab0..26842278f 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -222,6 +222,28 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }); }, + collection: function() + { + //strip http:// and trailing slash + var desc = "cloud de google drive"; + + var return_object = { + prettyname: "Google Drive", + description: desc, + iconfile: "googledrive.png" + }; + + //Icon and text specific for Runners-ID + if (desc.indexOf("runners-id.com") !== -1 || + desc.indexOf("runners-id.org") !== -1 ) + { + return_object["prettyname"] = "Runners-ID"; + return_object["iconfile"] = "runnersid-icon.png"; + } + + return return_object; + }, + getStreamUrl: function (ourUrl) { var songId = ourUrl.replace("googledrive://id/", ""); var meta = JSON.parse(this.oauth.ogetSyncJSON('https://www.googleapis.com/drive/v2/files/' + songId)); From 4b802858c01958203dbc50af07f99bffba135f8e Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Wed, 6 Mar 2013 17:12:08 +0100 Subject: [PATCH 055/118] Test scenario : delition without key add and some corrections --- googledrive/googledrive.js | 4 +++- googledrive/musicManager.js | 9 ++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 1bf4ccf77..bf7fcc8b5 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -230,7 +230,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { googleDriveMusicManagerTests: function() { //musicManagerTester.flushDatabaseTest() ; - musicManagerTester.init() ; + //musicManagerTester.init() ; //musicManagerTester.addTrackTest() ; //musicManager.deletionWithoutKeyTest(); //musicManagerTester.populateDatabase(1) ; @@ -244,6 +244,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //musicManagerTester.insertionDuplicateTest() ; //musicManagerTester.retrieveRowEmptyGenreTest() ; //musicManagerTester.insertionWithoutCoreTest() ; + //musicManagerTester.insertionWithoutCoreTest() ; + //musicManagerTester.deletionWithoutKeyTest() ; //musicManagerTester.showDatabase() ; }, diff --git a/googledrive/musicManager.js b/googledrive/musicManager.js index a1230d41f..dd6eceb44 100644 --- a/googledrive/musicManager.js +++ b/googledrive/musicManager.js @@ -79,8 +79,7 @@ var musicManager = { var mimetype = tabTrackDetails["mimetype"] || '' ; var bitrate = tabTrackDetails["bitrate"] || '' ; var url = tabTrackDetails["url"] || '' ; - - + // check core information provided if (id == "" || track == "" || album=="" || artist =="" || url=="") { Tomahawk.log("Insertion Failed : core information track isn't provided to "+this.dbName); @@ -109,9 +108,10 @@ var musicManager = { deleteTrack: function (tabTrackDetails) { + var id = tabTrackDetails["id"] || ''; if (id == "" || !id) { Tomahawk.log("Deletion intented without an id key"); return ; } this.dbSQL.transaction(function (tx) { - tx.executeSql('DELETE FROM track WHERE id = ?', [tabTrackDetails["id"]], function (tx,resultsQuery){}); + tx.executeSql('DELETE FROM track WHERE id = ?', [id], function (tx,resultsQuery){}); }); Tomahawk.log("Deletion inside "+this.dbName+""); }, @@ -320,14 +320,13 @@ var musicManager = { this.tabTrackDetails = {"id":null , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; musicManager.addTrack(this.tabTrackDetails) ; // should log a core unprovided error }, - /* + deletionWithoutKeyTest:function() { this.tabTrackDetails = {"id":"" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; musicManager.deleteTrack(this.tabTrackDetails) ; this.tabTrackDetails = {"track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; musicManager.deleteTrack(this.tabTrackDetails) ; }, - */ retrieveRowEmptyGenreTest:function() { From 87dc69486c758abc6e8d2f07b60c509d1014e472 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Wed, 6 Mar 2013 17:13:22 +0100 Subject: [PATCH 056/118] Complete ID3Tag callback in Dropbox. --- dropbox/dropbox.js | 88 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 69 insertions(+), 19 deletions(-) diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index 9979eacba..e2fc2095e 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -143,43 +143,93 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { this.updateDatabase(); } }, - + onID3TagCallback: function(tags) - { - //Add track to database - //var url = 'googledrive://' + fileId; - //dbSql.addTrack - Tomahawk.log("Tags : "); - Tomahawk.log(DumpObjectIndented(tags)); + { + var trackInfo = { + 'id' : tags['fileId'], + 'url' : 'dropbox://path/' + tags['fileId'], + 'title' : tags['track'], + 'artist' : tags['artist'], + 'album' : tags['album'], + 'albumpos' : tags['albumpos'], + 'year' : tags['year'], + 'bitrate' : tags['bitrate'], + 'mimetype' : tags['mimetype'], + 'size' : tags['size'], + 'duration' : tags['duration'], + }; + + Tomahawk.log("Adding : " + DumpObjectIndented(trackInfo)); + musicManager.addTrack(trackInfo); }, resolve: function (qid, artist, album, title) { - //this.doSearchOrResolve(qid, title, 1); + musicManager.resolve(artist, album, title, function(results) { + var return_songs = { + qid: qid, + results: results + }; + Tomahawk.log("Resolved query : " + artist + ", "+ album+ ", "+ title+" returned: " + DumpObjectIndented(return_songs.results)); + Tomahawk.addTrackResults(return_songs); + }); + }, search: function (qid, searchString) { - //this.doSearchOrResolve(qid, searchString, 15); + // set up a limit for the musicManager search Query + Tomahawk.log("search query"); + musicManager.searchQuery(searchString,function(results){ + var return_songs = { + qid: qid, + results: results + }; + + Tomahawk.log("Search query : " + searchString +" , result: " + DumpObjectIndented(return_songs.results)); + Tomahawk.addTrackResults(return_songs); + }); }, artists: function( qid ) { - musicManager.initDatabase() ; - var results = this.musicManager.allArtistsQuery() ; - var return_artists = { - qid: qid, - artists: results - }; - + Tomahawk.log("artists query"); + musicManager.allArtistsQuery(function(results){ + var return_artists = { + qid: qid, + artists: results + }; + Tomahawk.log("google drive artists returned: "); + Tomahawk.addArtistResults(return_artists); + }); }, albums: function( qid, artist ) { - + Tomahawk.log("albums query"); + musicManager.albumsQuery(artist, function(results){ + var return_albums = { + qid: qid, + artist: artist, + albums: results + }; + Tomahawk.log("google drive albums returned: "); + Tomahawk.addAlbumResults(return_albums); + }); }, tracks: function( qid, artist, album ) { - + Tomahawk.log("tracks query"); + musicManager.tracksQuery(artist, album, function(results){ + var return_tracks = { + qid: qid, + artist: artist, + album: album, + results: results + }; + Tomahawk.log("Google Drive tracks returned:"); + Tomahawk.addAlbumTrackResults(return_tracks); + }); }, isMimeTypeSupported: function(mimeType) @@ -190,7 +240,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { }, getStreamUrl: function (ourUrl) { - var path = ourUrl.replace("dropbox://", ""); + var path = ourUrl.replace("dropbox://path/", ""); return this.oauth.oAuthGetUrl(this.getFileUrl + path); }, From f6c14903c065cb207001f5cdb0f516c91e2c82cd Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Wed, 6 Mar 2013 21:01:12 +0100 Subject: [PATCH 057/118] Unsloppify string in Ampache config ui. --- ampache/config.ui | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ampache/config.ui b/ampache/config.ui index aed9f47be..b79dec8ca 100644 --- a/ampache/config.ui +++ b/ampache/config.ui @@ -7,7 +7,7 @@ 0 0 447 - 300 + 318 @@ -41,13 +41,11 @@ - 12 - true + false - For owncloud installs, server url is -http://[owncloud url]/remote.php/ampache + <html><head/><body><p>For ownCloud instances, the Server URL is<br/>http://<span style=" color:#585858;">ownCloud base url</span>/remote.php/ampache</p></body></html> Qt::AlignCenter From dc5ef928d2116c71f4fa4650c47dfeb4f7f3785b Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Wed, 6 Mar 2013 22:17:55 +0100 Subject: [PATCH 058/118] Consistency++ --- ampache/config.ui | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ampache/config.ui b/ampache/config.ui index b79dec8ca..c9efa9597 100644 --- a/ampache/config.ui +++ b/ampache/config.ui @@ -57,7 +57,7 @@ - Username + Username: @@ -67,7 +67,7 @@ - Password + Password: @@ -81,7 +81,7 @@ - Server URL + Server URL: From e18d935b2e9c554972d7ce1f9b9e94f4c9d0975f Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Thu, 7 Mar 2013 11:38:14 +0100 Subject: [PATCH 059/118] Add log message in track function --- googledrive/googledrive.js | 2 +- googledrive/musicManager.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 4db64ccf3..569589d66 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -218,7 +218,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { album: album, results: results }; - Tomahawk.log("Google Drive tracks returned:"); + Tomahawk.log("Google Drive tracks for ("+artist + " , "+ album +") returned:" + + DumpObjectIndented(return_tracks.results)); Tomahawk.addAlbumTrackResults(return_tracks); }); }, diff --git a/googledrive/musicManager.js b/googledrive/musicManager.js index dd6eceb44..6928fb648 100644 --- a/googledrive/musicManager.js +++ b/googledrive/musicManager.js @@ -181,7 +181,8 @@ var musicManager = { tx.executeSql('SELECT * FROM track WHERE artist=? and album=?', [artist,album], function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; - //Tomahawk.log("Number of results : "+results.length); + Tomahawk.log("Number of results : "+results.length+ " "+ DumpObjectIndented(results)); + Tomahawk.log("Number of resultsQuery : "+resultsQuery.length+ " "+ DumpObjectIndented(resultsQuery)); callBack(results) ; }); }); From d985a710cdf79200113db73898b181ea9b8300f0 Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Thu, 7 Mar 2013 11:51:24 +0100 Subject: [PATCH 060/118] adding fixed : wrong row title instead of track --- googledrive/googledrive.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 4db64ccf3..c5c3c3e03 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -94,9 +94,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { this.oauth.init(); musicManager.initDatabase() ; - //musicManager.showDatabase(); - - //this.googleDriveMusicManagerTests() ; + //musicManager.showDatabase(); + this.googleDriveMusicManagerTests() ; Tomahawk.addCustomUrlHandler( "googledrive", "getStreamUrl" ); Tomahawk.reportCapabilities( TomahawkResolverCapability.Browsable | TomahawkResolverCapability.AccountFactory ); @@ -271,7 +270,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //musicManagerTester.insertionWithoutCoreTest() ; //musicManagerTester.insertionWithoutCoreTest() ; //musicManagerTester.deletionWithoutKeyTest() ; - //musicManagerTester.showDatabase() ; + musicManagerTester.showDatabase() ; }, onID3TagCallback: function(tags) @@ -279,7 +278,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { var trackInfo = { 'id' : tags['fileId'], 'url' : 'googledrive://id/' + tags['fileId'], - 'title' : tags['track'], + 'track' : tags['track'], 'artist' : tags['artist'], 'album' : tags['album'], 'albumpos' : tags['albumpos'], From be2d49198e9d16a073f36ff7c10e39cc667e86c1 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Thu, 7 Mar 2013 11:52:49 +0100 Subject: [PATCH 061/118] Removing buggy log --- googledrive/musicManager.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/googledrive/musicManager.js b/googledrive/musicManager.js index 6928fb648..d2182f8ae 100644 --- a/googledrive/musicManager.js +++ b/googledrive/musicManager.js @@ -181,8 +181,7 @@ var musicManager = { tx.executeSql('SELECT * FROM track WHERE artist=? and album=?', [artist,album], function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; - Tomahawk.log("Number of results : "+results.length+ " "+ DumpObjectIndented(results)); - Tomahawk.log("Number of resultsQuery : "+resultsQuery.length+ " "+ DumpObjectIndented(resultsQuery)); + //Tomahawk.log("Number of results : "+results.length+ " "+ DumpObjectIndented(results)); callBack(results) ; }); }); From 0d39d083233a118ffd496891f9c157841a54d222 Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Thu, 7 Mar 2013 14:12:10 +0100 Subject: [PATCH 062/118] Changed Title to Track to add into database --- dropbox/dropbox.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index e2fc2095e..1571e3fd1 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -149,7 +149,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { var trackInfo = { 'id' : tags['fileId'], 'url' : 'dropbox://path/' + tags['fileId'], - 'title' : tags['track'], + 'track' : tags['track'], 'artist' : tags['artist'], 'album' : tags['album'], 'albumpos' : tags['albumpos'], From 2f7ebcc8b1c1d67e3035d1764fe47b61b88650f7 Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Thu, 7 Mar 2013 14:14:51 +0100 Subject: [PATCH 063/118] Dropbox music manager adapted from the newest version of GD music manager --- dropbox/musicManager.js | 159 ++++++++++++++++++++++++++++------------ 1 file changed, 112 insertions(+), 47 deletions(-) diff --git a/dropbox/musicManager.js b/dropbox/musicManager.js index 669b53d15..6ef9b77de 100644 --- a/dropbox/musicManager.js +++ b/dropbox/musicManager.js @@ -28,23 +28,26 @@ var musicManager = { initDatabase : function() { - // TODO : choose the id : url / device ID / combo of columns ? Tomahawk.log("Init webSQL Db : "); if (!this.dbSQL) this.dbSQL = openDatabase(this.dbName, '1.0', 'Muic Database', 2 * 1024 * 1024) ; this.dbSQL.transaction(function (tx) { - tx.executeSql('CREATE TABLE IF NOT EXISTS track (id primary key, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url)'); - }); + tx.executeSql('CREATE TABLE IF NOT EXISTS track (id primary key, track, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url)'); + }); }, showDatabase: function() { - Tomahawk.log("Displaying Content of Database"); + Tomahawk.log("Displaying Content of Database"); var log = "" ; this.dbSQL.transaction(function (tx) { tx.executeSql('SELECT * FROM track', [], function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; + // Parsing to display information on each music var len = results.length ; var i = 0 ; - for (i ; i < len ; i ++) { - Tomahawk.log("id:"+results[i].id+", title:"+results[i].title+", artist:"+results[i].artist+", album:"+results[i].album+", url:"+results[i].url+""); + for (i ; i < len ; i ++) { + for (row in results[i]) { + log += ""+row+": "+ results[i][row] +"," ; + } + Tomahawk.log (log) ; } }); }); @@ -62,41 +65,51 @@ var musicManager = { addTrack : function(tabTrackDetails) { - var id = tabTrackDetails["id"]; - var title = tabTrackDetails["title"]; - var artist = tabTrackDetails["artist"]; - var album = tabTrackDetails["album"] ; - var albumpos = tabTrackDetails["albumpos"]; - var year = tabTrackDetails["year"] ; - var genre = tabTrackDetails["genre"] ; - var size = tabTrackDetails["size"] ; - var duration = tabTrackDetails["duration"] ; - var mimetype = tabTrackDetails["mimetype"] ; - var bitrate = tabTrackDetails["bitrate"] ; - var url = tabTrackDetails["url"] ; - - // Check presence in the database before adding - this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT id FROM track where id=?', [id], function (tx, resultsQuery ) { - if (resultsQuery.rows.length > 0) { - Tomahawk.log("Insertion abort : data already inside the "+this.dbName+""); - return ; - } - }); - }); + var id = tabTrackDetails["id"] || ''; + var track = tabTrackDetails["track"] || ''; + var artist = tabTrackDetails["artist"] || ''; + var album = tabTrackDetails["album"] || ''; + var albumpos = tabTrackDetails["albumpos"] || ''; + var year = tabTrackDetails["year"] || ''; + var genre = tabTrackDetails["genre"] || '' ; + var size = tabTrackDetails["size"] || '' ; + var duration = tabTrackDetails["duration"] || '' ; + var mimetype = tabTrackDetails["mimetype"] || '' ; + var bitrate = tabTrackDetails["bitrate"] || '' ; + var url = tabTrackDetails["url"] || '' ; + + // check core information provided + if (id == "" || track == "" || album=="" || artist =="" || url=="") { + Tomahawk.log("Insertion Failed : core information track isn't provided to "+this.dbName); + return ; + } + else + { + // Check presence in the database before adding + var db = this.dbName ; + this.dbSQL.transaction(function (tx) { + tx.executeSql('SELECT id FROM track where id=?', [id], function (tx, resultsQuery ) { + if (resultsQuery.rows.length > 0) { + Tomahawk.log("Insertion abort : data already inside the "+db+""); + return ; + } + }); + }); + } // Track Insertion this.dbSQL.transaction(function (tx) { - tx.executeSql('INSERT INTO track (id, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', - [id, title, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url]); + tx.executeSql('INSERT INTO track (id, track, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', + [id, track, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url]); }); Tomahawk.log("Insertion inside "+this.dbName+""); }, deleteTrack: function (tabTrackDetails) { + var id = tabTrackDetails["id"] || ''; + if (id == "" || !id) { Tomahawk.log("Deletion intented without an id key"); return ; } this.dbSQL.transaction(function (tx) { - //tx.executeSql('DELETE FROM track (title, artist, album, url) VALUES (?, ?, ?, ?)', [tabTrackDetails["title"], tabTrackDetails["artist"], tabTrackDetails["album"] , tabTrackDetails["url"]]); - tx.executeSql('DELETE FROM track WHERE id = ?', [tabTrackDetails["id"]], function (tx,resultsQuery){}); + tx.executeSql('DELETE FROM track WHERE id = ?', [id], function (tx,resultsQuery){}); }); Tomahawk.log("Deletion inside "+this.dbName+""); }, @@ -110,7 +123,7 @@ var musicManager = { for (i = 0; i < len; i++) { song = { id: resultsQuery.rows.item(i).id , - title: resultsQuery.rows.item(i).title , + track: resultsQuery.rows.item(i).track , artist: resultsQuery.rows.item(i).artist , album: resultsQuery.rows.item(i).album , albumpos: resultsQuery.rows.item(i).albumpos , @@ -166,18 +179,18 @@ var musicManager = { tx.executeSql('SELECT * FROM track WHERE artist=? and album=?', [artist,album], function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; - //Tomahawk.log("Number of results : "+results.length); + Tomahawk.log("Number of results : "+results.length+ " "+ DumpObjectIndented(results)); callBack(results) ; }); }); }, - // Parse Title, Album , Artist + // Parse track, Album , Artist searchQuery: function (searchString,callBack) { this.dbSQL.transaction(function (tx) { // Select first or limit mechanisim ? - tx.executeSql("SELECT * FROM track WHERE (album LIKE ?) or (artist LIKE ?) or (title LIKE ?)", ["%"+searchString+"%","%"+searchString+"%","%"+searchString+"%"], + tx.executeSql("SELECT * FROM track WHERE (album LIKE ?) or (artist LIKE ?) or (track LIKE ?)", ["%"+searchString+"%","%"+searchString+"%","%"+searchString+"%"], function (tx, resultsQuery ) { var len = resultsQuery.rows.length, i; var results = musicManager.parseSongAttriutes(resultsQuery) ; @@ -188,15 +201,15 @@ var musicManager = { }, // Only one Track matching - resolve: function(artist, album, title, callBack) + resolve: function(artist, album, track, callBack) { var results = [] ; this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT * FROM track WHERE album=? and artist=? and title=? ', [album,artist,title], // Select first or limit mechanisim ? + tx.executeSql('SELECT * FROM track WHERE album=? and artist=? and track=? ', [album,artist,track], // Select first or limit mechanisim ? function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; //Tomahawk.log("Number of track results for resolve : "+results.length); - // Filter to give only ONE row + // Filter to give only ONE row : improvement possible : set up a limit ( even if tomahawk is already doing it ) callBack(results[0]) ; }); }); @@ -208,8 +221,8 @@ var musicManager = { tabTrackDetails: [] , init: function() { - // Example of structure - this.tabTrackDetails = {"id": "22" , "title": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + this.tabTrackDetails = {"id":"22" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + //musicManager.addTrack(this.tabTrackDetails) ; }, populateDatabase: function (rows){ @@ -239,12 +252,21 @@ var musicManager = { musicManager.flushDatabase() ; }, + flushDatabaseAndWaitTest: function() { + musicManager.dbSQL.transaction(function (tx) { + tx.executeSql('DROP TABLE track'); + }); + musicManager.initDatabase() ; + Tomahawk.log("webSQL db cleaned out"); + return true ; + }, + resolveTest: function() { var artist = this.tabTrackDetails["artist"]; var album = this.tabTrackDetails["album"]; - var title = this.tabTrackDetails["title"]; - musicManager.resolve(artist,album,title, function(results){ - Tomahawk.log("Return songs title "+results.title); + var track = this.tabTrackDetails["track"]; + musicManager.resolve(artist,album,track, function(results){ + Tomahawk.log("Return songs track "+results.track); }); }, @@ -264,7 +286,7 @@ var musicManager = { musicManager.tracksQuery(artist, album , function(results){ var len = results.length ; var i = 0; for (i ; i < len ; i++) { - Tomahawk.log("Return track title name num "+i+" : "+results[i].title); + Tomahawk.log("Return track track name num "+i+" : "+results[i].track); } }); }, @@ -274,7 +296,7 @@ var musicManager = { musicManager.albumsQuery(artist, function(results){ var len = results.length ; var i = 0; for (i ; i < len ; i++) { - Tomahawk.log("Return album title name num "+i+" : "+results[i]); + Tomahawk.log("Return album track name num "+i+" : "+results[i]); } }); }, @@ -284,9 +306,52 @@ var musicManager = { musicManager.searchQuery(qString, function(results){ var len = results.length ; var i = 0; for (i ; i < len ; i++) { - //Tomahawk.log("Return of a search query size : "+i+" : "+results[i]); + Tomahawk.log("Return of a search query size : "+i+" : "+results[i]); } }); }, + + // Test Scenario + insertionDuplicateTest:function() { + Tomahawk.log("Test Scenario : duplicate insertion"); + this.tabTrackDetails = {"id":"22" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + musicManager.addTrack(this.tabTrackDetails) ; // should log a duplicate error + musicManager.addTrack(this.tabTrackDetails) ; + }, + + + insertionWithoutCoreTest:function() { + this.tabTrackDetails = {"id":"" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + musicManager.addTrack(this.tabTrackDetails) ; // should log a core unprovided error + this.tabTrackDetails = {"id":null , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + musicManager.addTrack(this.tabTrackDetails) ; // should log a core unprovided error + }, + + deletionWithoutKeyTest:function() { + this.tabTrackDetails = {"id":"" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + musicManager.deleteTrack(this.tabTrackDetails) ; + this.tabTrackDetails = {"track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + musicManager.deleteTrack(this.tabTrackDetails) ; + }, + retrieveRowEmptyGenreTest:function() { + + this.tabTrackDetails = {"id":"23" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + musicManager.addTrack(this.tabTrackDetails) ; + + this.tabTrackDetails = {"id":"24" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + musicManager.addTrack(this.tabTrackDetails) ; + + var qString = "Division" ; var log ; + musicManager.searchQuery(qString, function(results){ + var len = results.length ; var i = 0; + for (i ; i < len ; i++) { + for (row in results[i]){ + log += ""+row+": "+ results[i][row] +"," ; + } + } + Tomahawk.log(log); + }); + }, }; + From 5968b1dc6b9cdfe25777c85ba290cc7846986e93 Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Thu, 7 Mar 2013 14:24:31 +0100 Subject: [PATCH 064/118] Little corrections on music manager et the concat bug of googledrive.js --- googledrive/googledrive.js | 13 ++++++------- googledrive/musicManager.js | 12 ++++-------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index fba80419c..c848bf4a3 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -83,7 +83,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { init: function () { Tomahawk.log("Beginnning INIT of Google Drive resovler"); //dbLocal.setItem("googledrive.expiresOn","1"); - //dbLocal.setItem("googledrive.cursor",""); + //dbLocal.setItem("googledrive.cursor",""); //Tomahawk.showWebInspector(); @@ -95,7 +95,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { musicManager.initDatabase() ; //musicManager.showDatabase(); - this.googleDriveMusicManagerTests() ; + //this.googleDriveMusicManagerTests() ; Tomahawk.addCustomUrlHandler( "googledrive", "getStreamUrl" ); Tomahawk.reportCapabilities( TomahawkResolverCapability.Browsable | TomahawkResolverCapability.AccountFactory ); @@ -173,7 +173,6 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { qid: qid, results: results }; - Tomahawk.log("google drive search query : " + searchString +" , result: " + DumpObjectIndented(return_songs.results)); Tomahawk.addTrackResults(return_songs); }); @@ -201,7 +200,6 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { artist: artist, albums: results }; - Tomahawk.log("google drive albums returned: "); Tomahawk.addAlbumResults(return_albums); }); @@ -217,7 +215,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { album: album, results: results }; - Tomahawk.log("Google Drive tracks for ("+artist + " , "+ album +") returned:" + + DumpObjectIndented(return_tracks.results)); + Tomahawk.log("google drive tracks returned: "); + //Tomahawk.log("Google Drive tracks for ("+artist + " , "+ album +") returned:"+ DumpObjectIndented(return_tracks.results)); Tomahawk.addAlbumTrackResults(return_tracks); }); }, @@ -270,9 +269,9 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //musicManagerTester.insertionWithoutCoreTest() ; //musicManagerTester.insertionWithoutCoreTest() ; //musicManagerTester.deletionWithoutKeyTest() ; - musicManagerTester.showDatabase() ; + //musicManagerTester.showDatabase() ; }, - + onID3TagCallback: function(tags) { var trackInfo = { diff --git a/googledrive/musicManager.js b/googledrive/musicManager.js index d2182f8ae..20955e244 100644 --- a/googledrive/musicManager.js +++ b/googledrive/musicManager.js @@ -29,7 +29,6 @@ var musicManager = { initDatabase : function() { - // TODO : choose the id : url / device ID / combo of columns ? Tomahawk.log("Init webSQL Db : "); if (!this.dbSQL) this.dbSQL = openDatabase(this.dbName, '1.0', 'Muic Database', 2 * 1024 * 1024) ; this.dbSQL.transaction(function (tx) { @@ -181,7 +180,7 @@ var musicManager = { tx.executeSql('SELECT * FROM track WHERE artist=? and album=?', [artist,album], function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; - //Tomahawk.log("Number of results : "+results.length+ " "+ DumpObjectIndented(results)); + Tomahawk.log("Number of results : "+results.length+ " "+ DumpObjectIndented(results)); callBack(results) ; }); }); @@ -211,7 +210,7 @@ var musicManager = { function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; //Tomahawk.log("Number of track results for resolve : "+results.length); - // Filter to give only ONE row + // Filter to give only ONE row : improvement possible : set up a limit ( even if tomahawk is already doing it ) callBack(results[0]) ; }); }); @@ -253,7 +252,7 @@ var musicManager = { flushDatabaseTest: function() { musicManager.flushDatabase() ; }, - + resolveTest: function() { var artist = this.tabTrackDetails["artist"]; var album = this.tabTrackDetails["album"]; @@ -299,12 +298,11 @@ var musicManager = { musicManager.searchQuery(qString, function(results){ var len = results.length ; var i = 0; for (i ; i < len ; i++) { - //Tomahawk.log("Return of a search query size : "+i+" : "+results[i]); + Tomahawk.log("Return of a search query size : "+i+" : "+results[i]); } }); }, - // Test Scenario insertionDuplicateTest:function() { Tomahawk.log("Test Scenario : duplicate insertion"); @@ -313,7 +311,6 @@ var musicManager = { musicManager.addTrack(this.tabTrackDetails) ; }, - insertionWithoutCoreTest:function() { this.tabTrackDetails = {"id":"" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; musicManager.addTrack(this.tabTrackDetails) ; // should log a core unprovided error @@ -347,5 +344,4 @@ var musicManager = { Tomahawk.log(log); }); }, - }; From 8f70b2248419e94928ec8ad9403ef7bfebb20250 Mon Sep 17 00:00:00 2001 From: GuillaumeJ Date: Thu, 7 Mar 2013 21:58:52 +0100 Subject: [PATCH 065/118] add fonction collection to dropbox.js --- dropbox/dropbox.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index 9979eacba..dfea65a83 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -180,6 +180,28 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { tracks: function( qid, artist, album ) { + }, + + collection: function() + { + //strip http:// and trailing slash + var desc = "cloud de dropbox"; + + var return_object = { + prettyname: "Dropbox", + description: desc, + iconfile: "dropbox.png" + }; + + //Icon and text specific for Runners-ID + if (desc.indexOf("runners-id.com") !== -1 || + desc.indexOf("runners-id.org") !== -1 ) + { + return_object["prettyname"] = "Runners-ID"; + return_object["iconfile"] = "runnersid-icon.png"; + } + + return return_object; }, isMimeTypeSupported: function(mimeType) From 81a5330011030bab2e04f73371d56534767543e1 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Sun, 17 Mar 2013 18:19:14 +0100 Subject: [PATCH 066/118] [beets] Bundlify --- beets/content/contents/code/beets-icon.png | Bin 0 -> 10657 bytes .../contents/code/beets-resolver.js} | 1 + beets/{ => content/contents/code}/config.ui | 0 beets/content/metadata.json | 18 ++++++++++++++++++ 4 files changed, 19 insertions(+) create mode 100644 beets/content/contents/code/beets-icon.png rename beets/{beets.js => content/contents/code/beets-resolver.js} (99%) rename beets/{ => content/contents/code}/config.ui (100%) create mode 100644 beets/content/metadata.json diff --git a/beets/content/contents/code/beets-icon.png b/beets/content/contents/code/beets-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3f8f6b286e6e35512ab95d4c03dd20ea4aa2424a GIT binary patch literal 10657 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 Date: Sun, 17 Mar 2013 18:51:29 +0100 Subject: [PATCH 067/118] [beets] Load config on startup. --- beets/content/contents/code/beets-resolver.js | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/beets/content/contents/code/beets-resolver.js b/beets/content/contents/code/beets-resolver.js index ce1c0ac6a..b4d8880e8 100644 --- a/beets/content/contents/code/beets-resolver.js +++ b/beets/content/contents/code/beets-resolver.js @@ -93,23 +93,16 @@ var BeetsResolver = Tomahawk.extend(TomahawkResolver, }; }, newConfigSaved: function () { + this.init(); + }, + init: function () { var userConfig = this.getUserConfig(); - this.host = userConfig.host || 'localhost'; - - var port = userConfig.port; - port = parseInt(port); - if (isNaN(port) || !port) { - port = 8337; + this.port = parseInt(userConfig.port); + if (isNaN(this.port) || !this.port) { + this.port = 8337; } - userConfig.port = port; - - this.port = port; }, - - // Defaults. - host: 'localhost', - port: 8337 }); Tomahawk.resolver.instance = BeetsResolver; From 051a4fa4351229466d0733f39cc1d112ed151833 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Sun, 17 Mar 2013 19:06:04 +0100 Subject: [PATCH 068/118] [beets] jslint coding style --- beets/content/contents/code/beets-resolver.js | 74 +++++++++---------- 1 file changed, 33 insertions(+), 41 deletions(-) diff --git a/beets/content/contents/code/beets-resolver.js b/beets/content/contents/code/beets-resolver.js index b4d8880e8..8898fb44f 100644 --- a/beets/content/contents/code/beets-resolver.js +++ b/beets/content/contents/code/beets-resolver.js @@ -9,11 +9,8 @@ var AUDIO_TYPES = { 'MusePack': ['mpc', 'audio/x-musepack'] }; -var BeetsResolver = Tomahawk.extend(TomahawkResolver, -{ - // Basic setup. - settings: - { +var BeetsResolver = Tomahawk.extend(TomahawkResolver, { + settings: { name: 'beets', icon: 'beets-icon.png', weight: 95, @@ -21,58 +18,53 @@ var BeetsResolver = Tomahawk.extend(TomahawkResolver, }, // Resolution. - resolve: function( qid, artist, album, title ) - { - this.beetsQuery(qid, - ['artist:' + artist, 'album:' + album, 'title:' + title] - ); + resolve: function (qid, artist, album, title) { + this.beetsQuery(qid, ['artist:' + artist, 'album:' + album, 'title:' + title]); }, - search: function( qid, searchString ) - { + + search: function (qid, searchString) { this.beetsQuery(qid, searchString.split(' ')); }, - baseUrl: function() { + + baseUrl: function () { return 'http://' + this.host + ':' + this.port; }, - beetsQuery: function( qid, queryParts ) - { - var baseUrl = this.baseUrl(); - var url = baseUrl + '/item/query/'; - for (var i = 0; i < queryParts.length; ++i) { - url += encodeURIComponent(queryParts[i]); + + beetsQuery: function (qid, queryParts) { + var baseUrl = this.baseUrl(), + url = this.baseUrl() + '/item/query/'; + queryParts.forEach(function (item) { + url += encodeURIComponent(item); url += '/'; - } + }); url = url.substring(0, url.length - 1); // Remove last /. - Tomahawk.asyncRequest(url, function(xhr) { - var resp = JSON.parse(xhr.responseText); - var items = resp['results']; - - var searchResults = []; - for (var i = 0; i < items.length; ++i) { - item = items[i]; - var type_info = AUDIO_TYPES[item['format']]; + Tomahawk.asyncRequest(url, function (xhr) { + var resp = JSON.parse(xhr.responseText), + items = resp.results, + searchResults = []; + items.forEach(function (item) { + var type_info = AUDIO_TYPES[item.format]; searchResults.push({ - artist: item['artist'], - album: item['album'], - track: item['title'], - albumpos: item['track'], + artist: item.artist, + album: item.album, + track: item.title, + albumpos: item.track, source: "beets", - url: baseUrl + '/item/' + item['id'] + '/file', - bitrate: Math.floor(item['bitrate'] / 1024), - duration: Math.floor(item['length']), - size: (item['size'] || 0), + url: baseUrl + '/item/' + item.id + '/file', + bitrate: Math.floor(item.bitrate / 1024), + duration: Math.floor(item.length), + size: (item.size || 0), score: 1.0, extension: type_info[0], mimetype: type_info[1], - year: item['year'] + year: item.year }); - } - + }); Tomahawk.addTrackResults({ qid: qid, results: searchResults - }) + }); }); }, @@ -98,7 +90,7 @@ var BeetsResolver = Tomahawk.extend(TomahawkResolver, init: function () { var userConfig = this.getUserConfig(); this.host = userConfig.host || 'localhost'; - this.port = parseInt(userConfig.port); + this.port = parseInt(userConfig.port, 10); if (isNaN(this.port) || !this.port) { this.port = 8337; } From 088d4cc051a5ad0aae172caa1b76879011b1c720 Mon Sep 17 00:00:00 2001 From: "Uwe L. Korn" Date: Sun, 17 Mar 2013 19:10:01 +0100 Subject: [PATCH 069/118] Add copyright information --- beets/content/contents/code/beets-resolver.js | 19 +++++++++++++++++++ beets/content/metadata.json | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/beets/content/contents/code/beets-resolver.js b/beets/content/contents/code/beets-resolver.js index 8898fb44f..6e0e5d1c9 100644 --- a/beets/content/contents/code/beets-resolver.js +++ b/beets/content/contents/code/beets-resolver.js @@ -1,3 +1,22 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012, Adrian Sampson + * Copyright 2013, Uwe L. Korn + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + // Map all the audio types supported by beets to extensions and MIME types. var AUDIO_TYPES = { 'MP3': ['mp3', 'audio/mpeg'], diff --git a/beets/content/metadata.json b/beets/content/metadata.json index 8e12e7a13..0ddd1ee01 100644 --- a/beets/content/metadata.json +++ b/beets/content/metadata.json @@ -1,7 +1,7 @@ { "name": "Beets", "pluginName": "beets", - "author": "Dominik, Leo and Teo", + "author": "Adrian and Uwe", "email": "uwelk@xhochy.com", "version": "0.3", "website": "http://gettomahawk.com", From 326ae9d189839a8691238c0a0f6b6cfb7f08fd1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20G=C3=B6ckel?= Date: Thu, 21 Mar 2013 17:54:21 +0100 Subject: [PATCH 070/118] Fix YouTube parsing. --- youtube/youtube.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/youtube/youtube.js b/youtube/youtube.js index f2fd5ae9a..a40750c65 100644 --- a/youtube/youtube.js +++ b/youtube/youtube.js @@ -184,7 +184,7 @@ var YoutubeResolver = Tomahawk.extend(TomahawkResolver, { console.log(this.settings.name + msg); } else if (this.debugMode){ - Tomahawk.log(this.settings.name + "Debug: " + msg); + Tomahawk.log(this.settings.name + " debug: " + msg); } }, @@ -271,7 +271,6 @@ var YoutubeResolver = Tomahawk.extend(TomahawkResolver, { // First, lets try and find the stream_map at top of the page // to save some time going to the end and do JSON.parse on the yt.config var streamMatch = html.match(/(url_encoded_fmt_stream_map=)(.*?)(?=(\\u0026amp))/i); - //Tomahawk.log(streamMatch); if (streamMatch && streamMatch[2] !== undefined) { var parsed = this.parseURLS(streamMatch[2]); if (parsed) { @@ -282,8 +281,8 @@ var YoutubeResolver = Tomahawk.extend(TomahawkResolver, { } } - // Now we can go further down, and check the yt.config map - streamMatch = html.match(/(yt\.playerConfig =)([^\r\n]+)/); + // Now we can go further down, and check the ytplayer.config map + streamMatch = html.match(/(ytplayer\.config =)([^\r\n]+);/); if (!streamMatch) { // Todo: Open window for user input? @@ -299,7 +298,7 @@ var YoutubeResolver = Tomahawk.extend(TomahawkResolver, { if (streamMatch && streamMatch[2] !== undefined) { try { - var jsonMap = JSON.parse(streamMatch[2].replace("};", "}")); + var jsonMap = JSON.parse(streamMatch[2]); if (jsonMap.args.url_encoded_fmt_stream_map !== undefined) { parsed = this.parseURLS(jsonMap.args.url_encoded_fmt_stream_map); if (parsed){ From fcd6f03f229d32008ae818eff81c8c4ca1b3cd97 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Fri, 22 Mar 2013 11:25:01 +0100 Subject: [PATCH 071/118] Change Googledrive incon to SVG. Remove unused description in collection() --- googledrive/googledrive.js | 14 +++----------- googledrive/googledrive.png | Bin 11493 -> 0 bytes googledrive/googledrive.svg | 11 +++++++++++ 3 files changed, 14 insertions(+), 11 deletions(-) delete mode 100755 googledrive/googledrive.png create mode 100644 googledrive/googledrive.svg diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index c848bf4a3..05cad48f4 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -25,7 +25,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { settings: { name: 'Google Drive', weight: 60, - icon : 'googledrive.png', + icon : 'googledrive.svg', timeout: 15 }, @@ -53,7 +53,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }] },], images: [{ - "googledrive.png": Tomahawk.readBase64("googledrive.png") + 'googledrive.svg': Tomahawk.readBase64(this.settings.icon) }, ] }; }, @@ -229,17 +229,9 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { var return_object = { prettyname: "Google Drive", description: desc, - iconfile: "googledrive.png" + iconfile: this.settings.icon }; - //Icon and text specific for Runners-ID - if (desc.indexOf("runners-id.com") !== -1 || - desc.indexOf("runners-id.org") !== -1 ) - { - return_object["prettyname"] = "Runners-ID"; - return_object["iconfile"] = "runnersid-icon.png"; - } - return return_object; }, diff --git a/googledrive/googledrive.png b/googledrive/googledrive.png deleted file mode 100755 index 49c89b660517cf3c145d0126ecf3ff1dc176e541..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11493 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 LNkvXXu0mjf{xs+S diff --git a/googledrive/googledrive.svg b/googledrive/googledrive.svg new file mode 100644 index 000000000..0f6af9439 --- /dev/null +++ b/googledrive/googledrive.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file From 71fb45010572a769faca1831d3f4479791778c1f Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Fri, 22 Mar 2013 11:29:49 +0100 Subject: [PATCH 072/118] Change Dropbox incon to svg. --- dropbox/dropbox.js | 14 +++----------- dropbox/dropbox.png | Bin 12978 -> 0 bytes dropbox/dropbox.svg | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 11 deletions(-) delete mode 100755 dropbox/dropbox.png create mode 100644 dropbox/dropbox.svg diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index 9766fbdb0..1a5cafc7b 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -24,7 +24,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { settings: { name: 'Dropbox', weight: 60, - icon : 'dropbox.png', + icon : 'dropbox.svg', timeout: 15 }, @@ -52,7 +52,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { }] },], images: [{ - "dropbox.png": Tomahawk.readBase64("dropbox.png") + "dropbox.svg": Tomahawk.readBase64(this.settings.icon) }, ] }; }, @@ -240,17 +240,9 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { var return_object = { prettyname: "Dropbox", description: desc, - iconfile: "dropbox.png" + iconfile: this.settings.icon }; - //Icon and text specific for Runners-ID - if (desc.indexOf("runners-id.com") !== -1 || - desc.indexOf("runners-id.org") !== -1 ) - { - return_object["prettyname"] = "Runners-ID"; - return_object["iconfile"] = "runnersid-icon.png"; - } - return return_object; }, diff --git a/dropbox/dropbox.png b/dropbox/dropbox.png deleted file mode 100755 index 98dde27d8694472aafd4427f9581c79d60c8d1ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12978 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 amC9s=2H5yKdH{b31t2G-ELkaT68Jxyx!>~u diff --git a/dropbox/dropbox.svg b/dropbox/dropbox.svg new file mode 100644 index 000000000..6f63627d1 --- /dev/null +++ b/dropbox/dropbox.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 62314472a6c524b0da467e861045bb8cc8ca3427 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Fri, 22 Mar 2013 11:43:20 +0100 Subject: [PATCH 073/118] Change config.ui of dropbox and google drive with SVG icon --- dropbox/config.ui | 18 ++---------------- googledrive/config.ui | 28 ++++++++++------------------ 2 files changed, 12 insertions(+), 34 deletions(-) diff --git a/dropbox/config.ui b/dropbox/config.ui index d40819a8a..65e1693d2 100644 --- a/dropbox/config.ui +++ b/dropbox/config.ui @@ -20,7 +20,7 @@ - dropbox.png + dropbox.svg Qt::AlignCenter @@ -39,27 +39,13 @@ Qt::AlignJustify|Qt::AlignTop - - - Account : - - - - - - - nd - - - - Associate - + true diff --git a/googledrive/config.ui b/googledrive/config.ui index 73c3b4336..f38581678 100755 --- a/googledrive/config.ui +++ b/googledrive/config.ui @@ -6,8 +6,8 @@ 0 0 - 447 - 305 + 322 + 339 @@ -16,11 +16,17 @@ + + + 304 + 260 + + - googledrive.png + googledrive.svg Qt::AlignCenter @@ -39,27 +45,13 @@ Qt::AlignJustify|Qt::AlignTop - - - Account : - - - - - - - nd - - - - Associate - + true From 6749b80ece1d47730f9e8820c14b15e369be426c Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Sat, 9 Mar 2013 12:14:54 +0100 Subject: [PATCH 074/118] Rearrange Subsonic directory structure as a bundle. --- subsonic/{ => content/contents/code}/config.ui | 0 .../contents/code}/runnersid-icon.png | Bin .../contents/code}/subsonic-icon.png | Bin .../{ => content/contents/code}/subsonic.js | 0 .../{ => content/contents/code}/subsonic.png | Bin subsonic/content/contents/images/icon.png | Bin 0 -> 12192 bytes subsonic/content/metadata.desktop | 15 +++++++++++++++ 7 files changed, 15 insertions(+) rename subsonic/{ => content/contents/code}/config.ui (100%) rename subsonic/{ => content/contents/code}/runnersid-icon.png (100%) rename subsonic/{ => content/contents/code}/subsonic-icon.png (100%) rename subsonic/{ => content/contents/code}/subsonic.js (100%) rename subsonic/{ => content/contents/code}/subsonic.png (100%) create mode 100644 subsonic/content/contents/images/icon.png create mode 100644 subsonic/content/metadata.desktop diff --git a/subsonic/config.ui b/subsonic/content/contents/code/config.ui similarity index 100% rename from subsonic/config.ui rename to subsonic/content/contents/code/config.ui diff --git a/subsonic/runnersid-icon.png b/subsonic/content/contents/code/runnersid-icon.png similarity index 100% rename from subsonic/runnersid-icon.png rename to subsonic/content/contents/code/runnersid-icon.png diff --git a/subsonic/subsonic-icon.png b/subsonic/content/contents/code/subsonic-icon.png similarity index 100% rename from subsonic/subsonic-icon.png rename to subsonic/content/contents/code/subsonic-icon.png diff --git a/subsonic/subsonic.js b/subsonic/content/contents/code/subsonic.js similarity index 100% rename from subsonic/subsonic.js rename to subsonic/content/contents/code/subsonic.js diff --git a/subsonic/subsonic.png b/subsonic/content/contents/code/subsonic.png similarity index 100% rename from subsonic/subsonic.png rename to subsonic/content/contents/code/subsonic.png diff --git a/subsonic/content/contents/images/icon.png b/subsonic/content/contents/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f3b6553b002417aa6795270b5807a276483aac52 GIT binary patch literal 12192 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 qchbVK&Y$VR$V~tD=}N8d5x Date: Wed, 13 Mar 2013 22:30:35 +0100 Subject: [PATCH 075/118] Added script to convert JSON resolver config into desktop file format. --- admin/any/json2desktop.rb | 108 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100755 admin/any/json2desktop.rb diff --git a/admin/any/json2desktop.rb b/admin/any/json2desktop.rb new file mode 100755 index 000000000..14e98f09d --- /dev/null +++ b/admin/any/json2desktop.rb @@ -0,0 +1,108 @@ +#!/usr/bin/env ruby +# === This file is part of Tomahawk Player - === +# +# Copyright 2013, Teo Mrnjavac +# +# Tomahawk is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Tomahawk is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Tomahawk. If not, see . + + +# +# This script converts a json metadata/manifest file into a desktop file for Synchrotron. +# + +require 'json' + +if ARGV.length < 1 + puts "This script converts a Tomahawk resolver's metadata/manifest JSON file" + puts "into a desktop file for Synchrotron." + puts "\nMake sure you have the gems json and zipruby." + puts "Usage: ruby json2desktop.rb path_to_metadata_file.json" + exit +end + +inputPath = File.absolute_path( ARGV[0] ) +outputPath = File.join( File.dirname( inputPath ), "metadata.desktop" ) + +if not File.exists?( inputPath ) or not File.readable?( inputPath ) + puts "Cannot read input file." + exit +end + +if File.exists?( outputPath ) and not File.writable?( outputPath ) + puts "Cannot write to output file." + exit +end + +inputFile = File.open( inputPath, 'r' ) +inputString = inputFile.read +input = JSON.parse( inputString ) +inputFile.close unless inputFile == nil + +# check if outputPath exists, maybe save stuff and/or overwrite, yes? +File.open( outputPath, 'w' ) do |f| + f.write "\ +############################################################################ +## Desktop file generated from JSON file '#{File.basename( inputPath )}' +## +## Created: #{Time.now.to_s} +## by: json2desktop.rb, https://github.com/tomahawk-player +## +## #### WARNING! #### +## All changes made to this file will be lost! +############################################################################ + +[Desktop Entry]\n" + + unless input["name"].nil? || input["name"].empty? + f.write "Name=#{input["name"]}\n" + end + + unless input["description"].nil? || input["description"].empty? + f.write "Comment=#{input["description"]}\n" + end + + f.write "\nType=Service\nX-KDE-ServiceTypes=Tomahawk/Resolver\n" + + unless input["manifest"].nil? + unless input["manifest"]["main"].nil? || input["manifest"]["main"].empty? + f.write "X-Synchrotron-MainScript=#{input["manifest"]["main"]}\n" + end + end + + f.write "\n" + + unless input["pluginName"].nil? || input["pluginName"].empty? + f.write "X-KDE-PluginInfo-Name=#{input["pluginName"]}\n" + end + + f.write "X-KDE-PluginInfo-Category=Resolver\n" + + unless input["author"].nil? || input["author"].empty? + f.write "X-KDE-PluginInfo-Author=#{input["author"]}\n" + end + + unless input["email"].nil? || input["email"].empty? + f.write "X-KDE-PluginInfo-Email=#{input["email"]}\n" + end + + unless input["version"].nil? || input["version"].empty? + f.write "X-KDE-PluginInfo-Version=#{input["version"]}\n" + end + + unless input["website"].nil? || input["website"].empty? + f.write "X-KDE-PluginInfo-Website=#{input["website"]}\n" + end + + +end From 63360238a4abb764aecde4fc2a5ace63ace3a786 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Wed, 13 Mar 2013 22:32:23 +0100 Subject: [PATCH 076/118] Replace desktop file with JSON config. --- subsonic/content/metadata.desktop | 15 --------------- subsonic/content/metadata.json | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 15 deletions(-) delete mode 100644 subsonic/content/metadata.desktop create mode 100644 subsonic/content/metadata.json diff --git a/subsonic/content/metadata.desktop b/subsonic/content/metadata.desktop deleted file mode 100644 index e1732ec05..000000000 --- a/subsonic/content/metadata.desktop +++ /dev/null @@ -1,15 +0,0 @@ -[Desktop Entry] -Name=Subsonic -Comment=Searches your Subsonic server for music to play - -Type=Service -X-KDE-ServiceTypes=Tomahawk/Resolver -X-Synchrotron-MainScript=contents/code/subsonic.js -X-Tomahawk-Resolver-MultiAccount=true - -X-KDE-PluginInfo-Name=subsonic -X-KDE-PluginInfo-Category=Resolver -X-KDE-PluginInfo-Author=mack_t and Teo -X-KDE-PluginInfo-Email=teo@kde.org -X-KDE-PluginInfo-Version=0.5 -X-KDE-PluginInfo-Website=http://gettomahawk.com diff --git a/subsonic/content/metadata.json b/subsonic/content/metadata.json new file mode 100644 index 000000000..0644b2ac7 --- /dev/null +++ b/subsonic/content/metadata.json @@ -0,0 +1,21 @@ +{ + "name": "Subsonic", + "pluginName": "subsonic", + "author": "mack_t and Teo", + "email": "teo@kde.org", + "version": "0.5", + "website": "http://gettomahawk.com", + "description": "Searches your Subsonic server for music to play", + "type": "resolver/javascript", + "manifest": { + "main": "contents/code/subsonic.js", + "scripts": [], + "icon": "contents/images/icon.png", + "resources": [ + "contents/code/config.ui", + "contents/code/runnersid-icon.png", + "contents/code/subsonic-icon.png", + "contents/code/subsonic.png" + ] + } +} From 1e17d111909d1d11259afffb9231047d28b95869 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Wed, 13 Mar 2013 23:10:33 +0100 Subject: [PATCH 077/118] Whitespace-- --- admin/any/json2desktop.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/admin/any/json2desktop.rb b/admin/any/json2desktop.rb index 14e98f09d..9bee5aaa6 100755 --- a/admin/any/json2desktop.rb +++ b/admin/any/json2desktop.rb @@ -103,6 +103,4 @@ unless input["website"].nil? || input["website"].empty? f.write "X-KDE-PluginInfo-Website=#{input["website"]}\n" end - - end From 81b983d30a9362f73b98a41717e3569802aa624d Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Thu, 14 Mar 2013 21:16:35 +0100 Subject: [PATCH 078/118] Bundlify Ampache! --- .../contents/code}/ampache-icon.png | Bin .../contents/code}/ampache-resolver.js | 0 .../{ => content/contents/code}/ampache.png | Bin ampache/{ => content/contents/code}/config.ui | 0 .../contents/code}/owncloud-icon.png | Bin .../{ => content/contents/code}/owncloud.png | Bin ampache/content/contents/images/icon.png | Bin 0 -> 12169 bytes ampache/content/metadata.json | 22 ++++++++++++++++++ 8 files changed, 22 insertions(+) rename ampache/{ => content/contents/code}/ampache-icon.png (100%) rename ampache/{ => content/contents/code}/ampache-resolver.js (100%) rename ampache/{ => content/contents/code}/ampache.png (100%) rename ampache/{ => content/contents/code}/config.ui (100%) rename ampache/{ => content/contents/code}/owncloud-icon.png (100%) rename ampache/{ => content/contents/code}/owncloud.png (100%) create mode 100644 ampache/content/contents/images/icon.png create mode 100644 ampache/content/metadata.json diff --git a/ampache/ampache-icon.png b/ampache/content/contents/code/ampache-icon.png similarity index 100% rename from ampache/ampache-icon.png rename to ampache/content/contents/code/ampache-icon.png diff --git a/ampache/ampache-resolver.js b/ampache/content/contents/code/ampache-resolver.js similarity index 100% rename from ampache/ampache-resolver.js rename to ampache/content/contents/code/ampache-resolver.js diff --git a/ampache/ampache.png b/ampache/content/contents/code/ampache.png similarity index 100% rename from ampache/ampache.png rename to ampache/content/contents/code/ampache.png diff --git a/ampache/config.ui b/ampache/content/contents/code/config.ui similarity index 100% rename from ampache/config.ui rename to ampache/content/contents/code/config.ui diff --git a/ampache/owncloud-icon.png b/ampache/content/contents/code/owncloud-icon.png similarity index 100% rename from ampache/owncloud-icon.png rename to ampache/content/contents/code/owncloud-icon.png diff --git a/ampache/owncloud.png b/ampache/content/contents/code/owncloud.png similarity index 100% rename from ampache/owncloud.png rename to ampache/content/contents/code/owncloud.png diff --git a/ampache/content/contents/images/icon.png b/ampache/content/contents/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6c4155f069422cda3d198d550d841dcb501387fb GIT binary patch literal 12169 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 Date: Fri, 15 Mar 2013 07:01:33 +0100 Subject: [PATCH 079/118] Move scripts around a bit. --- admin/{any => }/json2desktop.rb | 0 admin/{ => spotify-synchrotron}/linux/create_synchrotron.rb | 0 admin/{ => spotify-synchrotron}/mac/create_synchrotron.rb | 0 admin/{ => spotify-synchrotron}/win/create_synchrotron.rb | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename admin/{any => }/json2desktop.rb (100%) rename admin/{ => spotify-synchrotron}/linux/create_synchrotron.rb (100%) rename admin/{ => spotify-synchrotron}/mac/create_synchrotron.rb (100%) rename admin/{ => spotify-synchrotron}/win/create_synchrotron.rb (100%) diff --git a/admin/any/json2desktop.rb b/admin/json2desktop.rb similarity index 100% rename from admin/any/json2desktop.rb rename to admin/json2desktop.rb diff --git a/admin/linux/create_synchrotron.rb b/admin/spotify-synchrotron/linux/create_synchrotron.rb similarity index 100% rename from admin/linux/create_synchrotron.rb rename to admin/spotify-synchrotron/linux/create_synchrotron.rb diff --git a/admin/mac/create_synchrotron.rb b/admin/spotify-synchrotron/mac/create_synchrotron.rb similarity index 100% rename from admin/mac/create_synchrotron.rb rename to admin/spotify-synchrotron/mac/create_synchrotron.rb diff --git a/admin/win/create_synchrotron.rb b/admin/spotify-synchrotron/win/create_synchrotron.rb similarity index 100% rename from admin/win/create_synchrotron.rb rename to admin/spotify-synchrotron/win/create_synchrotron.rb From 981e9c8efecfeb299ce838083bb768ee67046a46 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Fri, 15 Mar 2013 07:23:42 +0100 Subject: [PATCH 080/118] We actually don't need any gems for this script. --- admin/json2desktop.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/admin/json2desktop.rb b/admin/json2desktop.rb index 9bee5aaa6..6fe9c88ea 100755 --- a/admin/json2desktop.rb +++ b/admin/json2desktop.rb @@ -26,7 +26,6 @@ if ARGV.length < 1 puts "This script converts a Tomahawk resolver's metadata/manifest JSON file" puts "into a desktop file for Synchrotron." - puts "\nMake sure you have the gems json and zipruby." puts "Usage: ruby json2desktop.rb path_to_metadata_file.json" exit end From 84be58c1cf3729e8411be8c31f28ce8160fe6a29 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Fri, 15 Mar 2013 10:18:07 +0100 Subject: [PATCH 081/118] Use UTC in json2desktop.rb output timestamp. --- admin/json2desktop.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/json2desktop.rb b/admin/json2desktop.rb index 6fe9c88ea..33b9408a9 100755 --- a/admin/json2desktop.rb +++ b/admin/json2desktop.rb @@ -54,7 +54,7 @@ ############################################################################ ## Desktop file generated from JSON file '#{File.basename( inputPath )}' ## -## Created: #{Time.now.to_s} +## Created: #{Time.now.utc.to_s} ## by: json2desktop.rb, https://github.com/tomahawk-player ## ## #### WARNING! #### From 3028ddc23ee770282ab1b88cf2ea6aaffe8931dd Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Fri, 15 Mar 2013 11:12:37 +0100 Subject: [PATCH 082/118] New script to create resolver bundles (axes). --- admin/makeaxe.rb | 163 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100755 admin/makeaxe.rb diff --git a/admin/makeaxe.rb b/admin/makeaxe.rb new file mode 100755 index 000000000..3b35383f0 --- /dev/null +++ b/admin/makeaxe.rb @@ -0,0 +1,163 @@ +#!/usr/bin/env ruby +# === This file is part of Tomahawk Player - === +# +# Copyright 2013, Teo Mrnjavac +# +# Tomahawk is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Tomahawk is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Tomahawk. If not, see . + + +# +# This script reads a json metadata/manifest file and creates a Tomahawk +# resolver bundle (axe). +# The script should be executed with the top-level resolver directory path as +# parameter, and expects the following structure: +# Mandatory: +# content/ +# + metadata.json +# Suggested: +# content/ +# + metadata.json +# + contents/ +# + code/ +# + .js +# + config.ui +# + +# + images/ +# + icon.png +# + +require 'json' +require 'rubygems' +require 'zip/zip' +require 'digest/md5' + +BUNDLEVERSION = 1 #might never be used but best to plan ahead + +if ARGV.length < 1 + puts "This script creates a Tomahawk resolver bundle." + puts "\nMake sure you have the zip gem." + puts "Usage: ruby makeaxe.rb path_to_resolver_directory" + exit +end + +inputPath = File.absolute_path( ARGV[0] ) + +if not Dir.exists?( inputPath ) + puts "Bad input directory path." + exit +end + +metadataRelPath = "content/metadata.json" +metadataPath = File.join( inputPath, metadataRelPath ) + +if not File.exists?( metadataPath ) or not File.readable?( metadataPath ) + puts "Cannot find metadata file." + puts "Make sure #{metadataRelPath} exists and is readable." + exit +end + +metadataFile = File.open( metadataPath, 'r' ) +metadataString = metadataFile.read +metadata = JSON.parse( metadataString ) +metadataFile.close unless metadataFile == nil + +if not metadata["pluginName"].nil? and + not metadata["name"].nil? and + not metadata["version"].nil? and + not metadata["description"].nil? and + not metadata["type"].nil? and + not metadata["manifest"].nil? and + not metadata["manifest"]["main"].nil? and + not metadata["manifest"]["icon"].nil? + outputPath = File.join( inputPath, metadata["pluginName"] + "-" + metadata["version"] + ".axe" ) + puts "Bundle metadata looks ok." +else + puts "Bad metadata file." + exit +end + +# Let's add some stuff to the metadata file, this is information that's much +# easier to fill in automatically now than manually whenever. +# * Timestamp of right now i.e. packaging time. +# * Git revision because it makes sense, especially during development. +# * Bundle format version, which might never be used but we add it just in +# case we ever need to distinguish one bundle format from another. +# We save it all as _metadata.json, which then gets added to the archive as +# metadata.json instead of the original one. +_metadataPath = File.join( inputPath, "content/_metadata.json" ) +if not File.exists?( _metadataPath ) or File.writable?( _metadataPath ) + File.open( _metadataPath, 'w' ) do |f| + metadata["timestamp"] = Time.now.utc.to_i + + gitCmd = "git rev-parse --short HEAD 2>&1" + inGit = system( gitCmd + "&>/dev/null" ) #will return true only if we're in a repo + if inGit + revision = %x[ #{gitCmd} ].sub( "\n", "" ) + metadata["revision"] = revision + end + #TODO: maybe add a --release switch to disable filling in the revision? + + metadata["bundleVersion"] = BUNDLEVERSION + + f.write "\ +############################################################################ +## Metadata file generated from unpackaged '#{metadataRelPath}' +## +## Created: #{Time.now.utc.to_s} +## by: makeaxe.rb, https://github.com/tomahawk-player +## +## #### WARNING! #### +## All changes made to this file will be lost! +############################################################################\n\n" + f.write( JSON.pretty_generate( metadata ) ) + end +end + +# Let's do some zipping according to the manifest. +filesToZip = [] +begin + m = metadata["manifest"] + filesToZip << File.join( "content", m["main"] ) + m["scripts"].each do |s| + filesToZip << File.join( "content", s ) + end + filesToZip << File.join( "content", m["icon"] ) + m["resources"].each do |s| + filesToZip << File.join( "content", s ) + end +end + +puts "Creating package for #{metadata["name"]}: '#{File.basename( outputPath )}'." + +if File.exists?( outputPath ) + File.delete( outputPath ) +end + +Zip::ZipFile.open( outputPath, Zip::ZipFile::CREATE ) do |z| + filesToZip.each do |relPath| + z.add( relPath, File.join( inputPath, relPath ) ) + end + z.add( metadataRelPath, _metadataPath ) +end + +puts "Cleaning up." + +File.delete( _metadataPath ) +File.open( outputPath, 'r' ) do |f| + File.open( outputPath.sub( "axe", "md5" ), 'w' ) do |g| + g.write( Digest::MD5.hexdigest( f.read ).to_s + "\t" + File.basename( outputPath ) ) + end +end + +puts "All done. Have a nice day." From 90e61b5c813e641f2c29689d50876f3dcf20ea02 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Fri, 15 Mar 2013 11:38:13 +0100 Subject: [PATCH 083/118] JSON doesn't want comments, d'oh. --- admin/makeaxe.rb | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/admin/makeaxe.rb b/admin/makeaxe.rb index 3b35383f0..76370a225 100755 --- a/admin/makeaxe.rb +++ b/admin/makeaxe.rb @@ -110,16 +110,6 @@ metadata["bundleVersion"] = BUNDLEVERSION - f.write "\ -############################################################################ -## Metadata file generated from unpackaged '#{metadataRelPath}' -## -## Created: #{Time.now.utc.to_s} -## by: makeaxe.rb, https://github.com/tomahawk-player -## -## #### WARNING! #### -## All changes made to this file will be lost! -############################################################################\n\n" f.write( JSON.pretty_generate( metadata ) ) end end From e22b0e03c810dc496962380bce9090db21d52f0c Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Sun, 17 Mar 2013 11:58:23 +0100 Subject: [PATCH 084/118] Add --release switch to makeaxe.rb avoid inclusion of revision hash. --- admin/makeaxe.rb | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/admin/makeaxe.rb b/admin/makeaxe.rb index 76370a225..4903708b5 100755 --- a/admin/makeaxe.rb +++ b/admin/makeaxe.rb @@ -44,13 +44,25 @@ BUNDLEVERSION = 1 #might never be used but best to plan ahead -if ARGV.length < 1 +def usage puts "This script creates a Tomahawk resolver bundle." puts "\nMake sure you have the zip gem." - puts "Usage: ruby makeaxe.rb path_to_resolver_directory" + puts "\nUsage: ruby makeaxe.rb path_to_resolver_directory [options]" + puts " --release\tskip trying to add the git revision hash to the bundle" + puts " --help\t\tthis help message" +end + +if ARGV.length < 1 or not ARGV.delete( "--help" ).nil? + usage exit end +if not ARGV.delete( "--release" ).nil? + release = true +else + release = false +end + inputPath = File.absolute_path( ARGV[0] ) if not Dir.exists?( inputPath ) @@ -100,13 +112,14 @@ File.open( _metadataPath, 'w' ) do |f| metadata["timestamp"] = Time.now.utc.to_i - gitCmd = "git rev-parse --short HEAD 2>&1" - inGit = system( gitCmd + "&>/dev/null" ) #will return true only if we're in a repo - if inGit - revision = %x[ #{gitCmd} ].sub( "\n", "" ) - metadata["revision"] = revision + unless release + gitCmd = "git rev-parse --short HEAD 2>&1" + inGit = system( gitCmd + "&>/dev/null" ) #will return true only if we're in a repo + if inGit + revision = %x[ #{gitCmd} ].sub( "\n", "" ) + metadata["revision"] = revision + end end - #TODO: maybe add a --release switch to disable filling in the revision? metadata["bundleVersion"] = BUNDLEVERSION From fb77aebe5a1f9374907f247918a8df6e604faf98 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Mon, 18 Mar 2013 07:09:49 +0100 Subject: [PATCH 085/118] Bundlify 4shared. --- .../contents/code}/4shared-icon.png | Bin .../contents/code}/4shared-resolver.js | 0 4shared/content/contents/images/icon.png | Bin 0 -> 10020 bytes 4shared/content/metadata.json | 18 ++++++++++++++++++ 4 files changed, 18 insertions(+) rename 4shared/{ => content/contents/code}/4shared-icon.png (100%) rename 4shared/{ => content/contents/code}/4shared-resolver.js (100%) create mode 100644 4shared/content/contents/images/icon.png create mode 100644 4shared/content/metadata.json diff --git a/4shared/4shared-icon.png b/4shared/content/contents/code/4shared-icon.png similarity index 100% rename from 4shared/4shared-icon.png rename to 4shared/content/contents/code/4shared-icon.png diff --git a/4shared/4shared-resolver.js b/4shared/content/contents/code/4shared-resolver.js similarity index 100% rename from 4shared/4shared-resolver.js rename to 4shared/content/contents/code/4shared-resolver.js diff --git a/4shared/content/contents/images/icon.png b/4shared/content/contents/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..14e4cff77e436e18924222ad57f29b2cda2fe590 GIT binary patch literal 10020 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 Date: Mon, 18 Mar 2013 07:24:43 +0100 Subject: [PATCH 086/118] Bundlify Dilandau. --- .../contents/code}/dilandau-icon.png | Bin .../{ => content/contents/code}/dilandau.js | 0 dilandau/content/contents/images/icon.png | Bin 0 -> 9781 bytes dilandau/content/metadata.json | 18 ++++++++++++++++++ 4 files changed, 18 insertions(+) rename dilandau/{ => content/contents/code}/dilandau-icon.png (100%) rename dilandau/{ => content/contents/code}/dilandau.js (100%) create mode 100644 dilandau/content/contents/images/icon.png create mode 100644 dilandau/content/metadata.json diff --git a/dilandau/dilandau-icon.png b/dilandau/content/contents/code/dilandau-icon.png similarity index 100% rename from dilandau/dilandau-icon.png rename to dilandau/content/contents/code/dilandau-icon.png diff --git a/dilandau/dilandau.js b/dilandau/content/contents/code/dilandau.js similarity index 100% rename from dilandau/dilandau.js rename to dilandau/content/contents/code/dilandau.js diff --git a/dilandau/content/contents/images/icon.png b/dilandau/content/contents/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8cbb5addf061b6aeab771a4a050743229b44a49c GIT binary patch literal 9781 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 P00000NkvXXu0mjf{I2B= literal 0 HcmV?d00001 diff --git a/dilandau/content/metadata.json b/dilandau/content/metadata.json new file mode 100644 index 000000000..e65aff4c3 --- /dev/null +++ b/dilandau/content/metadata.json @@ -0,0 +1,18 @@ +{ + "name": "Dilandau", + "pluginName": "dilandau", + "author": "lasconic", + "email": "lasconic@gmail.com", + "version": "0.4.1", + "website": "http://gettomahawk.com", + "description": "Uses mp3 search engine http://www.dilandau.eu/ to find tracks", + "type": "resolver/javascript", + "manifest": { + "main": "contents/code/dilandau.js", + "scripts": [], + "icon": "contents/images/icon.png", + "resources": [ + "contents/code/dilandau-icon.png" + ] + } +} From d5fcd6904f2faf7d4a5e32403aa3cb950df52050 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Mon, 18 Mar 2013 07:38:16 +0100 Subject: [PATCH 087/118] Bundlify Grooveshark. --- .../{ => content/contents/code}/config.ui | 0 .../contents/code}/grooveshark-icon.png | Bin .../contents/code}/grooveshark.js | 18 +++++++++++++++ .../contents/code}/grooveshark.png | Bin .../contents/code}/grooveshark.svg | 0 grooveshark/content/contents/images/icon.png | Bin 0 -> 4803 bytes grooveshark/content/metadata.json | 21 ++++++++++++++++++ 7 files changed, 39 insertions(+) rename grooveshark/{ => content/contents/code}/config.ui (100%) rename grooveshark/{ => content/contents/code}/grooveshark-icon.png (100%) rename grooveshark/{ => content/contents/code}/grooveshark.js (96%) rename grooveshark/{ => content/contents/code}/grooveshark.png (100%) rename grooveshark/{ => content/contents/code}/grooveshark.svg (100%) create mode 100644 grooveshark/content/contents/images/icon.png create mode 100644 grooveshark/content/metadata.json diff --git a/grooveshark/config.ui b/grooveshark/content/contents/code/config.ui similarity index 100% rename from grooveshark/config.ui rename to grooveshark/content/contents/code/config.ui diff --git a/grooveshark/grooveshark-icon.png b/grooveshark/content/contents/code/grooveshark-icon.png similarity index 100% rename from grooveshark/grooveshark-icon.png rename to grooveshark/content/contents/code/grooveshark-icon.png diff --git a/grooveshark/grooveshark.js b/grooveshark/content/contents/code/grooveshark.js similarity index 96% rename from grooveshark/grooveshark.js rename to grooveshark/content/contents/code/grooveshark.js index 370c22841..76693fd14 100644 --- a/grooveshark/grooveshark.js +++ b/grooveshark/content/contents/code/grooveshark.js @@ -1,3 +1,21 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2011-2012, Leo Franchi + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + // for removing diacritics [extracted from : http://lehelk.com/2011/05/06/script-to-remove-diacritics/] var defaultDiacriticsRemovalMap = [ {'base':'A', 'letters':/[\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F]/g}, diff --git a/grooveshark/grooveshark.png b/grooveshark/content/contents/code/grooveshark.png similarity index 100% rename from grooveshark/grooveshark.png rename to grooveshark/content/contents/code/grooveshark.png diff --git a/grooveshark/grooveshark.svg b/grooveshark/content/contents/code/grooveshark.svg similarity index 100% rename from grooveshark/grooveshark.svg rename to grooveshark/content/contents/code/grooveshark.svg diff --git a/grooveshark/content/contents/images/icon.png b/grooveshark/content/contents/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0aabe3cd9c322bffeabfe5848cde7e9ebfafad0e GIT binary patch literal 4803 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 Date: Mon, 18 Mar 2013 10:02:10 +0100 Subject: [PATCH 088/118] License headers. --- .../content/contents/code/4shared-resolver.js | 19 +++++++++++++-- dilandau/content/contents/code/dilandau.js | 23 +++++++++++++++---- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/4shared/content/contents/code/4shared-resolver.js b/4shared/content/contents/code/4shared-resolver.js index 612a37241..7562c99d1 100644 --- a/4shared/content/contents/code/4shared-resolver.js +++ b/4shared/content/contents/code/4shared-resolver.js @@ -1,6 +1,21 @@ -/* - * (c) 2011 lasconic +/* === This file is part of Tomahawk Player - === + * + * Copyright 2011, lasconic + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . */ + var FSharedResolver = Tomahawk.extend(TomahawkResolver, { settings: { name: '4shared', diff --git a/dilandau/content/contents/code/dilandau.js b/dilandau/content/contents/code/dilandau.js index c8f2c404d..81e40d9d4 100644 --- a/dilandau/content/contents/code/dilandau.js +++ b/dilandau/content/contents/code/dilandau.js @@ -1,8 +1,23 @@ -/* - * (c) 2011 lasconic - * (c) 2011 leo franchi - * (c) 2012 thierry göckel +/* === This file is part of Tomahawk Player - === + * + * Copyright 2011, lasconic + * Copyright 2011, Leo Franchi + * Copyright 2012, Thierry Göckel + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . */ + var DilandauResolver = Tomahawk.extend(TomahawkResolver, { settings: { From 75b0d5707a4484d7206427e6a070ecbe2739e5e0 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Mon, 18 Mar 2013 11:32:26 +0100 Subject: [PATCH 089/118] Fix indentation. Sorry. --- 4shared/content/metadata.json | 10 +++++----- ampache/content/metadata.json | 18 +++++++++--------- grooveshark/content/metadata.json | 16 ++++++++-------- subsonic/content/metadata.json | 16 ++++++++-------- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/4shared/content/metadata.json b/4shared/content/metadata.json index 9670475f5..18fa742d8 100644 --- a/4shared/content/metadata.json +++ b/4shared/content/metadata.json @@ -9,10 +9,10 @@ "type": "resolver/javascript", "manifest": { "main": "contents/code/4shared-resolver.js", - "scripts": [], - "icon": "contents/images/icon.png", - "resources": [ - "contents/code/4shared-icon.png" - ] + "scripts": [], + "icon": "contents/images/icon.png", + "resources": [ + "contents/code/4shared-icon.png" + ] } } diff --git a/ampache/content/metadata.json b/ampache/content/metadata.json index 7a3930313..d6fa395ab 100644 --- a/ampache/content/metadata.json +++ b/ampache/content/metadata.json @@ -9,14 +9,14 @@ "type": "resolver/javascript", "manifest": { "main": "contents/code/ampache-resolver.js", - "scripts": [], - "icon": "contents/images/icon.png", - "resources": [ - "contents/code/config.ui", - "contents/code/ampache-icon.png", - "contents/code/ampache.png", - "contents/code/owncloud-icon.png", - "contents/code/owncloud.png" - ] + "scripts": [], + "icon": "contents/images/icon.png", + "resources": [ + "contents/code/config.ui", + "contents/code/ampache-icon.png", + "contents/code/ampache.png", + "contents/code/owncloud-icon.png", + "contents/code/owncloud.png" + ] } } diff --git a/grooveshark/content/metadata.json b/grooveshark/content/metadata.json index 1a3474dcc..15b9939b8 100644 --- a/grooveshark/content/metadata.json +++ b/grooveshark/content/metadata.json @@ -9,13 +9,13 @@ "type": "resolver/javascript", "manifest": { "main": "contents/code/grooveshark.js", - "scripts": [], - "icon": "contents/images/icon.png", - "resources": [ - "contents/code/config.ui", - "contents/code/grooveshark.png", - "contents/code/grooveshark.svg", - "contents/code/grooveshark-icon.png" - ] + "scripts": [], + "icon": "contents/images/icon.png", + "resources": [ + "contents/code/config.ui", + "contents/code/grooveshark.png", + "contents/code/grooveshark.svg", + "contents/code/grooveshark-icon.png" + ] } } diff --git a/subsonic/content/metadata.json b/subsonic/content/metadata.json index 0644b2ac7..3ab37f472 100644 --- a/subsonic/content/metadata.json +++ b/subsonic/content/metadata.json @@ -9,13 +9,13 @@ "type": "resolver/javascript", "manifest": { "main": "contents/code/subsonic.js", - "scripts": [], - "icon": "contents/images/icon.png", - "resources": [ - "contents/code/config.ui", - "contents/code/runnersid-icon.png", - "contents/code/subsonic-icon.png", - "contents/code/subsonic.png" - ] + "scripts": [], + "icon": "contents/images/icon.png", + "resources": [ + "contents/code/config.ui", + "contents/code/runnersid-icon.png", + "contents/code/subsonic-icon.png", + "contents/code/subsonic.png" + ] } } From f861ee4cf4bca22f74909c4844c7ac2951b2acd3 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Mon, 18 Mar 2013 11:45:06 +0100 Subject: [PATCH 090/118] Fix indentation again. --- dilandau/content/metadata.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dilandau/content/metadata.json b/dilandau/content/metadata.json index e65aff4c3..7353bd59c 100644 --- a/dilandau/content/metadata.json +++ b/dilandau/content/metadata.json @@ -9,10 +9,10 @@ "type": "resolver/javascript", "manifest": { "main": "contents/code/dilandau.js", - "scripts": [], - "icon": "contents/images/icon.png", - "resources": [ - "contents/code/dilandau-icon.png" - ] + "scripts": [], + "icon": "contents/images/icon.png", + "resources": [ + "contents/code/dilandau-icon.png" + ] } } From ebb6ea243c2034a9e8f6c6af3c0de112d925e9f3 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Mon, 18 Mar 2013 12:48:31 +0100 Subject: [PATCH 091/118] Bundlify Jamendo. --- .../contents/code}/jamendo-icon.png | Bin .../contents/code}/jamendo-resolver.js | 19 ++++++++++++++++-- jamendo/content/contents/images/icon.png | Bin 0 -> 5689 bytes jamendo/content/metadata.json | 18 +++++++++++++++++ 4 files changed, 35 insertions(+), 2 deletions(-) rename jamendo/{ => content/contents/code}/jamendo-icon.png (100%) rename jamendo/{ => content/contents/code}/jamendo-resolver.js (79%) create mode 100644 jamendo/content/contents/images/icon.png create mode 100644 jamendo/content/metadata.json diff --git a/jamendo/jamendo-icon.png b/jamendo/content/contents/code/jamendo-icon.png similarity index 100% rename from jamendo/jamendo-icon.png rename to jamendo/content/contents/code/jamendo-icon.png diff --git a/jamendo/jamendo-resolver.js b/jamendo/content/contents/code/jamendo-resolver.js similarity index 79% rename from jamendo/jamendo-resolver.js rename to jamendo/content/contents/code/jamendo-resolver.js index ec1d586d7..683f5c50e 100644 --- a/jamendo/jamendo-resolver.js +++ b/jamendo/content/contents/code/jamendo-resolver.js @@ -1,6 +1,21 @@ -/* - * (c) 2011 lasconic +/* === This file is part of Tomahawk Player - === + * + * Copyright 2011, lasconic + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . */ + var JamendoResolver = Tomahawk.extend(TomahawkResolver, { settings: { name: 'Jamendo', diff --git a/jamendo/content/contents/images/icon.png b/jamendo/content/contents/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1b0bb15502808e60c37f82c029d9b8d49626bc5c GIT binary patch literal 5689 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 Date: Mon, 18 Mar 2013 15:30:59 +0100 Subject: [PATCH 092/118] Bundlify Last.fm. --- .../contents/code}/lastfm-icon.png | Bin lastfm/{ => content/contents/code}/lastfm.js | 18 ++++++++++++++++++ lastfm/content/contents/images/icon.png | Bin 0 -> 14813 bytes lastfm/content/metadata.json | 18 ++++++++++++++++++ 4 files changed, 36 insertions(+) rename lastfm/{ => content/contents/code}/lastfm-icon.png (100%) rename lastfm/{ => content/contents/code}/lastfm.js (71%) create mode 100644 lastfm/content/contents/images/icon.png create mode 100644 lastfm/content/metadata.json diff --git a/lastfm/lastfm-icon.png b/lastfm/content/contents/code/lastfm-icon.png similarity index 100% rename from lastfm/lastfm-icon.png rename to lastfm/content/contents/code/lastfm-icon.png diff --git a/lastfm/lastfm.js b/lastfm/content/contents/code/lastfm.js similarity index 71% rename from lastfm/lastfm.js rename to lastfm/content/contents/code/lastfm.js index 1e1206883..65083bc88 100644 --- a/lastfm/lastfm.js +++ b/lastfm/content/contents/code/lastfm.js @@ -1,3 +1,21 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2011-2012, Thierry Göckel + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + var LastfmResolver = Tomahawk.extend(TomahawkResolver, { settings: { name: 'Last.fm', diff --git a/lastfm/content/contents/images/icon.png b/lastfm/content/contents/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..982d86383a6222b5b570da8043796366a7e9cce1 GIT binary patch literal 14813 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 x)~Q0nLEXUsik Date: Mon, 18 Mar 2013 19:53:49 +0100 Subject: [PATCH 093/118] Initial documentation. --- HACKING.md | 1 + README | 3 --- README.md | 12 ++++++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 HACKING.md delete mode 100644 README create mode 100644 README.md diff --git a/HACKING.md b/HACKING.md new file mode 100644 index 000000000..73a4efee2 --- /dev/null +++ b/HACKING.md @@ -0,0 +1 @@ +# Tomahawk Resolvers Developer Documentation diff --git a/README b/README deleted file mode 100644 index 6c9f4c515..000000000 --- a/README +++ /dev/null @@ -1,3 +0,0 @@ -To manually intstall a resolver: either 1) clone this repo, or 2) download the .zip, or 3) download the individual files within the individual resolver folder you are installing. - -After you have the files installed locally, open Tomahawk's preferences and from the "Services" tab click "Install from File" and select the .js file for the resolver you are installing. diff --git a/README.md b/README.md new file mode 100644 index 000000000..af5a8cf77 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +# Tomahawk Resolvers + +Supported resolvers are distributed and updated automatically through Tomahawk's Settings dialog. +To manually intstall a resolver: either +* clone this repo, +* download the .zip, or +* download all the files within the individual resolver folder you are installing. + +Since March 2013 Tomahawk resolvers have switched to a new directory structure for easy packaging. +After you have the files locally, open Tomahawk's preferences and from the "Services" tab click "Install from File" and select the .axe or .js file for the resolver you are installing. + +For developer documentation, see [HACKING.md](HACKING.md). From 11b90e1d4169fcda74e1f92f9495b76f181f4cdc Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Mon, 18 Mar 2013 22:36:23 +0100 Subject: [PATCH 094/118] Added HACKING file contents. --- HACKING.md | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 3 +- 2 files changed, 105 insertions(+), 1 deletion(-) diff --git a/HACKING.md b/HACKING.md index 73a4efee2..c15ed6e92 100644 --- a/HACKING.md +++ b/HACKING.md @@ -1 +1,104 @@ # Tomahawk Resolvers Developer Documentation + +## Developing resolvers + +The Tomahawk resolver API is currently still in flux. It is probably a good idea to use the existing resolvers as example. + +The API you should develop against is defined in [tomahawk.js](https://github.com/tomahawk-player/tomahawk/blob/master/data/js/tomahawk.js) and [QtScriptResolverHelper](https://github.com/tomahawk-player/tomahawk/blob/master/src/libtomahawk/resolvers/QtScriptResolver.h) in the Tomahawk main repo. + +If you have questions, look for us in #tomahawk on irc.freenode.net. + +## Packaging resolvers + +### Structure overview + +Starting with Tomahawk 0.7, all resolver directories must be structured as follows. + +Mandatory: +``` +content/ + + metadata.json +``` +Suggested: +``` +content/ + + metadata.json + + contents/ + + code/ + + .js + + config.ui + + + + images/ + + icon.png +``` + +This structure is commonly referred to as a resolver bundle, i.e. a resolver script with all related files and metadata. + +A bundle can be packaged or unpackaged (i.e. as it is in this repo), thus resolvers can be installed manually in two ways: +* from an unpackaged bundle, +* from a package (or axe). + +### Installing a resolver bundle + +To install a resolver from an unpackaged bundle (the preferred way for testing and development), in Tomahawk's Settings dialog click on "Install from file" and select the resolver's main .js file. + +Keep in mind that with such a path, Tomahawk expects to find the file `metadata.json` in `../..` from the main script's path. If `metadata.json` is not found, it is likely that your resolver directory is not structured properly. The resolver's main script will still be loaded, but any additional scripts will not and the accounts list in the Settings dialog will not show any metadata for the resolver (e.g. author, version, etc.). This is a **bad thing**. The only reason why a resolver without `metadata.json` is still loaded is for compatibility reasons. Plain unbundled .js files as resolvers are deprecated. You should update your resolver to a proper bundle structure as soon as possible. + +A packaged resolver bundle is a file with file extension `axe`. It is a compressed archive with all the contents of a resolver directory. To install such a bundle (the preferred way for end users who wish to install a resolver manually), in Tomahawk's Settings dialog click on "Install from file" and select the package file (`.axe`). + +**WARNING** for developers and testers: the installation process for an *unpackaged* bundle loads the resolver in-place. This means that any changed to the resolver script are applied immediately, simply by disabling and re-enabling the "installed" resolver with the account's checkbox in the accounts list. There is usually no need to remove and re-install the resolver. This also means that changes to the directory structure may make the resolver stop functioning. On the other hand, packaged bundles (axes) are decompressed and copied to a Tomahawk-managed directory (`/manualresolvers`) during the installation process, so any change to the axe can only be applied by re-installing. + +### Packaging + +#### metadata.json + +Every resolver bundle directory must contain a metadata file. This file must be named `metadata.json`, and it must be located in the directory `content` relative to the top-level resolver bundle directory. + +For example, this is a `metadata.json` file for Subsonic: +``` +{ + "name": "Subsonic", + "pluginName": "subsonic", + "author": "mack_t and Teo", + "email": "teo@kde.org", + "version": "0.5", + "website": "http://gettomahawk.com", + "description": "Searches your Subsonic server for music to play", + "type": "resolver/javascript", + "manifest": { + "main": "contents/code/subsonic.js", + "scripts": [], + "icon": "contents/images/icon.png", + "resources": [ + "contents/code/config.ui", + "contents/code/runnersid-icon.png", + "contents/code/subsonic-icon.png", + "contents/code/subsonic.png" + ] + } +} +``` + +For most purposes all the fields are mandatory. + +**WARNING**: the manifest object **must** list all the files required by the resolver. Unlisted scripts will not be loaded, and any unlisted files will not be packaged. + +#### makeaxe.rb + +If your resolver directory conforms to the previously described structure and your `metadata.json` is complete, the harder part is done. The Tomahawk team provides you with a script to automate the packaging process: [`makeaxe.rb`](admin/makeaxe.rb). You will need [ruby](http://www.ruby-lang.org/en/) 1.9.2 or later and the [zip](https://rubygems.org/gems/zip) gem. + +To create a package from a resolver directory, simply run `makeaxe.rb` with the directory path passed as parameter. + +E.g. on Linux and Mac OS X, for Subsonic and from the repository root, you would do the following: +``` +% ruby admin/makeaxe.rb subsonic +% ls subsonic +content/ subsonic-0.5.axe subsonic-0.5.md5 +``` +In this case, `subsonic-0.5.axe` is the compressed bundle and `subsonic-0.5.md5` is the MD5 checksum file. + +Please note that `makeaxe.rb` does not simply compress the contents of the directory, it also checks the metadata file and adds additional data, including a packaging timestamp and the revision hash, if any. + +Optionally, if you pass the `--release` parameter to `makeaxe.rb` it will not include the commit hash in the axe, as would be expected in a release-worthy package. + +Happy packaging! diff --git a/README.md b/README.md index af5a8cf77..8d7c36d98 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ To manually intstall a resolver: either * download the .zip, or * download all the files within the individual resolver folder you are installing. -Since March 2013 Tomahawk resolvers have switched to a new directory structure for easy packaging. After you have the files locally, open Tomahawk's preferences and from the "Services" tab click "Install from File" and select the .axe or .js file for the resolver you are installing. +Since March 2013 Tomahawk resolvers have switched to a new directory structure for easy packaging. Ideally, you should download nightly .axe files, if available. + For developer documentation, see [HACKING.md](HACKING.md). From 637cd4036466219022de5394a954b4c224a19c08 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Mon, 18 Mar 2013 23:33:12 +0100 Subject: [PATCH 095/118] Bundlify Official.fm. --- .../contents/code}/officialfm-icon.png | Bin .../{ => content/contents/code}/officialfm.js | 19 ++++++++++++++++++ official.fm/content/contents/images/icon.png | Bin 0 -> 2678 bytes official.fm/content/metadata.json | 18 +++++++++++++++++ 4 files changed, 37 insertions(+) rename official.fm/{ => content/contents/code}/officialfm-icon.png (100%) rename official.fm/{ => content/contents/code}/officialfm.js (85%) create mode 100644 official.fm/content/contents/images/icon.png create mode 100644 official.fm/content/metadata.json diff --git a/official.fm/officialfm-icon.png b/official.fm/content/contents/code/officialfm-icon.png similarity index 100% rename from official.fm/officialfm-icon.png rename to official.fm/content/contents/code/officialfm-icon.png diff --git a/official.fm/officialfm.js b/official.fm/content/contents/code/officialfm.js similarity index 85% rename from official.fm/officialfm.js rename to official.fm/content/contents/code/officialfm.js index f86ce0b43..01db89913 100644 --- a/official.fm/officialfm.js +++ b/official.fm/content/contents/code/officialfm.js @@ -1,3 +1,22 @@ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2011, lasconic + * Copyright 2011, Leo Franchi + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . + */ + var OfficialfmResolver = Tomahawk.extend(TomahawkResolver, { settings: { name: 'Official.fm', diff --git a/official.fm/content/contents/images/icon.png b/official.fm/content/contents/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e9f01d6a0664aea0830b8a810a6829b20a552291 GIT binary patch literal 2678 zcmZ8jc|6oz7r*lxV;IDgj4Y9T%_I?{nIS}x@mR7=)Qd8flr_TGN1{lLBJ>O)4_Tw^ zdnKY~9=po&jIy^Vjd*|0`{#QS$6_}*=uEH;t(;u z{J_o9VOgqg$B$-QG<&qTI9|PMK3n2$_7KyFQjj%O`k+1xEzp!Yb4p;G?TG%Q&{;^u zhGHLinZ5PRy{oFhQXt@qWM5kk{86obLY6y*E12Cs(B*DO%GOLuYe$gicx(5Nl8hQA`V7AwfjOtLw~yMA-lOrSDtObSY;(IS?tE% zJxIN7TR=RwKGOpqdyE8yMMXu#iRrdjTX{wb^X%QU!l_8^~t(~4mR>s9;WHXue@c&cK>qsFX2$uiq0a3i8 zqXRbZU-1X|5uV(^2YJxkAp9mN+G`L5;e-FNHop4B%dE%K)D#jTuViOu3oJK8^TNb& zI95f4P2(K8RmFY1 zy)&=wXyS7RI=LQgF~{IL%@OOSqij!GSXC_-|?YhtY|DwSFt^wAX7S*XbZ z1|B|}GvE^v8Y+m^)7BPIR#vWZ*6N(##m5?Eq=?GRz~82Q)_F%WQSui~=Npgttt%+0sQg)6jFKb8h#RSB zX$e2A;wLefXQ&ur4I>WguBWd*^RC3UlXogBaq}ye_4x70Qrw~F zUm+6o$*~&me#VBar6s-ReB4VfsTv7+1^>xLSi$hX>E={b+kAl$2;91V|GHa4pvYKS zRhpunUN*eD0aN!+!<`o|ESsZw60iez?dL8o_CvP_FlS&t>ifWep^Ki*ZygSi=mp=2R}Jc&g57>*LdQkx?#4;kEw-rl-r zPk+k?=)(NSBYJuQZG?+>1pMBaun8rgc=+wxcm{)UE{cDnLq0tGhe?BNu1bN&XK%y} z`kMk$*T_i2k1=|t@V*~sgVOmeSed9oFRYeJ4IdoDI(0G@RzY=jwH7F@y*RAkKiz!Q zteml=<@WSO6yl^Ng!Us6iP2{bHGeHMrlkqt;%HWa7A&lbi;HP!+|;4DIwD>61FpWi z+f4VKwduj3@$r*V>B)Tvwh{nJR=X=)YLmw&CQ@V$!vM&$hF_?Y1H`abu3Qn@zdysi z+b2fjG^Qrh1mzG&)I~B?45AIQA8d+J6k+4C1v(SrXndsdi8zVjy=^X z40LRKnLjl)(09Shivov=`i6!**x^cQQ=@=P`g!XoBe%!=?=HvR*mu}x=rgBWokS{t z5srNmT2oFAxTq&}ZSxCidU_hU(Y0@{C`!k<3UD}_wT+GKGC}E*#b>1tH+j5wk8E;d zN`LLGQn`ta-?k#eY#oJzQ;ll{a{F&NA+k4=qw9@Xo@!!hXlj1C@PV#L0a;3!Fu~{N z=Z8s2$Vxn-yStm>>sxlKr4~3SfeNQnyp3g^vdIO6nl%_69%he@TCxym_kW-luU`F{ z4~Hp_fZ#A&)X&tpNn3LPBz>3Wrq=@lBCyDuV^R8yi|k}SO%08R(I;|kRIo?Inj8?I zEzI9ln!(wFooeY1L$LIJh)7$zHy|ny%#@e?} z_OEjdY=1gdx$|Y{#%^zNb5I^xN-{LwvHb3pyGZ8*tz59or@!Z_p zszVo@T6^Y=cj52<-YzXwbFOg8sF~!$2TnHHX+q1~bOwWLVQ<0^~drb&oOY*m0nmLt+ zlCh)yPp1P60w?8L&c2DWpY3{h_`+Z}yUhOM>gs#$S2%||oH;WK$0hfga&KM6$4qka z{}maV0nmqPz)e_!8q?d*iIQAXD98<}5^j&(j6AB`uMCVpJ!l>k%zL#x0r)bILxSxX zPeTt}NzG0yve9p+9Zgn`h-ACC`r5wcIk)a2?*V68O&o0gS0?dpBCjovQF^JzL&G*B z&re8ib*v%QaC9ehe^qsWMx|lzU-hbwh>CXUl_hD;?Ku1DibB=o=N<7|r0>4-zmBIA RCBii$urfbwR%z-P|6d)F%Ju*N literal 0 HcmV?d00001 diff --git a/official.fm/content/metadata.json b/official.fm/content/metadata.json new file mode 100644 index 000000000..289b74a1f --- /dev/null +++ b/official.fm/content/metadata.json @@ -0,0 +1,18 @@ +{ + "name": "Official.fm", + "pluginName": "officialfm", + "author": "Leo and lasconic", + "email": "lasconic@gmail.com", + "version": "1.0.5", + "website": "http://gettomahawk.com", + "description": "Searches Official.fm for playable tracks", + "type": "resolver/javascript", + "manifest": { + "main": "contents/code/officialfm.js", + "scripts": [], + "icon": "contents/images/icon.png", + "resources": [ + "contents/code/officialfm-icon.png" + ] + } +} From ea89200d12f6d32cebcce8acd38f42455e2300a6 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 19 Mar 2013 14:32:10 +0100 Subject: [PATCH 096/118] Bundlify Qobuz. --- qobuz/{ => content/contents/code}/config.ui | 0 qobuz/{ => content/contents/code}/qobuz.js | 0 qobuz/{ => content/contents/code}/qobuz.png | Bin qobuz/content/contents/images/icon.png | Bin 0 -> 60703 bytes qobuz/content/metadata.json | 19 +++++++++++++++++++ 5 files changed, 19 insertions(+) rename qobuz/{ => content/contents/code}/config.ui (100%) rename qobuz/{ => content/contents/code}/qobuz.js (100%) rename qobuz/{ => content/contents/code}/qobuz.png (100%) create mode 100644 qobuz/content/contents/images/icon.png create mode 100644 qobuz/content/metadata.json diff --git a/qobuz/config.ui b/qobuz/content/contents/code/config.ui similarity index 100% rename from qobuz/config.ui rename to qobuz/content/contents/code/config.ui diff --git a/qobuz/qobuz.js b/qobuz/content/contents/code/qobuz.js similarity index 100% rename from qobuz/qobuz.js rename to qobuz/content/contents/code/qobuz.js diff --git a/qobuz/qobuz.png b/qobuz/content/contents/code/qobuz.png similarity index 100% rename from qobuz/qobuz.png rename to qobuz/content/contents/code/qobuz.png diff --git a/qobuz/content/contents/images/icon.png b/qobuz/content/contents/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9b3e5f19519fd5df58dd030e6adf36fa81593a2b GIT binary patch literal 60703 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 Date: Tue, 19 Mar 2013 14:51:50 +0100 Subject: [PATCH 097/118] Bundlify SoundCloud. --- .../{ => content/contents/code}/config.ui | 0 .../content/contents/code/soundcloud-icon.png | Bin 0 -> 1913 bytes .../{ => content/contents/code}/soundcloud.js | 19 +++++++++++++++-- .../contents/code}/soundcloud.png | Bin soundcloud/content/contents/images/icon.png | Bin 0 -> 1913 bytes soundcloud/content/metadata.json | 20 ++++++++++++++++++ soundcloud/soundcloud-icon.png | Bin 37199 -> 0 bytes 7 files changed, 37 insertions(+), 2 deletions(-) rename soundcloud/{ => content/contents/code}/config.ui (100%) create mode 100644 soundcloud/content/contents/code/soundcloud-icon.png rename soundcloud/{ => content/contents/code}/soundcloud.js (91%) rename soundcloud/{ => content/contents/code}/soundcloud.png (100%) create mode 100644 soundcloud/content/contents/images/icon.png create mode 100644 soundcloud/content/metadata.json delete mode 100644 soundcloud/soundcloud-icon.png diff --git a/soundcloud/config.ui b/soundcloud/content/contents/code/config.ui similarity index 100% rename from soundcloud/config.ui rename to soundcloud/content/contents/code/config.ui diff --git a/soundcloud/content/contents/code/soundcloud-icon.png b/soundcloud/content/contents/code/soundcloud-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b685e9b84a9091d01fe420ed2d126e46cb2c4015 GIT binary patch literal 1913 zcmV-<2Zs2GP)hDWcC@qtQ4XGk1HZ&NvsDnVQxLEM$s`9K7W8&Y z){E^5K>(+Ngva`BBVrS?qMfjQ*c4#ntr1|I@J>VK0k*ws3XogM5V|NxYcW7o0K(U3 zEe7}%z-kJ(0}PVAZX;7H3#fpZa?X6?AmY!i)JY}DptmUqW`Nql6MsxS_gCyp0v4Dx zLOkHhBEsVWRZu_>aPhHLw~m7d&=l|*Ve(uhqGS?03c%#X0H%;2z>0H|T4ON9c~b}U z?sbUXvkD~91ifP^=*ST0*fp5L=a4@29nxoif@a)8gfkFPh=Af6rHo3<2#ug^VIzoE z5sc3kUBkp#O8g7E?Al0V53)Xv;QNQ$38=ZrJ+kAGHNKA1ja2ee124O zOP zFq)COC2ziOo)5GAULXd$jnZ}H|>QX zT}+I}QbAP};DBcwSYlT{FuU8jou05$tu65x9nf0lfJ|@m0;lC=p4gJL(7IN;?#7gu zG${lG20XEkT7X$(nh#)}eFZXaZ1wYQEU*G^W^8%M$VY(6C^c2tTYgU)+7aJz2vnQq z%X!)M2!6dB0v10k$00~CM4&aPO-P1}tVFm3uzV3-0q)$~v;s762q~v& z5t$j%9Be8rf-RHBR_3wB>KM;MLav7)wJw*Hn^UVRT!{)!GxJzBDkSiBtv1C<_L{^V*i>53Ds31krDloEG68gqhkp7_$vFF~!jZd~A z_Q)2bP7M?Yn87peP)P;wmUwgvAiAf$iSb{*!1%#kptr8`%8|(jhYSe;F~ALQ!sjWM z56{=p7y3Y(?m~234=9h~diN@@)&+<^@e)YmEMHIy0vvFiR#pMo+O!9rLj9f}LE9Hu z!J1=Y!9fripQnn?YjH%Dtp|-a%D0&&asw_T1~61y0Xaj&j9IAL_9+Z5b~hHtdI13n za3Ve9QdzeZrk&O(Wd#PcJbPOCEKpF?hh5A7hX(|8eFf9(qq?N3dUYpDJjF3wK zQ@aH{4225+1Q!V1x240b0F)L4YYLc}3Scz_gj)e&{Jj9FDWFDxLqMu3vom*QO9=vw zBFP@dNXVck<#tfa7rc)aZvH5IQ$JI<3#=_t@_U^hPrnNB%kfKyV3Z#jQ#k31h3)gHA&)y-*&*xY0?QVqQ=kt3w_@m;5{{ +/* === This file is part of Tomahawk Player - === + * + * Copyright 2012, Thierry Göckel + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . */ + var SoundcloudResolver = Tomahawk.extend(TomahawkResolver, { getConfigUi: function () { diff --git a/soundcloud/soundcloud.png b/soundcloud/content/contents/code/soundcloud.png similarity index 100% rename from soundcloud/soundcloud.png rename to soundcloud/content/contents/code/soundcloud.png diff --git a/soundcloud/content/contents/images/icon.png b/soundcloud/content/contents/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b685e9b84a9091d01fe420ed2d126e46cb2c4015 GIT binary patch literal 1913 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 P1D4GR+v7#n?vein+*pv@ From 58ab8063e1da5b852172ccfff0de8f3c09bfb6f0 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 19 Mar 2013 16:56:10 +0100 Subject: [PATCH 098/118] Bundlify 8tracks. --- .../{ => content/contents/code}/8tracks.js | 21 +++++++++++++++--- 8tracks/content/contents/images/icon.png | Bin 0 -> 8689 bytes 8tracks/content/metadata.json | 16 +++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) rename 8tracks/{ => content/contents/code}/8tracks.js (78%) create mode 100644 8tracks/content/contents/images/icon.png create mode 100644 8tracks/content/metadata.json diff --git a/8tracks/8tracks.js b/8tracks/content/contents/code/8tracks.js similarity index 78% rename from 8tracks/8tracks.js rename to 8tracks/content/contents/code/8tracks.js index 6878d44fa..589ca1958 100644 --- a/8tracks/8tracks.js +++ b/8tracks/content/contents/code/8tracks.js @@ -1,7 +1,22 @@ -/* - * (c) 2011 Janez Troha (https://github.com/dz0ny) - * (c) 2011 Leo Franchi === + * + * Copyright 2011, Janez Troha (https://github.com/dz0ny) + * Copyright 2011, Leo Franchi + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . */ + var EightTracksResolver = Tomahawk.extend(TomahawkResolver, { settings: { name: '8tracks Resolver', diff --git a/8tracks/content/contents/images/icon.png b/8tracks/content/contents/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..155e894cb2925391bba05df02d2491475fb97050 GIT binary patch literal 8689 zcmVF}4^dfF_3rdaTDVjxmJCxCYSF7#9Ie4$mOQdJN+j zLyYSHO^$I9(Bv3b0-GEjW}E`*h9I3TA&mQjKwvNeyO#_gtX?J3i|wBc!fIT`U1Hob z5Ex;=Xb{r=#h6jqo8I{H*AKgZ8ju(x0RvLt<#U|gHI;?)W^vA$GnhG}gN`YaP%=@l z1zHRC_Z*;m{{gnX+Rdh|-SiyjqY#A{qmc%T5C~$lutXt7VR5{1BVZ`d7$ic%X+7F~PWI1?y?TV%`2Ntm=21`ol-=P%+NH(bhP7c8P{YKOZ%VcDhY?UI*Z z2||$J|Bj;=FoN!$Lp=J_T7LTAlWcf-r?buMb)~18?9&`At>^@r#JFH|MxH0ytSK{7?4!zYNA2h zK`gxXW8(yng|YkI?mNL*v!-+V2XEy1t1cq1Jh$I9xEZlEj@jp^eYqek-?s;B8E5Z*wf(I3+K8 zuSFsPEGr+{e#)|PyS9Ro76BcTC$i#=7m`zgwHvk)$J(kA825SNglIu^&As5x6S)7> zfFL!)PV4IA8+Uw!w_J6x`(texZ_W6OmTwGNYqZwHah(1?c_r^>?@1QF^t1NxJWsOx z`~{pjV=7OsT2B}!J_tiONe&&}3Eh1PAkpBpP)wiN&Nu$zqn!Wx`9PeSYgP9clm5&u za(3a3F=d=VN}2wYQlgYf|CW8#hCmy^TUK0xQi?C%buUN#7$GEReM08qxFZOI5rU~x zTKR{+`ZE?UoQ=?i7#vT|T$x??I3|uG!YC$=HBl52#rFSNYmC-p{eQ{A3+dr`63

S=&)>#* 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 Date: Tue, 19 Mar 2013 17:28:20 +0100 Subject: [PATCH 099/118] Bundlify VKontakte. --- .../contents/code}/vkontakte-resolver.js | 18 ++++++++++++++++-- vkontakte/content/contents/images/icon.png | Bin 0 -> 10459 bytes vkontakte/content/metadata.json | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) rename vkontakte/{ => content/contents/code}/vkontakte-resolver.js (94%) create mode 100644 vkontakte/content/contents/images/icon.png create mode 100644 vkontakte/content/metadata.json diff --git a/vkontakte/vkontakte-resolver.js b/vkontakte/content/contents/code/vkontakte-resolver.js similarity index 94% rename from vkontakte/vkontakte-resolver.js rename to vkontakte/content/contents/code/vkontakte-resolver.js index 4a7cd177c..a781cd7a0 100644 --- a/vkontakte/vkontakte-resolver.js +++ b/vkontakte/content/contents/code/vkontakte-resolver.js @@ -1,5 +1,19 @@ -/* - * (c) 2011 Krzysztof Klinikowski +/* === This file is part of Tomahawk Player - === + * + * Copyright 2011, Krzysztof Klinikowski + * + * Tomahawk is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tomahawk is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tomahawk. If not, see . */ debugMode = false; diff --git a/vkontakte/content/contents/images/icon.png b/vkontakte/content/contents/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ced9db3b3471ce6388bc31679e16a0ba92305b60 GIT binary patch literal 10459 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 RoVox2002ovPDHLkV1n(@Dg^)l literal 0 HcmV?d00001 diff --git a/vkontakte/content/metadata.json b/vkontakte/content/metadata.json new file mode 100644 index 000000000..ae5e53a5b --- /dev/null +++ b/vkontakte/content/metadata.json @@ -0,0 +1,16 @@ +{ + "name": "VKontakte", + "pluginName": "vkontakte", + "author": "Krzysztof Klinikowski", + "email": "kkszysiu@gmail.com", + "version": "0.1", + "website": "http://gettomahawk.com", + "description": "Searches VKontakte (vk.com) for music to play", + "type": "resolver/javascript", + "manifest": { + "main": "contents/code/vkontakte-resolver.js", + "scripts": [], + "icon": "contents/images/icon.png", + "resources": [] + } +} From 82287502cdeed90ff701ddabd711296738fa6206 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 19 Mar 2013 17:36:42 +0100 Subject: [PATCH 100/118] Bundlify YouTube. --- youtube/{ => content/contents/code}/config.ui | 0 .../contents/code}/youtube-icon.png | Bin .../{ => content/contents/code}/youtube.js | 1 + .../{ => content/contents/code}/youtube.png | Bin youtube/content/contents/images/icon.png | Bin 0 -> 12193 bytes youtube/content/metadata.json | 20 ++++++++++++++++++ 6 files changed, 21 insertions(+) rename youtube/{ => content/contents/code}/config.ui (100%) rename youtube/{ => content/contents/code}/youtube-icon.png (100%) rename youtube/{ => content/contents/code}/youtube.js (99%) rename youtube/{ => content/contents/code}/youtube.png (100%) create mode 100644 youtube/content/contents/images/icon.png create mode 100644 youtube/content/metadata.json diff --git a/youtube/config.ui b/youtube/content/contents/code/config.ui similarity index 100% rename from youtube/config.ui rename to youtube/content/contents/code/config.ui diff --git a/youtube/youtube-icon.png b/youtube/content/contents/code/youtube-icon.png similarity index 100% rename from youtube/youtube-icon.png rename to youtube/content/contents/code/youtube-icon.png diff --git a/youtube/youtube.js b/youtube/content/contents/code/youtube.js similarity index 99% rename from youtube/youtube.js rename to youtube/content/contents/code/youtube.js index a40750c65..ffbbcc3d8 100644 --- a/youtube/youtube.js +++ b/youtube/content/contents/code/youtube.js @@ -18,6 +18,7 @@ * * NOTICE: This resolver and its intent, is for demonstrational purposes only **/ + var YoutubeResolver = Tomahawk.extend(TomahawkResolver, { getConfigUi: function () diff --git a/youtube/youtube.png b/youtube/content/contents/code/youtube.png similarity index 100% rename from youtube/youtube.png rename to youtube/content/contents/code/youtube.png diff --git a/youtube/content/contents/images/icon.png b/youtube/content/contents/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2b9bb3a23e85b936e3fade42625178716c482e72 GIT binary patch literal 12193 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 TurU71u?J)&6(y>~i~|1;?uFbT literal 0 HcmV?d00001 diff --git a/youtube/content/metadata.json b/youtube/content/metadata.json new file mode 100644 index 000000000..d95c65777 --- /dev/null +++ b/youtube/content/metadata.json @@ -0,0 +1,20 @@ +{ + "name": "YouTube", + "pluginName": "youtube", + "author": "Hugo, Leo and Thierry", + "email": "lfranchi@kde.org", + "version": "0.9.7", + "website": "http://gettomahawk.com", + "description": "Searches YouTube for audio content", + "type": "resolver/javascript", + "manifest": { + "main": "contents/code/youtube.js", + "scripts": [], + "icon": "contents/images/icon.png", + "resources": [ + "contents/code/config.ui", + "contents/code/youtube-icon.png", + "contents/code/youtube.png" + ] + } +} From 01a8832ce3e113f3f6c1b4f5461613db0aaea7a1 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 19 Mar 2013 18:08:24 +0100 Subject: [PATCH 101/118] Add licensing information. --- HACKING.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/HACKING.md b/HACKING.md index c15ed6e92..7248e9972 100644 --- a/HACKING.md +++ b/HACKING.md @@ -4,10 +4,20 @@ The Tomahawk resolver API is currently still in flux. It is probably a good idea to use the existing resolvers as example. -The API you should develop against is defined in [tomahawk.js](https://github.com/tomahawk-player/tomahawk/blob/master/data/js/tomahawk.js) and [QtScriptResolverHelper](https://github.com/tomahawk-player/tomahawk/blob/master/src/libtomahawk/resolvers/QtScriptResolver.h) in the Tomahawk main repo. +The API you should develop against is defined in [`tomahawk.js`](https://github.com/tomahawk-player/tomahawk/blob/master/data/js/tomahawk.js) and [`QtScriptResolverHelper`](https://github.com/tomahawk-player/tomahawk/blob/master/src/libtomahawk/resolvers/QtScriptResolver.h) in the Tomahawk main repo. If you have questions, look for us in #tomahawk on irc.freenode.net. +### Licensing + +Tomahawk resolvers are considered derivative works of Tomahawk, specifically through the previously mentioned `tomahawk.js` and `QtScriptResolver.h` files. These files are released under a GNU General Public License, version 3 or later. + +Thus, developers who release a resolver are expected to +* release the resolver code they produce under a license compatible with Tomahawk, and specifically with Tomahawk's resolver interface, and +* add a copyright and licensing statement at the beginning of those resolver file(s) that interface with Tomahawk, with a wording that makes their licensing (and compatibility) clear. + +Exceptions to this requirement can be evaluated upon request by the Tomahawk team. + ## Packaging resolvers ### Structure overview From a47c79a60edde8ea2661716e0d152033ba5822a3 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 19 Mar 2013 18:26:10 +0100 Subject: [PATCH 102/118] Improve wording in HACKING. --- HACKING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HACKING.md b/HACKING.md index 7248e9972..e1d119379 100644 --- a/HACKING.md +++ b/HACKING.md @@ -52,7 +52,7 @@ A bundle can be packaged or unpackaged (i.e. as it is in this repo), thus resolv To install a resolver from an unpackaged bundle (the preferred way for testing and development), in Tomahawk's Settings dialog click on "Install from file" and select the resolver's main .js file. -Keep in mind that with such a path, Tomahawk expects to find the file `metadata.json` in `../..` from the main script's path. If `metadata.json` is not found, it is likely that your resolver directory is not structured properly. The resolver's main script will still be loaded, but any additional scripts will not and the accounts list in the Settings dialog will not show any metadata for the resolver (e.g. author, version, etc.). This is a **bad thing**. The only reason why a resolver without `metadata.json` is still loaded is for compatibility reasons. Plain unbundled .js files as resolvers are deprecated. You should update your resolver to a proper bundle structure as soon as possible. +Keep in mind that with such a path, Tomahawk expects to find the file `metadata.json` in `../..` from the main script's path. If `metadata.json` is not found, it is likely that your resolver directory is not structured properly. The resolver's main script will still be loaded, but any additional scripts will not and the accounts list in the Settings dialog will not show any metadata for the resolver (e.g. author, version, etc.). This is a **bad thing**. The only reason why a resolver without `metadata.json` is still loaded is backward compatibility. Plain unbundled .js files as resolvers are deprecated. You should update your resolver to a proper bundle structure as soon as possible. A packaged resolver bundle is a file with file extension `axe`. It is a compressed archive with all the contents of a resolver directory. To install such a bundle (the preferred way for end users who wish to install a resolver manually), in Tomahawk's Settings dialog click on "Install from file" and select the package file (`.axe`). From 71e3c9b2c5df10ab6304ae521cd909705342d998 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Sun, 24 Mar 2013 11:31:34 +0100 Subject: [PATCH 103/118] Add images dir for compatibility reasons. --- beets/content/contents/images/icon.png | Bin 0 -> 10657 bytes beets/content/metadata.json | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 beets/content/contents/images/icon.png diff --git a/beets/content/contents/images/icon.png b/beets/content/contents/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3f8f6b286e6e35512ab95d4c03dd20ea4aa2424a GIT binary patch literal 10657 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 Date: Sun, 24 Mar 2013 17:02:52 +0100 Subject: [PATCH 104/118] Make custom url handler asynchronous in Google Drive. --- googledrive/googledrive.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 05cad48f4..f60cd427d 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -97,7 +97,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //musicManager.showDatabase(); //this.googleDriveMusicManagerTests() ; - Tomahawk.addCustomUrlHandler( "googledrive", "getStreamUrl" ); + Tomahawk.addCustomUrlHandler( "googledrive", "getStreamUrl", "true" ); Tomahawk.reportCapabilities( TomahawkResolverCapability.Browsable | TomahawkResolverCapability.AccountFactory ); //TODO updateDatabase when? @@ -235,12 +235,11 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { return return_object; }, - getStreamUrl: function (ourUrl) { + getStreamUrl: function (quid, ourUrl) { var songId = ourUrl.replace("googledrive://id/", ""); - var meta = JSON.parse(this.oauth.ogetSyncJSON('https://www.googleapis.com/drive/v2/files/' + songId)); - - return(this.oauth.createOauthUrl(meta['downloadUrl'])) ; - + this.oauth.ogetJSON('https://www.googleapis.com/drive/v2/files/' + songId, function(meta) { + var url = this.oauth.createOauthUrl(meta['downloadUrl']); + Tomahawk.reportStreamUrl(quid, url);}.bind(this)); }, googleDriveMusicManagerTests: function() { From 97101ba9e505b30cb7c7afe08aaceff87cd4a433 Mon Sep 17 00:00:00 2001 From: loclamor Date: Mon, 25 Mar 2013 13:11:59 +0100 Subject: [PATCH 105/118] update to allow cloudstream to ask a new streamUrl --- dropbox/dropbox.js | 8 +++++--- googledrive/googledrive.js | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index 9766fbdb0..186a4569f 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -129,7 +129,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { //Tomahawk.log("size : " + meta['bytes']); //Tomahawk.log("mime : " + meta['mime_type']); //Tomahawk.log('request : ' + DumpObjectIndented( this.getStreamUrl(path) )); - Tomahawk.ReadCloudFile(path, path, meta['bytes'], meta['mime_type'], this.getStreamUrl(path), "onID3TagCallback" + Tomahawk.ReadCloudFile(path, path, meta['bytes'], meta['mime_type'], this.getStreamUrl(path), "onID3TagCallback", "getStreamUrl" ); } } @@ -263,8 +263,10 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { getStreamUrl: function (ourUrl) { var path = ourUrl.replace("dropbox://path/", ""); - - return this.oauth.oAuthGetUrl(this.getFileUrl + path); + Tomahawk.log(">>>>> file+path : " + this.getFileUrl + path); + var url = this.oauth.oAuthGetUrl(this.getFileUrl + path); + Tomahawk.log(">>>>> streamUrl : " + url); + return url; }, oauth: { diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index c848bf4a3..3dacbd67c 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -141,7 +141,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //Tomahawk.log("size : " + item['file']['fileSize']); //Tomahawk.log("mime : " + item['file']['mimeType']); //Tomahawk.log('url : ' + this.getStreamUrl(item['file']['id'])); - Tomahawk.ReadCloudFile(file['originalFilename'], file['id'], file['fileSize'], file['mimeType'], this.oauth.createOauthUrl(file['downloadUrl']), "onID3TagCallback"); + Tomahawk.ReadCloudFile(file['originalFilename'], file['id'], file['fileSize'], file['mimeType'], this.oauth.createOauthUrl(file['downloadUrl']), "onID3TagCallback", ""); } } } From 5ecd12d02cf5033f0ec02917f2ab7909e0aadddc Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Wed, 27 Mar 2013 17:43:43 +0100 Subject: [PATCH 106/118] Flush track DB when deleting association. --- dropbox/dropbox.js | 1 + 1 file changed, 1 insertion(+) diff --git a/dropbox/dropbox.js b/dropbox/dropbox.js index 9afc4fdd8..4358b3874 100644 --- a/dropbox/dropbox.js +++ b/dropbox/dropbox.js @@ -72,6 +72,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { dbLocal.setItem('dropbox.cursor',''); this.oauth.deleteAssociation(); + musicManager.flushDatabase(); }, From 8091d38918d4a055d6e8035f3168b3478d9ddbe3 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Wed, 27 Mar 2013 18:21:08 +0100 Subject: [PATCH 107/118] Flush DB when deleting association in google drive. --- googledrive/googledrive.js | 1 + 1 file changed, 1 insertion(+) diff --git a/googledrive/googledrive.js b/googledrive/googledrive.js index 1fc26d1b9..d3d1d8f1f 100644 --- a/googledrive/googledrive.js +++ b/googledrive/googledrive.js @@ -73,6 +73,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { dbLocal.setItem('googledrive.cursor',''); this.oauth.deleteAssociation(); + musicManager.flushDatabase(); }, From ea28e7af9fe0903c94624f2c50c19a948521a940 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Sun, 24 Mar 2013 17:24:56 +0100 Subject: [PATCH 108/118] Bundle Google Drive and Dropbox resolvers. --- dropbox/{ => content/contents/code}/config.ui | 0 .../{ => content/contents/code}/dropbox.js | 0 .../{ => content/contents/code}/dropbox.svg | 0 .../contents/code}/jsOAuth-1.3.6.min.js | 0 .../contents/code}/musicManager.js | 0 dropbox/content/contents/images/icon.svg | 39 +++++++++++++++++++ dropbox/content/metadata.json | 19 +++++++++ .../{ => content/contents/code}/config.ui | 0 .../contents/code}/googledrive.js | 0 .../contents/code}/googledrive.svg | 0 .../contents/code}/musicManager.js | 0 googledrive/content/contents/images/icon.svg | 11 ++++++ googledrive/content/metadata.json | 19 +++++++++ 13 files changed, 88 insertions(+) rename dropbox/{ => content/contents/code}/config.ui (100%) rename dropbox/{ => content/contents/code}/dropbox.js (100%) rename dropbox/{ => content/contents/code}/dropbox.svg (100%) rename dropbox/{ => content/contents/code}/jsOAuth-1.3.6.min.js (100%) rename dropbox/{ => content/contents/code}/musicManager.js (100%) create mode 100644 dropbox/content/contents/images/icon.svg create mode 100644 dropbox/content/metadata.json rename googledrive/{ => content/contents/code}/config.ui (100%) rename googledrive/{ => content/contents/code}/googledrive.js (100%) rename googledrive/{ => content/contents/code}/googledrive.svg (100%) rename googledrive/{ => content/contents/code}/musicManager.js (100%) create mode 100644 googledrive/content/contents/images/icon.svg create mode 100644 googledrive/content/metadata.json diff --git a/dropbox/config.ui b/dropbox/content/contents/code/config.ui similarity index 100% rename from dropbox/config.ui rename to dropbox/content/contents/code/config.ui diff --git a/dropbox/dropbox.js b/dropbox/content/contents/code/dropbox.js similarity index 100% rename from dropbox/dropbox.js rename to dropbox/content/contents/code/dropbox.js diff --git a/dropbox/dropbox.svg b/dropbox/content/contents/code/dropbox.svg similarity index 100% rename from dropbox/dropbox.svg rename to dropbox/content/contents/code/dropbox.svg diff --git a/dropbox/jsOAuth-1.3.6.min.js b/dropbox/content/contents/code/jsOAuth-1.3.6.min.js similarity index 100% rename from dropbox/jsOAuth-1.3.6.min.js rename to dropbox/content/contents/code/jsOAuth-1.3.6.min.js diff --git a/dropbox/musicManager.js b/dropbox/content/contents/code/musicManager.js similarity index 100% rename from dropbox/musicManager.js rename to dropbox/content/contents/code/musicManager.js diff --git a/dropbox/content/contents/images/icon.svg b/dropbox/content/contents/images/icon.svg new file mode 100644 index 000000000..6f63627d1 --- /dev/null +++ b/dropbox/content/contents/images/icon.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dropbox/content/metadata.json b/dropbox/content/metadata.json new file mode 100644 index 000000000..d6db240ae --- /dev/null +++ b/dropbox/content/metadata.json @@ -0,0 +1,19 @@ +{ + "name": "Dropbox", + "pluginName": "dropbox", + "author": "ISI-Peasy team", + "email": "isi-peasy@googlegroups.com", + "version": "0.2", + "website": "http://gettomahawk.com", + "description": "Browse your music files on Dropbox", + "type": "resolver/javascript", + "manifest": { + "main": "contents/code/dropbox.js", + "scripts": ["contents/code/musicManager.js", "contents/code/jsOAuth-1.3.6.min.js"], + "icon": "contents/images/icon.svg", + "resources": [ + "contents/code/config.ui", + "contents/code/dropbox.svg" + ] + } +} diff --git a/googledrive/config.ui b/googledrive/content/contents/code/config.ui similarity index 100% rename from googledrive/config.ui rename to googledrive/content/contents/code/config.ui diff --git a/googledrive/googledrive.js b/googledrive/content/contents/code/googledrive.js similarity index 100% rename from googledrive/googledrive.js rename to googledrive/content/contents/code/googledrive.js diff --git a/googledrive/googledrive.svg b/googledrive/content/contents/code/googledrive.svg similarity index 100% rename from googledrive/googledrive.svg rename to googledrive/content/contents/code/googledrive.svg diff --git a/googledrive/musicManager.js b/googledrive/content/contents/code/musicManager.js similarity index 100% rename from googledrive/musicManager.js rename to googledrive/content/contents/code/musicManager.js diff --git a/googledrive/content/contents/images/icon.svg b/googledrive/content/contents/images/icon.svg new file mode 100644 index 000000000..0f6af9439 --- /dev/null +++ b/googledrive/content/contents/images/icon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/googledrive/content/metadata.json b/googledrive/content/metadata.json new file mode 100644 index 000000000..cf7b0c4d9 --- /dev/null +++ b/googledrive/content/metadata.json @@ -0,0 +1,19 @@ +{ + "name": "Google Drive", + "pluginName": "googledrive", + "author": "ISI-Peasy team", + "email": "isi-peasy@googlegroups.com", + "version": "0.2", + "website": "http://gettomahawk.com", + "description": "Browse your music files on Google Drive", + "type": "resolver/javascript", + "manifest": { + "main": "contents/code/googledrive.js", + "scripts": ["contents/code/musicManager.js"], + "icon": "contents/images/icon.svg", + "resources": [ + "contents/code/config.ui", + "contents/code/googledrive.svg" + ] + } +} From f2f890523d4a7480d95a22bd5cdc2b331b48bbb0 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Wed, 27 Mar 2013 21:47:55 +0100 Subject: [PATCH 109/118] Handle case when querying the musicManager DB. --- dropbox/content/contents/code/musicManager.js | 10 +++++----- googledrive/content/contents/code/musicManager.js | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dropbox/content/contents/code/musicManager.js b/dropbox/content/contents/code/musicManager.js index 6ef9b77de..d97b9b6cb 100644 --- a/dropbox/content/contents/code/musicManager.js +++ b/dropbox/content/contents/code/musicManager.js @@ -101,7 +101,7 @@ var musicManager = { tx.executeSql('INSERT INTO track (id, track, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [id, track, artist, album, albumpos, year, genre, size, duration, mimetype, bitrate, url]); }); - Tomahawk.log("Insertion inside "+this.dbName+""); + Tomahawk.log("Insertion inside "+this.dbName+" : " + id); }, deleteTrack: function (tabTrackDetails) @@ -161,7 +161,7 @@ var musicManager = { { var results = [] ; this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT DISTINCT album FROM track WHERE artist=?', [artist], function (tx, resultsQuery ) { + tx.executeSql('SELECT DISTINCT album FROM track WHERE LOWER(artist)=LOWER(?)', [artist], function (tx, resultsQuery ) { var len = resultsQuery.rows.length, i; //Tomahawk.log("Number of albums results : "+ len); for (i = 0; i < len; i++) { @@ -176,7 +176,7 @@ var musicManager = { tracksQuery: function(artist , album, callBack) { this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT * FROM track WHERE artist=? and album=?', [artist,album], + tx.executeSql('SELECT * FROM track WHERE LOWER(artist)=LOWER(?) and LOWER(album)=LOWER(?)', [artist,album], function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; Tomahawk.log("Number of results : "+results.length+ " "+ DumpObjectIndented(results)); @@ -190,7 +190,7 @@ var musicManager = { { this.dbSQL.transaction(function (tx) { // Select first or limit mechanisim ? - tx.executeSql("SELECT * FROM track WHERE (album LIKE ?) or (artist LIKE ?) or (track LIKE ?)", ["%"+searchString+"%","%"+searchString+"%","%"+searchString+"%"], + tx.executeSql("SELECT * FROM track WHERE (LOWER(artist) LIKE LOWER(?)) or (LOWER(album) LIKE LOWER(?)) or (LOWER(track) LIKE LOWER(?))", ["%"+searchString+"%","%"+searchString+"%","%"+searchString+"%"], function (tx, resultsQuery ) { var len = resultsQuery.rows.length, i; var results = musicManager.parseSongAttriutes(resultsQuery) ; @@ -205,7 +205,7 @@ var musicManager = { { var results = [] ; this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT * FROM track WHERE album=? and artist=? and track=? ', [album,artist,track], // Select first or limit mechanisim ? + tx.executeSql('SELECT * FROM track WHERE LOWER(artist)=LOWER(?) and LOWER(album)=LOWER(?) and LOWER(track)=LOWER(?) ', [artist,album,track], // Select first or limit mechanisim ? function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; //Tomahawk.log("Number of track results for resolve : "+results.length); diff --git a/googledrive/content/contents/code/musicManager.js b/googledrive/content/contents/code/musicManager.js index 20955e244..360078c2b 100644 --- a/googledrive/content/contents/code/musicManager.js +++ b/googledrive/content/contents/code/musicManager.js @@ -162,7 +162,7 @@ var musicManager = { { var results = [] ; this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT DISTINCT album FROM track WHERE artist=?', [artist], function (tx, resultsQuery ) { + tx.executeSql('SELECT DISTINCT album FROM track WHERE LOWER(artist)=LOWER(?)', [artist], function (tx, resultsQuery ) { var len = resultsQuery.rows.length, i; //Tomahawk.log("Number of albums results : "+ len); for (i = 0; i < len; i++) { @@ -177,7 +177,7 @@ var musicManager = { tracksQuery: function(artist , album, callBack) { this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT * FROM track WHERE artist=? and album=?', [artist,album], + tx.executeSql('SELECT * FROM track WHERE LOWER(artist)=LOWER(?) and LOWER(album)=LOWER(?)', [artist,album], function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; Tomahawk.log("Number of results : "+results.length+ " "+ DumpObjectIndented(results)); @@ -191,7 +191,7 @@ var musicManager = { { this.dbSQL.transaction(function (tx) { // Select first or limit mechanisim ? - tx.executeSql("SELECT * FROM track WHERE (album LIKE ?) or (artist LIKE ?) or (track LIKE ?)", ["%"+searchString+"%","%"+searchString+"%","%"+searchString+"%"], + tx.executeSql("SELECT * FROM track WHERE (LOWER(artist) LIKE LOWER(?)) or (LOWER(album) LIKE LOWER(?)) or (LOWER(track) LIKE LOWER(?))", ["%"+searchString+"%","%"+searchString+"%","%"+searchString+"%"], function (tx, resultsQuery ) { var len = resultsQuery.rows.length, i; var results = musicManager.parseSongAttriutes(resultsQuery) ; @@ -206,7 +206,7 @@ var musicManager = { { var results = [] ; this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT * FROM track WHERE album=? and artist=? and track=? ', [album,artist,track], // Select first or limit mechanisim ? + tx.executeSql('SELECT * FROM track WHERE LOWER(artist)=LOWER(?) and LOWER(album)=LOWER(?) and LOWER(track)=LOWER(?) ', [artist,album,track], // Select first or limit mechanisim ? function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; //Tomahawk.log("Number of track results for resolve : "+results.length); From 7cfa33d7474402530a242527795deb28030ca586 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Thu, 28 Mar 2013 00:31:18 +0100 Subject: [PATCH 110/118] Better Handle of resolve in musicManager. Fix return of resolve so it return a list. --- dropbox/content/contents/code/musicManager.js | 4 ++-- googledrive/content/contents/code/musicManager.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dropbox/content/contents/code/musicManager.js b/dropbox/content/contents/code/musicManager.js index d97b9b6cb..f40ff38bb 100644 --- a/dropbox/content/contents/code/musicManager.js +++ b/dropbox/content/contents/code/musicManager.js @@ -205,12 +205,12 @@ var musicManager = { { var results = [] ; this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT * FROM track WHERE LOWER(artist)=LOWER(?) and LOWER(album)=LOWER(?) and LOWER(track)=LOWER(?) ', [artist,album,track], // Select first or limit mechanisim ? + tx.executeSql('SELECT * FROM track WHERE (LOWER(artist)=LOWER(?) and LOWER(album)=LOWER(?) and LOWER(track)=LOWER(?)) OR (LOWER(artist)=LOWER(?) and LOWER(track)=LOWER(?)) ', [artist,album,track,artist,track], // Select first or limit mechanisim ? function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; //Tomahawk.log("Number of track results for resolve : "+results.length); // Filter to give only ONE row : improvement possible : set up a limit ( even if tomahawk is already doing it ) - callBack(results[0]) ; + callBack(results) ; }); }); }, diff --git a/googledrive/content/contents/code/musicManager.js b/googledrive/content/contents/code/musicManager.js index 360078c2b..516588903 100644 --- a/googledrive/content/contents/code/musicManager.js +++ b/googledrive/content/contents/code/musicManager.js @@ -206,12 +206,12 @@ var musicManager = { { var results = [] ; this.dbSQL.transaction(function (tx) { - tx.executeSql('SELECT * FROM track WHERE LOWER(artist)=LOWER(?) and LOWER(album)=LOWER(?) and LOWER(track)=LOWER(?) ', [artist,album,track], // Select first or limit mechanisim ? + tx.executeSql('SELECT * FROM track WHERE (LOWER(artist)=LOWER(?) and LOWER(album)=LOWER(?) and LOWER(track)=LOWER(?)) OR (LOWER(artist)=LOWER(?) and LOWER(track)=LOWER(?)) ', [artist,album,track,artist,track], // Select first or limit mechanisim ? function (tx, resultsQuery ) { var results = musicManager.parseSongAttriutes(resultsQuery) ; //Tomahawk.log("Number of track results for resolve : "+results.length); // Filter to give only ONE row : improvement possible : set up a limit ( even if tomahawk is already doing it ) - callBack(results[0]) ; + callBack(results) ; }); }); }, From b80ba8c7b9d5dde331499bc57bc893481404b37e Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Thu, 28 Mar 2013 14:42:37 +0100 Subject: [PATCH 111/118] Add error handling when executing SQL in musicManagers. --- dropbox/content/contents/code/musicManager.js | 10 +++++----- googledrive/content/contents/code/musicManager.js | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/dropbox/content/contents/code/musicManager.js b/dropbox/content/contents/code/musicManager.js index f40ff38bb..0e18c4626 100644 --- a/dropbox/content/contents/code/musicManager.js +++ b/dropbox/content/contents/code/musicManager.js @@ -152,7 +152,7 @@ var musicManager = { results.push(resultsQuery.rows.item(i).artist) ; } callBack(results); - }); + }, function(tx, error){ Tomahawk.log(error.message); }); }); }, @@ -168,7 +168,7 @@ var musicManager = { results.push (resultsQuery.rows.item(i).album) ; } callBack(results); - }); + }, function(tx, error){ Tomahawk.log(error.message); }); }); }, @@ -181,7 +181,7 @@ var musicManager = { var results = musicManager.parseSongAttriutes(resultsQuery) ; Tomahawk.log("Number of results : "+results.length+ " "+ DumpObjectIndented(results)); callBack(results) ; - }); + }, function(tx, error){ Tomahawk.log(error.message); }); }); }, @@ -196,7 +196,7 @@ var musicManager = { var results = musicManager.parseSongAttriutes(resultsQuery) ; //Tomahawk.log("Number of track results for query : "+results.length); callBack(results) ; - }); + }, function(tx, error){ Tomahawk.log(error.message); }); }); }, @@ -211,7 +211,7 @@ var musicManager = { //Tomahawk.log("Number of track results for resolve : "+results.length); // Filter to give only ONE row : improvement possible : set up a limit ( even if tomahawk is already doing it ) callBack(results) ; - }); + }, function(tx, error){ Tomahawk.log(error.message); }); }); }, }; diff --git a/googledrive/content/contents/code/musicManager.js b/googledrive/content/contents/code/musicManager.js index 516588903..7b3c2da57 100644 --- a/googledrive/content/contents/code/musicManager.js +++ b/googledrive/content/contents/code/musicManager.js @@ -153,7 +153,7 @@ var musicManager = { results.push(resultsQuery.rows.item(i).artist) ; } callBack(results); - }); + }, function(tx, error){ Tomahawk.log(error.message); }); }); }, @@ -169,7 +169,7 @@ var musicManager = { results.push (resultsQuery.rows.item(i).album) ; } callBack(results); - }); + }, function(tx, error){ Tomahawk.log(error.message); }); }); }, @@ -182,7 +182,7 @@ var musicManager = { var results = musicManager.parseSongAttriutes(resultsQuery) ; Tomahawk.log("Number of results : "+results.length+ " "+ DumpObjectIndented(results)); callBack(results) ; - }); + }, function(tx, error){ Tomahawk.log(error.message); }); }); }, @@ -197,7 +197,7 @@ var musicManager = { var results = musicManager.parseSongAttriutes(resultsQuery) ; //Tomahawk.log("Number of track results for query : "+results.length); callBack(results) ; - }); + }, function(tx, error){ Tomahawk.log(error.message); }); }); }, @@ -212,7 +212,7 @@ var musicManager = { //Tomahawk.log("Number of track results for resolve : "+results.length); // Filter to give only ONE row : improvement possible : set up a limit ( even if tomahawk is already doing it ) callBack(results) ; - }); + }, function(tx, error){ Tomahawk.log(error.message); }); }); }, }; From 43583b544ad6e2579b34cc40eb5f85b35f93a840 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Thu, 28 Mar 2013 16:32:15 +0100 Subject: [PATCH 112/118] Update readCloudUrl function name. --- dropbox/content/contents/code/dropbox.js | 2 +- googledrive/content/contents/code/googledrive.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dropbox/content/contents/code/dropbox.js b/dropbox/content/contents/code/dropbox.js index 4358b3874..cbdd41f9b 100644 --- a/dropbox/content/contents/code/dropbox.js +++ b/dropbox/content/contents/code/dropbox.js @@ -130,7 +130,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { //Tomahawk.log("size : " + meta['bytes']); //Tomahawk.log("mime : " + meta['mime_type']); //Tomahawk.log('request : ' + DumpObjectIndented( this.getStreamUrl(path) )); - Tomahawk.ReadCloudFile(path, path, meta['bytes'], meta['mime_type'], this.getStreamUrl(path), "onID3TagCallback", "getStreamUrl" + Tomahawk.readCloudFile(path, path, meta['bytes'], meta['mime_type'], this.getStreamUrl(path), "onID3TagCallback", "getStreamUrl" ); } } diff --git a/googledrive/content/contents/code/googledrive.js b/googledrive/content/contents/code/googledrive.js index d3d1d8f1f..2b7f60100 100644 --- a/googledrive/content/contents/code/googledrive.js +++ b/googledrive/content/contents/code/googledrive.js @@ -142,7 +142,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //Tomahawk.log("size : " + item['file']['fileSize']); //Tomahawk.log("mime : " + item['file']['mimeType']); //Tomahawk.log('url : ' + this.getStreamUrl(item['file']['id'])); - Tomahawk.ReadCloudFile(file['originalFilename'], file['id'], file['fileSize'], file['mimeType'], this.oauth.createOauthUrl(file['downloadUrl']), "onID3TagCallback", ""); + Tomahawk.readCloudFile(file['originalFilename'], file['id'], file['fileSize'], file['mimeType'], this.oauth.createOauthUrl(file['downloadUrl']), "onID3TagCallback", ""); } } } From c95ab93814156fa25494d8daccadcf5b129e4c1c Mon Sep 17 00:00:00 2001 From: Knarf64 Date: Fri, 29 Mar 2013 10:57:38 +0100 Subject: [PATCH 113/118] Handling undefined album insertion into database, with bunch of test to proove it. --- dropbox/content/contents/code/musicManager.js | 12 +++++++++--- googledrive/content/contents/code/googledrive.js | 3 ++- googledrive/content/contents/code/musicManager.js | 12 +++++++++--- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/dropbox/content/contents/code/musicManager.js b/dropbox/content/contents/code/musicManager.js index 0e18c4626..aaa95e5d5 100644 --- a/dropbox/content/contents/code/musicManager.js +++ b/dropbox/content/contents/code/musicManager.js @@ -68,7 +68,7 @@ var musicManager = { var id = tabTrackDetails["id"] || ''; var track = tabTrackDetails["track"] || ''; var artist = tabTrackDetails["artist"] || ''; - var album = tabTrackDetails["album"] || ''; + var album = tabTrackDetails["album"] || 'undefined'; var albumpos = tabTrackDetails["albumpos"] || ''; var year = tabTrackDetails["year"] || ''; var genre = tabTrackDetails["genre"] || '' ; @@ -78,8 +78,8 @@ var musicManager = { var bitrate = tabTrackDetails["bitrate"] || '' ; var url = tabTrackDetails["url"] || '' ; - // check core information provided - if (id == "" || track == "" || album=="" || artist =="" || url=="") { + // check core information provided + if (id == "" || track == "" || artist =="" || url=="") { Tomahawk.log("Insertion Failed : core information track isn't provided to "+this.dbName); return ; } @@ -327,6 +327,12 @@ var musicManager = { musicManager.addTrack(this.tabTrackDetails) ; // should log a core unprovided error }, + insertionUndefinedAlbumTest:function() { + this.tabTrackDetails = {"id":"22" , "track": "Division Bell", "artist": "PinkFloyd", "album": "", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + musicManager.addTrack(this.tabTrackDetails) ; // should add album undefined row + + }, + deletionWithoutKeyTest:function() { this.tabTrackDetails = {"id":"" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; musicManager.deleteTrack(this.tabTrackDetails) ; diff --git a/googledrive/content/contents/code/googledrive.js b/googledrive/content/contents/code/googledrive.js index 2b7f60100..ad624a077 100644 --- a/googledrive/content/contents/code/googledrive.js +++ b/googledrive/content/contents/code/googledrive.js @@ -245,7 +245,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { googleDriveMusicManagerTests: function() { //musicManagerTester.flushDatabaseTest() ; - //musicManagerTester.init() ; + musicManagerTester.init() ; + //musicManagerTester.insertionUndefinedAlbumTest() ; //musicManagerTester.addTrackTest() ; //musicManager.deletionWithoutKeyTest(); //musicManagerTester.populateDatabase(1) ; diff --git a/googledrive/content/contents/code/musicManager.js b/googledrive/content/contents/code/musicManager.js index 7b3c2da57..98817080c 100644 --- a/googledrive/content/contents/code/musicManager.js +++ b/googledrive/content/contents/code/musicManager.js @@ -69,7 +69,7 @@ var musicManager = { var id = tabTrackDetails["id"] || ''; var track = tabTrackDetails["track"] || ''; var artist = tabTrackDetails["artist"] || ''; - var album = tabTrackDetails["album"] || ''; + var album = tabTrackDetails["album"] || 'undefined'; var albumpos = tabTrackDetails["albumpos"] || ''; var year = tabTrackDetails["year"] || ''; var genre = tabTrackDetails["genre"] || '' ; @@ -79,8 +79,8 @@ var musicManager = { var bitrate = tabTrackDetails["bitrate"] || '' ; var url = tabTrackDetails["url"] || '' ; - // check core information provided - if (id == "" || track == "" || album=="" || artist =="" || url=="") { + // check core information provided + if (id == "" || track == "" || artist =="" || url=="") { Tomahawk.log("Insertion Failed : core information track isn't provided to "+this.dbName); return ; } @@ -318,6 +318,12 @@ var musicManager = { musicManager.addTrack(this.tabTrackDetails) ; // should log a core unprovided error }, + insertionUndefinedAlbumTest:function() { + this.tabTrackDetails = {"id":"22" , "track": "Division Bell", "artist": "PinkFloyd", "album": "", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; + musicManager.addTrack(this.tabTrackDetails) ; // should add album undefined row + + }, + deletionWithoutKeyTest:function() { this.tabTrackDetails = {"id":"" , "track": "Division Bell", "artist": "PinkFloyd", "album": "Division Bell", "albumpos": "Track1" ,"year": "1980","genre": "Divin" ,"size": "3000","duration":"3:06","mimetype":"flac","bitrate":"256mps","url":"www.pinkFloyd.com/DivisionBell" }; musicManager.deleteTrack(this.tabTrackDetails) ; From d9792290e7beab1a6298985137f2bf9ff47162b5 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Fri, 29 Mar 2013 13:03:42 +0100 Subject: [PATCH 114/118] Remove OAuth App key and secret from resolvers. Add fields to set the App key and secret in the config.ui --- dropbox/content/contents/code/config.ui | 27 +++++++++++++++++ dropbox/content/contents/code/dropbox.js | 29 +++++++++++++++++-- googledrive/content/contents/code/config.ui | 27 +++++++++++++++++ .../content/contents/code/googledrive.js | 28 ++++++++++++++++-- 4 files changed, 107 insertions(+), 4 deletions(-) diff --git a/dropbox/content/contents/code/config.ui b/dropbox/content/contents/code/config.ui index 65e1693d2..1fd0df7f9 100644 --- a/dropbox/content/contents/code/config.ui +++ b/dropbox/content/contents/code/config.ui @@ -55,6 +55,33 @@ + + + + OAuth developer key : + + + + + + + App Key + + + + + + + App Secret + + + + + + + + + diff --git a/dropbox/content/contents/code/dropbox.js b/dropbox/content/contents/code/dropbox.js index cbdd41f9b..ef83f13c1 100644 --- a/dropbox/content/contents/code/dropbox.js +++ b/dropbox/content/contents/code/dropbox.js @@ -50,6 +50,16 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { signal: "clicked()", javascriptCallback: "resolver.deleteClicked();" }] + }, + { + name: "consumerKey", + widget: "appKeyLineEdit", + property: "text" + }, + { + name: "consumerSecret", + widget: "appSecretLineEdit", + property: "text" },], images: [{ "dropbox.svg": Tomahawk.readBase64(this.settings.icon) @@ -58,6 +68,19 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { }, newConfigSaved: function () { + var userConfig = this.getUserConfig(); + + if (this.oauth.oauthSettings.consumerKey !== userConfig.consumerKey || + this.oauth.oauthSettings.consumerSecret !== userConfig.consumerSecret) + { + this.oauth.oauthSettings.consumerKey = userConfig.consumerKey.trim(); + this.oauth.oauthSettings.consumerSecret = userConfig.consumerSecret.trim(); + + dbLocal.setItem('dropbox.consumerKey', this.oauth.oauthSettings.consumerKey); + dbLocal.setItem('dropbox.consumerSecret', this.oauth.oauthSettings.consumerSecret); + + this.oauth.init(); + } }, associateClicked: function () { @@ -265,6 +288,8 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { oauth: { init: function(){ + this.oauthSettings.consumerKey = dbLocal.getItem('dropbox.consumerKey', ''); + this.oauthSettings.consumerSecret = dbLocal.getItem('dropbox.consumerSecret', ''); this.oauthSettings.accessTokenKey = dbLocal.getItem('dropbox.accessTokenKey',''); this.oauthSettings.accessTokenSecret = dbLocal.getItem('dropbox.accessTokenSecret',''); @@ -322,8 +347,8 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { oauthEngine: null, oauthSettings: { - consumerKey: '7scivkf1tstl8dl', - consumerSecret: 'lu05s08m19h0dib', + consumerKey: '', + consumerSecret: '', requestTokenUrl: 'https://api.dropbox.com/1/oauth/request_token', authorizationUrl: 'https://www.dropbox.com/1/oauth/authorize', accessTokenUrl: 'https://api.dropbox.com/1/oauth/access_token', diff --git a/googledrive/content/contents/code/config.ui b/googledrive/content/contents/code/config.ui index f38581678..802e7c1d8 100755 --- a/googledrive/content/contents/code/config.ui +++ b/googledrive/content/contents/code/config.ui @@ -61,6 +61,33 @@ + + + + OAuth developer key : + + + + + + + App Key + + + + + + + App Secret + + + + + + + + + diff --git a/googledrive/content/contents/code/googledrive.js b/googledrive/content/contents/code/googledrive.js index ad624a077..985a94b51 100644 --- a/googledrive/content/contents/code/googledrive.js +++ b/googledrive/content/contents/code/googledrive.js @@ -51,6 +51,16 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { signal: "clicked()", javascriptCallback: "resolver.deleteClicked();" }] + }, + { + name: "clientId", + widget: "appKeyLineEdit", + property: "text" + }, + { + name: "clientSecret", + widget: "appSecretLineEdit", + property: "text" },], images: [{ 'googledrive.svg': Tomahawk.readBase64(this.settings.icon) @@ -59,6 +69,18 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { }, newConfigSaved: function () { + var userConfig = this.getUserConfig(); + + if (this.oauth.clientId !== userConfig.clientId || + this.oauth.clientSecret !== userConfig.clientSecret) + { + this.oauth.clientId = userConfig.clientId.trim(); + this.oauth.clientSecret = userConfig.clientSecret.trim(); + + dbLocal.setItem('googledrive.clientId', this.oauth.clientId); + dbLocal.setItem('googledrive.clientSecret', this.oauth.clientSecret); + + } }, associateClicked: function () { @@ -296,6 +318,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { oauth: { init: function(){ + this.clientId = dbLocal.getItem('googledrive.clientId',''); + this.clientSecret = dbLocal.getItem('googledrive.clientSecret',''); this.accessToken = dbLocal.getItem('googledrive.accessToken',''); this.refreshToken = dbLocal.getItem('googledrive.refreshToken',''); this.expiresOn = dbLocal.getItem('googledrive.expiresOn',''); @@ -395,8 +419,8 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //Private member - clientId: '440397511251.apps.googleusercontent.com', - clientSecret: 'Y2ucuavLH6HN4CmlPGhdHuxu', + clientId: '', + clientSecret: '', oauthUrl: 'https://accounts.google.com/o/oauth2/auth', tokenUrl: 'https://accounts.google.com/o/oauth2/token', scopes: 'https://www.googleapis.com/auth/drive.readonly', From 27912d0350f2dde90c37814e7cc50f35aaf95790 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Tue, 9 Apr 2013 15:32:52 +0200 Subject: [PATCH 115/118] Remove call to addLocalJSFil. Now using resolver bundle. --- dropbox/content/contents/code/dropbox.js | 4 +--- googledrive/content/contents/code/googledrive.js | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/dropbox/content/contents/code/dropbox.js b/dropbox/content/contents/code/dropbox.js index ef83f13c1..382f744d0 100644 --- a/dropbox/content/contents/code/dropbox.js +++ b/dropbox/content/contents/code/dropbox.js @@ -105,10 +105,8 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { init: function () { Tomahawk.log("Beginnning INIT of Dropbox resovler"); - Tomahawk.addLocalJSFile('jsOAuth-1.3.6.min.js'); - Tomahawk.addLocalJSFile("musicManager.js"); - dbLocal.setItem("dropbox.cursor",""); + //dbLocal.setItem("dropbox.cursor",""); this.cursor = dbLocal.getItem('dropbox.cursor',''); diff --git a/googledrive/content/contents/code/googledrive.js b/googledrive/content/contents/code/googledrive.js index 985a94b51..3f0afec25 100644 --- a/googledrive/content/contents/code/googledrive.js +++ b/googledrive/content/contents/code/googledrive.js @@ -109,8 +109,6 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { //dbLocal.setItem("googledrive.cursor",""); //Tomahawk.showWebInspector(); - - Tomahawk.addLocalJSFile("musicManager.js"); this.cursor = dbLocal.getItem('googledrive.cursor',''); From 52977ca7ab50ba326042f66780958121db540cd2 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Wed, 10 Apr 2013 10:49:58 +0200 Subject: [PATCH 116/118] Encode url when the custom url handler is called. --- dropbox/content/contents/code/dropbox.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dropbox/content/contents/code/dropbox.js b/dropbox/content/contents/code/dropbox.js index 382f744d0..5efe2b824 100644 --- a/dropbox/content/contents/code/dropbox.js +++ b/dropbox/content/contents/code/dropbox.js @@ -278,7 +278,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { getStreamUrl: function (ourUrl) { var path = ourUrl.replace("dropbox://path/", ""); Tomahawk.log(">>>>> file+path : " + this.getFileUrl + path); - var url = this.oauth.oAuthGetUrl(this.getFileUrl + path); + var url = this.oauth.oAuthGetUrl(encodeURI(this.getFileUrl + path)); Tomahawk.log(">>>>> streamUrl : " + url); return url; }, From 3d4d3c3cac017a67605b2d826cfc5a0220794c65 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Wed, 10 Apr 2013 10:54:40 +0200 Subject: [PATCH 117/118] Update track database when artists() is called. --- dropbox/content/contents/code/dropbox.js | 3 ++- googledrive/content/contents/code/googledrive.js | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dropbox/content/contents/code/dropbox.js b/dropbox/content/contents/code/dropbox.js index 5efe2b824..91ccf765e 100644 --- a/dropbox/content/contents/code/dropbox.js +++ b/dropbox/content/contents/code/dropbox.js @@ -142,7 +142,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { //Tomahawk.log("Entry n°" + i + ", Path: " + path /*+ ", Meta: " + DumpObjectIndented(meta)*/); if(!meta){ Tomahawk.log("Deleting : " + path); - //dbSQL.deleteTrack(path); + musicManager.deleteTrack({id:path}); }else{ if(!meta['is_dir'] && this.isMimeTypeSupported(meta['mime_type'])){ //Tomahawk.log(DumpObjectIndented(meta)); @@ -223,6 +223,7 @@ var DropboxResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.log("google drive artists returned: "); Tomahawk.addArtistResults(return_artists); }); + this.updateDatabase(); }, albums: function( qid, artist ) diff --git a/googledrive/content/contents/code/googledrive.js b/googledrive/content/contents/code/googledrive.js index 3f0afec25..e5899d73f 100644 --- a/googledrive/content/contents/code/googledrive.js +++ b/googledrive/content/contents/code/googledrive.js @@ -210,6 +210,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { Tomahawk.log("google drive artists returned: "); Tomahawk.addArtistResults(return_artists); }); + this.updateDatabase(); }, albums: function( qid, artist ) From 8b3b89172612f962c7f52b1f1c3680b582380e14 Mon Sep 17 00:00:00 2001 From: AltarBeastiful Date: Thu, 11 Apr 2013 13:11:38 +0200 Subject: [PATCH 118/118] Change function name to asyncFormPostRequest. --- googledrive/content/contents/code/googledrive.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/googledrive/content/contents/code/googledrive.js b/googledrive/content/contents/code/googledrive.js index e5899d73f..bf3a41c58 100644 --- a/googledrive/content/contents/code/googledrive.js +++ b/googledrive/content/contents/code/googledrive.js @@ -363,7 +363,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { this.getRefreshedAccessToken(function (){this.opostJSON(url, data, success);}.bind(this)); }else{ //TODO treat case no parameters given - Tomahawk.asyncPostRequest(url, data, function (data) { + Tomahawk.asyncFormPostRequest(url, data, function (data) { success(JSON.parse(data.responseText)); }, {'Authorization': 'Bearer '+ this.accessToken}); } @@ -456,7 +456,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { + '&client_secret='+ this.clientSecret + '&redirect_uri=' + this.redirectUri; - Tomahawk.asyncPostRequest(this.tokenUrl, params, function(data){ + Tomahawk.asyncFormPostRequest(this.tokenUrl, params, function(data){ this.onAccessTokenReceived(data, callback); }.bind(this)); } @@ -503,7 +503,7 @@ var GoogleDriveResolver = Tomahawk.extend(TomahawkResolver, { + '&client_id=' + this.clientId + '&client_secret=' + this.clientSecret; - Tomahawk.asyncPostRequest(this.tokenUrl, params, function(data){ + Tomahawk.asyncFormPostRequest(this.tokenUrl, params, function(data){ this.onAccessTokenReceived(data, callback); }.bind(this)); },