From f79761541333cdd1bd37b4230841d245742b872b Mon Sep 17 00:00:00 2001 From: Correl Roush Date: Thu, 27 May 2010 22:38:06 -0400 Subject: [PATCH] Initial commit --- default.py | 27 + default.tbn | Bin 0 -> 43855 bytes resources/language/English/strings.xml | 20 + resources/lib/basictypes/__init__.py | 8 + resources/lib/basictypes/basic_types.py | 274 ++ resources/lib/basictypes/booleanfix.py | 66 + resources/lib/basictypes/boundary.py | 303 +++ resources/lib/basictypes/bytes.py | 76 + resources/lib/basictypes/callable.py | 309 +++ .../lib/basictypes/datatypedefinition.py | 91 + resources/lib/basictypes/date_types.py | 108 + .../lib/basictypes/datedatetime_types.py | 196 ++ resources/lib/basictypes/datemx_types.py | 383 +++ resources/lib/basictypes/debug.py | 57 + resources/lib/basictypes/decimaldt.py | 21 + resources/lib/basictypes/domainname.py | 37 + resources/lib/basictypes/enumeration.py | 282 ++ resources/lib/basictypes/factory.py | 20 + resources/lib/basictypes/interfaces.py | 257 ++ resources/lib/basictypes/latebind.py | 68 + resources/lib/basictypes/license.txt | 35 + resources/lib/basictypes/list_types.py | 227 ++ resources/lib/basictypes/pythoninterfaces.py | 893 +++++++ resources/lib/basictypes/registry.py | 16 + resources/lib/basictypes/rlist.py | 48 + resources/lib/basictypes/rstring.py | 67 + resources/lib/basictypes/typeunion.py | 87 + resources/lib/basictypes/vfs/__init__.py | 18 + resources/lib/basictypes/vfs/basepath.py | 154 ++ resources/lib/basictypes/vfs/filepath.py | 360 +++ resources/lib/basictypes/vfs/test_filepath.py | 116 + resources/lib/basictypes/wx/__init__.py | 1 + resources/lib/basictypes/wx/colour.py | 59 + resources/lib/basictypes/wx/font.py | 13 + resources/lib/basictypes/wx/pen.py | 212 ++ resources/lib/basictypes/wx/wxcopyreg.py | 131 + resources/lib/basictypes/wxtypes/__init__.py | 1 + resources/lib/basictypes/wxtypes/colour.py | 59 + resources/lib/basictypes/wxtypes/font.py | 13 + resources/lib/basictypes/wxtypes/pen.py | 212 ++ resources/lib/basictypes/wxtypes/wxcopyreg.py | 131 + resources/lib/basictypes/xmlgenerator.py | 55 + resources/lib/gui.py | 138 + resources/lib/repeater.py | 41 + resources/lib/simplejson/__init__.py | 318 +++ resources/lib/simplejson/_speedups.c | 2329 +++++++++++++++++ resources/lib/simplejson/decoder.py | 354 +++ resources/lib/simplejson/encoder.py | 440 ++++ resources/lib/simplejson/scanner.py | 65 + resources/lib/simplejson/tool.py | 37 + .../lib/transmissionrpc-0.3-python2.4.patch | 80 + .../transmissionrpc-0.3-python2.4/__init__.py | 10 + .../constants.py | 230 ++ .../transmission.py | 606 +++++ .../transmissionrpc-0.3-python2.4/utils.py | 138 + resources/lib/transmissionrpc-0.3/__init__.py | 10 + .../lib/transmissionrpc-0.3/constants.py | 230 ++ .../lib/transmissionrpc-0.3/transmission.py | 605 +++++ resources/lib/transmissionrpc-0.3/utils.py | 135 + resources/lib/transmissionrpc-0.4/__init__.py | 10 + .../lib/transmissionrpc-0.4/constants.py | 234 ++ .../lib/transmissionrpc-0.4/transmission.py | 628 +++++ resources/lib/transmissionrpc-0.4/utils.py | 138 + resources/lib/transmissionrpc/__init__.py | 10 + resources/lib/transmissionrpc/constants.py | 230 ++ resources/lib/transmissionrpc/transmission.py | 606 +++++ resources/lib/transmissionrpc/utils.py | 138 + resources/settings.xml | 8 + .../PAL/script-Transmission-details.xml | 20 + .../default/PAL/script-Transmission-main.xml | 216 ++ resources/skins/default/media/black.png | Bin 0 -> 265 bytes resources/skins/default/media/blue.png | Bin 0 -> 227 bytes .../media/list-bg-selected-nofocus.png | Bin 0 -> 1346 bytes .../skins/default/media/list-bg-selected.png | Bin 0 -> 3510 bytes resources/skins/default/media/list-bg.png | Bin 0 -> 554 bytes .../skins/default/media/transmission-main.png | Bin 0 -> 155056 bytes .../skins/default/media/transmission-main.xcf | Bin 0 -> 1053942 bytes resources/skins/default/skin.xml | 11 + resources/skins/media/.directory | 3 + resources/skins/media/transmission-512.png | Bin 0 -> 43855 bytes 80 files changed, 13529 insertions(+) create mode 100644 default.py create mode 100644 default.tbn create mode 100644 resources/language/English/strings.xml create mode 100644 resources/lib/basictypes/__init__.py create mode 100644 resources/lib/basictypes/basic_types.py create mode 100644 resources/lib/basictypes/booleanfix.py create mode 100644 resources/lib/basictypes/boundary.py create mode 100644 resources/lib/basictypes/bytes.py create mode 100644 resources/lib/basictypes/callable.py create mode 100644 resources/lib/basictypes/datatypedefinition.py create mode 100644 resources/lib/basictypes/date_types.py create mode 100644 resources/lib/basictypes/datedatetime_types.py create mode 100644 resources/lib/basictypes/datemx_types.py create mode 100644 resources/lib/basictypes/debug.py create mode 100644 resources/lib/basictypes/decimaldt.py create mode 100644 resources/lib/basictypes/domainname.py create mode 100644 resources/lib/basictypes/enumeration.py create mode 100644 resources/lib/basictypes/factory.py create mode 100644 resources/lib/basictypes/interfaces.py create mode 100644 resources/lib/basictypes/latebind.py create mode 100644 resources/lib/basictypes/license.txt create mode 100644 resources/lib/basictypes/list_types.py create mode 100644 resources/lib/basictypes/pythoninterfaces.py create mode 100644 resources/lib/basictypes/registry.py create mode 100644 resources/lib/basictypes/rlist.py create mode 100644 resources/lib/basictypes/rstring.py create mode 100644 resources/lib/basictypes/typeunion.py create mode 100644 resources/lib/basictypes/vfs/__init__.py create mode 100644 resources/lib/basictypes/vfs/basepath.py create mode 100644 resources/lib/basictypes/vfs/filepath.py create mode 100644 resources/lib/basictypes/vfs/test_filepath.py create mode 100644 resources/lib/basictypes/wx/__init__.py create mode 100644 resources/lib/basictypes/wx/colour.py create mode 100644 resources/lib/basictypes/wx/font.py create mode 100644 resources/lib/basictypes/wx/pen.py create mode 100644 resources/lib/basictypes/wx/wxcopyreg.py create mode 100644 resources/lib/basictypes/wxtypes/__init__.py create mode 100644 resources/lib/basictypes/wxtypes/colour.py create mode 100644 resources/lib/basictypes/wxtypes/font.py create mode 100644 resources/lib/basictypes/wxtypes/pen.py create mode 100644 resources/lib/basictypes/wxtypes/wxcopyreg.py create mode 100644 resources/lib/basictypes/xmlgenerator.py create mode 100644 resources/lib/gui.py create mode 100644 resources/lib/repeater.py create mode 100644 resources/lib/simplejson/__init__.py create mode 100644 resources/lib/simplejson/_speedups.c create mode 100644 resources/lib/simplejson/decoder.py create mode 100644 resources/lib/simplejson/encoder.py create mode 100644 resources/lib/simplejson/scanner.py create mode 100644 resources/lib/simplejson/tool.py create mode 100644 resources/lib/transmissionrpc-0.3-python2.4.patch create mode 100644 resources/lib/transmissionrpc-0.3-python2.4/__init__.py create mode 100755 resources/lib/transmissionrpc-0.3-python2.4/constants.py create mode 100755 resources/lib/transmissionrpc-0.3-python2.4/transmission.py create mode 100644 resources/lib/transmissionrpc-0.3-python2.4/utils.py create mode 100644 resources/lib/transmissionrpc-0.3/__init__.py create mode 100755 resources/lib/transmissionrpc-0.3/constants.py create mode 100755 resources/lib/transmissionrpc-0.3/transmission.py create mode 100644 resources/lib/transmissionrpc-0.3/utils.py create mode 100755 resources/lib/transmissionrpc-0.4/__init__.py create mode 100755 resources/lib/transmissionrpc-0.4/constants.py create mode 100755 resources/lib/transmissionrpc-0.4/transmission.py create mode 100644 resources/lib/transmissionrpc-0.4/utils.py create mode 100644 resources/lib/transmissionrpc/__init__.py create mode 100755 resources/lib/transmissionrpc/constants.py create mode 100755 resources/lib/transmissionrpc/transmission.py create mode 100644 resources/lib/transmissionrpc/utils.py create mode 100644 resources/settings.xml create mode 100644 resources/skins/default/PAL/script-Transmission-details.xml create mode 100644 resources/skins/default/PAL/script-Transmission-main.xml create mode 100644 resources/skins/default/media/black.png create mode 100644 resources/skins/default/media/blue.png create mode 100644 resources/skins/default/media/list-bg-selected-nofocus.png create mode 100644 resources/skins/default/media/list-bg-selected.png create mode 100644 resources/skins/default/media/list-bg.png create mode 100644 resources/skins/default/media/transmission-main.png create mode 100644 resources/skins/default/media/transmission-main.xcf create mode 100644 resources/skins/default/skin.xml create mode 100644 resources/skins/media/.directory create mode 100644 resources/skins/media/transmission-512.png diff --git a/default.py b/default.py new file mode 100644 index 0000000..6ea766d --- /dev/null +++ b/default.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- + +import os +import xbmc +import xbmcgui + +__scriptname__ = "Transmission" +__author__ = "Correl" +__url__ = "" +__svn_url__ = "" +__credits__ = "" +__version__ = "0.5a" +__XBMC_Revision__ = "22240" + +BASE_RESOURCE_PATH = xbmc.translatePath( os.path.join( os.getcwd(), 'resources', 'lib' ) ) +sys.path.append (BASE_RESOURCE_PATH) + +__language__ = xbmc.Language(os.getcwd()).getLocalizedString + +KEY_BUTTON_BACK = 275 +KEY_KEYBOARD_ESC = 61467 + +if __name__ == '__main__': + from gui import TransmissionGUI + w = TransmissionGUI("script-Transmission-main.xml",os.getcwd() ,"default") + w.doModal() + del w diff --git a/default.tbn b/default.tbn new file mode 100644 index 0000000000000000000000000000000000000000..96c17bde4b5aa6e1a053e35d734663c91881b229 GIT binary patch literal 43855 zcmd3Ng;$hc)b5!XhE7Q(6+ybBL}CC55h>{$1Vlhex(5NJ1*H@z0i{Dpsi6@hr9l`Z z1tp|&?(6Sc-@5ltxNCaWyyxt*&pvxU``LS^9?<0z{~j0CN$wih;E5QH5#^g4KiB<=)D{Zz3Pn5Vj-lTpOj*Ra)edOA0ME(orM zQ!5ew|NS&V(0P?(34J_;-?g`jR&VLlU4JLKLO@4}Ab#%lWlDc2wW_W0*{+dBL(6&d zVbhl194uT1P>YE*;?K7fkT=e(5&M+LS?TxfX!31FAfNJAtmS0xu(`J5b{I7&PB0`FY^T-*oPd%KHYak_`=j|tS)RM zGeTB#U&@;<=uj)cP(9e)P^z=7atYEF7& z9ZQ3(+^Z`Nc8x|&TR~e5JvkiVa7+SB`~pAI7poUS%F#DmvEtg-Iqfu%rC_zBL;XsY z@&zVgb32DBh{rDJL^>{HrcvPae#qN)6fqK9MW|FZ?ks|Vr`M;u!OLJALcxPy?ODRo zjx@pb_?IAw-Z)S$c-H9j$lzc_aeuVW7@`xNtbHoY9-QnL@;^u zW8dwE;&*&lhzdC{dX9C3lOQKvr+6G4TN&Ugc_`!2{bV4>%g8}aPQ*6($sF8U4q%gE-ba59uhi&$OCQCJLt4R98Z9gnP1Wg4e` zzR=vQrW+Y?%q1Woz!81z*mutFHV>G-MC3PWb)%ncIQt;-MK|UautIDn!87%-3h<+| zhK&&I=k7&6smZDEY-xW(jrefMSL*J;e4hEO%Bf{Z$B(>hF$)aL(ZRm?{4xDXaJM@( z0W44fvq-Mm6F*EiW=cQih&0{!(4E9jAGptNrD9BGmzkJMZ##$I^7UXP_aHoKgkLBi z&LYSHQ|93Qpa-@~!(oQBbj55LVvAvo#2A}`-;_yfqZB`FZvGM<$dp4&cpVD()9V$A zKjUC(bovF)OjqR2P%Jf7sn=^B_>%RHhM0Tgc$o9RXBPn-k*!1iY#dttGA1)5e z6@bSaXVlwNl-u@Kj+*Fkg98WyN?IiNCH8Xc@Yfb>JIDZ64MxNdf@`XWxSzK)}x$!c!E=UMJ5)t{Zp^9e(&Be`K*UqDb=xhn~c%gB& z#P-TIuD$-+rrXZB!6M!BGA>tN$dZv=M2?dYJbHQwAW`!qbN;cdGxXaB#09d1fu=C_ z?^t^_#5S-4R=-ZcW2}bQaR;`CKOe9*Cu(1Sw_6cq|qFt=l;%-xS`(oq$oV3y( z>3At^k7k(3(t{re+_hv4LV*Hz!vH>krGUp~$VBXC)k-Fz_qD7MHTyz}QlaZP1t|7uqE$<0CZ;!l+| zk>7i(v!$WJvXp0|oLJ%Qbsa!1(L$`LiY-U@Dy#7qe7(yO{Og|k+Q99^+rcc4e`2?^FZ&{l;%(RqGICq9~-7Y$)n7#>8w)t^A|6tgnD0Rhy zcMQ9jsjGyJ!10%O+m5?<@#^FE#2bUMVVy1b0D-d~^H&8JX3pwNdOdzR1Ig+p#}4`lwZ^tx<=;dw^JF}d^izz=&jm8Ps$ zZX#l}mtC=xbF^rm{_~8h$}@7vrBV|VZWLXqp@UhXMN0^|A9^%cG9jtrYO>7UGVDh- zl}@B^^vwHm{*{`GOrQJ9P!f3DmxfPoX`P;ECj6{TvX*AHmg9w+wZY15!7^8qvjG$L zVu%z54@Zw2H1)c>{Z20LpePTKYt;O3Q6bJ&k-d}s!B3Qkaz3^EB2JXJy<#hDrLBT+ z!mD$2d5S>6k%Ea7gQz!RE}x}T)NyHad`wsU<&UK1yf-snak1|Tw0ALC_{M#PWVj_I zuAH4{?udBXE?yRi#qLUPlOh7IpvDiHB5vBd?V8O;|6cGvdL4Bw57=H&onKgQ#=F@X zwH*fWENIA=804H}pJsj2a;j^7Vz*`Li$asfegJEX?V{tp4j{j)n3RKwy?cs?4Lj_L z_dfgnQ9dFrX54~B`wH%*0(sz#Fa$3kd}~!uJAbZuy9?jpWEsXhxBdJ}u|jl$6OWr^ zmAsmwe*d7Cd0qUs_b(h1o~}@^sHIHc{1{e8C)ck9eehx4)hk<|m;^cm3Af$h!v3qb zcfQ%nht&@T4IJ1|IpGfF;ej&^7_N9RXm##vZsxdDYm>?D9ogBl^ZA!=W?Wz7N^~)= zE4t?^aA+q#G1&5t|As(+!N`VqY-A=!& z>Piod?D_2$8|HTRFNTBUN3eJSXcAGxSpls1`}#B6&(epuFeU{r(nV8Fs+t2jSwBtOle`uhaj#MTTSTA z@&@Six{#sV$wf22PZ1?%oDLwKJdOuF8S-(x#a40l_&x2? z52}C)aYU^43ZA`n%Zh#Ch4Y-p`nZ|?g>K%;rk_6<8S(M)K0Ng z=g3)OzZss06p&&<(N}yWFg7EL-EvgIA^XJ()edL(ncg4tyIyPbBpF`ri)3IxKi;Dv zKc7>xgQH*?oec-cVu*SqN0epd6ucm4nSb)^hXRhm8&$x83E1OlwCToWNW<_S(%%|# z#BqY{jPfACU_5OWb?VszY#%$qC75bkyYUhoI6uz@KI%SodcZQMo0a(Qv40LNbGsE^ z&fogMoRbb(kz}VCn^;!q?G0i15gLC$Sn8B1?$qj@G*$UN_)i%KvKi z6NbVWSGDzJVIqMBlSePvyNk85x`W6Gx-+3%9-_>E_`5qP>&(j@A!=iGT_# z8b#9sS7*HiS93gTr%s-~a7G7b(k@iY^1r9w#`%G~Ig0e}PkF$}X>`bLdcpYu`?dX( ziJ1AD!O#vA8|BY{Zs}e+5LTh5+qQ_ie?KZFeN_I`1R8`t#2=`7oBM4YN}YVYLBlFf zzEv}Gr@P_%cgaCAc0p3iLR&^!!XLa*v53_zX znhtQv<{(2KJue5j8gO`8=eQ>Soww0-mpM90Qj6QzfjrhEPJD4PTO{$0AIM z(XC<7U;xHK-|;F(b#BCjVU7mk<-9MsBjM;fqTt#>k);zw%E9G#8+;1mk@AD&##HLZ zTgh3egh%A$#PL;6ZZ<*CIX9L;9wd(Aa>d>|wxYNFQR$n3*Rw)f-%MPGV=EdskyxI= z^ARE}6GEPk)9F;*#{8I^JQ9cy#-m+sn(q4L049rTkPc=GC^i@{`lM6Nuic!9+&*uf#9`c|PSe7>)rmruO$TQ$j@C_W+I0}|@!DQbc0Gy?r)`%RcQVU10vJ=#qc&_TEBE(Yy_pa{taD*s&p`kh|= z?|>LK%WKQAwWx+1`<9WL|_G=!#QlwtAs3hL#R%KrOr(M!vL~EVQ(kG9WYQr z#fD*GB9M+{1AJgc5Xd9K6bq^gd`M~m4|F4NBSWhrF$I*E%RPEnzJ zN(N%sFs)dJZw8kRgY|_xu+T44O)H595ACSNbCe4P`rU`t_?Z&s-#uaCKw{B2c6ouh z=@Nz*77sej+sCO`*+;_ESIonBMO#`W$54R{BO@AU{gO-*BB4H*(9A6jLVA5EU`--~T zj1!)tknJv3gbf|OBiggUh7{m+RjW-q+miXyn3$E{Dytv((xnkZw#G&~;GB^)oOu^LZMTi5*kwpA82q0|pxb3^+f(VZa`cL_c%CJkj1q3iL@U$(N z?(*!|xrjd)ikN>AzQ24ob?-0Bp`TR3{im*6Ob9dU6BvsGiV ztY2;!k=oyu_nij@Ip6P`BF4q@%~BtmMDTn&?sl4eIHn7|_HE`-vdroS2S%`#J>u;f zEV@t(y#w14$65hthu!81lT-k{jouY+#8ig4~selmrWgAN3B1z?1OsePLeXOx&+ zLyyey$X>h0-Jy%8I`Ltq$`0jHLg*oC1RIkuiV>xdk$QLStXz%^3dint#kVa3$|Iw$ zLAi!)!^&ME-$hQWO1vZztFyg`oeyFwsr*zfVR*72f7m$u#bxhyg9&~JxrrA=Cv$4U zMD!b(eK%JzM){#uFp-(fZ(l5y%dZjw6fg3-FN&W+vBE2~)>3}mjF6oBdKg~`6Tu|2 z4g03Zi7tPR)3<|=+bS@2Q+V)CS;wnzk1=zn3acgxB&lC(PZ+Ti8hzygaCSm<-mr;jI=%9~sD=qn}6~=zI zOx4F+x0uj(Fd%IMl9aUI#N%K~o;a{bcVT_3NgVZMr|1v3Y4-Am<9!MS@ilG=H|Ir zB9oc2>NG9*hM*34NU<-#Bt~~8hspA%+CF884hx%U4Z=}ChT0*vEl7Ao0|wpniLWa6 zrqXX?IkA0@&v=1)*e>dbXFHJ->i`ZBNB81;w{7x-Z(@WO>Jt;|`a>qb{4VkKPc@7- zpXEt2#tgEN^L^uYWI#xka@G#R{)G5hJ4=SO1pY4TgzIX`lDjSNW59NE;&SouqboqR zS2PE3h_MxJy*@uz!yJxdq?m9-U^YxkjEMMZUO>rZoD>Lrf;`&YCFgn%I5Kw1{LjAI zgTR$`Y#L!RBlhqzE{-&9ftaF#3aw5CyL*$7X;gvETp#;UV%q_PY(H+IBY|ePyX%5R zK-uikzBYW*4o6RV#Acw)6^Lv?DD%@3ZXb%7c&gWv;)Ln9S0Re$5M-@p%0mQ?Xq<28 zproZV6~Sw49}6y-(6UhLyxPzpY3)zeKg*FgrTKzYlFpK#t~o^Nu{6rn=4vxOSj&JlhZkY zGA3L!ye#`-o(o|vhJA;SB|;A%g$59*gE!GH;h5OiT8=wSYYBDRLoYB%M7A(2a+a8B zRbA5LlM9-R$W$wr zV4i&#mHSj~%crSmvPzT~b&(jcQ_YTO{(3t$!4~bt^p6au0$1}s7Te|!VacJSgo*Pv zVGl}CX${8lk1dD50rc{Ps1^|4LfM*tuzDmqN#ijA@zp)>ADPYulvLXhB5518uZKj# z|D%|7VCtWM2*wNKRg>|+h;Q*gPzs{mhY%>@U%!-0D&UfFc#1i{y906mvB{75z?3LC zoFn`?IW!A2oj>$^UZcr2DhRk_rT&wl3V+Jl9*hl72w!0MPojT9r^eWF3KPmEt#%25 zf5i3G($ZhJ^G7w%P;dR#Jrf20RwDy-<$msIS%SEu9s)tY zf7J*`f$HN z3Ez|Ye(b^$s=)vWQ;=kx2{1J|4ORq*ZsmurImmrcT3l#V@jr3!nGtZj4sCUTVAwN zQE0Yl>DAZnx2Q=zS2nx9d{+O0b68tR8x~K9aXSdDg?K&J>~HK&YUj21vmN}|eM)L1 zaA-T;UCp?WdGvE5``c~u(Zlv^Gnwffj&lod20pMOnx2XiA-J@>c)f5h&4I?o^R zvcBkG2fvpkFEMx(;==sc{MT}JG>lKSTF#P%re$|D3 ztBYR7mSFt3D<0d?u~&XEB7CkFr|eN7LQz4~c-~su0*}8?11;c6$jCQ6${8|-?nK?6 z?{trr$N2lQTDC$@o73ABsjx#&FV6f{?`a1vG>RP=u{e!fT=7k#g%!e8lNkBZ=Chjc z&GQ&t1@DEn2o*{aIiTFGOeH6Nv3#R>k2il5ue7MG+7Cl-2yk#liygKOTcw@by9RI) zg~8E0zPQi;Eu;3o_Br1UpNgwHA<+cFzuXZg*K!ARAFtj#RPdem6XAmZSi+l(jG)5j zySISw&&SkCkwc8=Z!Ps(t+gQ!y}c#d7a#&pdNW|Vc?*+^j|>gIQ*~4;?P6?kYL0*X zgAW|G4~HD!!d&GBhS%h0)3scd@ei5KFM|jzg}!}rh-D>E1oMXrbwaX(VXJ;_7K~+! zO1B1T%D=f=tnomUDy?3jej6Vq83WM%{#T9zL#2$VhE+ME#ozPXp;IXsa}#Nh?DsaxmIx1)x#7^NIcWu@p* zC{;dPpu*!wKoxCfgOG60ppfhXUrC;ULjAW=lQ3G)#*Ufjv}(Ly=0q@poGa%p!_J%2<;13FksU0rTRJv6hv z-+47PHL>n8ZyLV2^PImpl=s}aYdN}!jpt&0y4JIIn!Vlrr_rZT2RoeGo$%EbcPbCf z@ac_!>_nKJ_(@naO<53G1e}sxh7Rx71)VVRQ6_?5pyo!UW*zx4E7yr>D}M}CQ$cdO8;h;(7yS!_R>KyooT>y#SKuzqw`E0$_pi>M7ci@K3n;O3nJ z)|esvx;__UMAs+(^ka)>yZuZl2Ml^7_CHGOTfxaRvgC3D%DV(WCJjZU0SI78(LN&2 zbw^v^X!Tf6?dKZ2zL_sP+nK3V7Y^p_JxrFmo)#DuLF{hEO9eR2jEY_6YzLC^Z4kkw za5KOfmw9mrN+h`+6oMPtnRmEfL*)l1c6K#Bb$0pT$WIqxS4DH_sp!!zqJ z4s6ux8zK@CW0{c;R=i%sYvRo)MUW_~p#mG{v2@vFjfJBfS~oeyH=cyYm9i|I_e4ex zLejjHUfEP+wca={M6g7d3%xiq4o+>&diStPUN48(z1Vd~Fkt7dwb#YR=T+(k0k=c~DJ zr)*m9WGUx^g=8Jg&lThOkXYEj)VkFaOYqvZb)Ft?Y~1ofJ^3E9>9qSjkJGH!p3jMW z%L#oeHTd3LSr!HNz*Ha93L%#2+r{VFrueYwTLJ`bu~$p}w->+j#cSuxG`{LhY# zr2ig^F6|z7yg#ELuNwcIJ2D_U8Wv<@=O~+%@*E7oONuDrlL_CunY_GKGcKbEL_1KvPSDryNFfcIZzR-r8qoxB*dvDf!BB{Js zGzT?po|JejT9G*w7&s9#bKRmS4Vl+t3{YB~u1JAb-IBVxtbts9`bNrF8|l%6eYxtt z9mL+ez9xR?kF1BxQa4PVdbC;+B0gkg#gEj3YWvGN}GMh0E z9i#$Y|2GZ+vjy_YirlC{$W?W8r}J@A>w9_ zj^L|)lnYFKFpfNhqd=bzy6>;&PqEBOF22<(q>B}u6mWrq47>19J``iexV2A6r0e{xqA^+@fgql9_AKeF>-rE|Hh zOvc<8?pM!(vY{DySK8sXfr0oPM;+kFirjS`v7uspTgYz{qhX`UY;MsKtykaC%9c3R zBKjtzoO>L#RL3XWA22lOV>#4 z)aFpKMe<-G>j{Pnr)>PT3k?dcme4 zK1*qC?}Jo6c=xL0qMOXGcyMlV64x7YN3elr3?_nL61YKyxZbXkuNNx1?`h0D@`jvm zjI>SUj*t}LAXMKj{@O^~b>;&uB6GE=P)1D5%nf&+nsdJnwMpEy;x!^H8{@wkUiIFz z6m4VEeiAgrYKe&=;TOgpHtl9?*~WSKgD+uvC){66xn6(e5S(p^z83eeaFTsP!bYdq zP?t=3O$OjD9S_~q8AdcGcH4?U~h6`vXfN~xvmYiiD}fRLW_XYg$1S(e*rnM8y8 zxRX!Tf|9+~Y;?;{k?G9LJSiFlhJ1}}B<@SwG^oj?4r6^dlkBN5zlT7+KA*Lp!yBnI z>Ta(Dt^9-m+l2l{J`#(+=sWdjpkj8#(dHA$7{_YTZuf+~<%;HJA&dMVVI)+^t~Ccz z-S>?YZI*?9d9kWokyyAed=+jTxxepKVr8L_uyrGRkC4@YE`|%bmk5+&4+CSDyG11B zpJS=~4{l3JN{KA^xrHOcSh`i927pTa4r6&?20*wn*0`Q>Em4^xFfFN`cQefyHq_%_ zAb4T)%l-bY2zg~)MWlU}9|M0Mzxc&@wf-Xpj$bm>70<`U3}g?#dDMCCJTwc~bN=zO z3ms(hqiC(&@O$bDYMqm(d&N~kIRCsn4a?_-|Mlp-2uJskiIsyzCNm` zujKVhH;dvECi)CpgQ;7>a49MH5;~TTY=NA9O#YRJ<(zSlU$J&@kNS58ZH0=gt*v2$ zaz2$CmS6P>!+YLG>Bv|J)4aQDw)a4^F4-s<&Y?SZGG4o4J@lz6Yo7SzFEX*Vspq(S zyr|B1=UQ~70i##??^#-;YroBMBGIy@%1YFJWQx-imt&%!KEznH%GSeQPqMh>Pl z@Rv^yT#sSy+{C*gi_{5FQui)WG`M6#eqFM-2v4YiEU@lqmMf|6Yd5d61l6lc1TdC~ zO5Rc}D#$KId`hF~L9or1)hqa<;G%hmFHy}DZnXSxXv+H~U~(EB83Pj$v7iCEbk>`HS&S~uvl%bXXgyz$mn0m)=m${c%uhw~CB+ZwxV{^w9PakG~+DA*+@H>lx> z(2EB*v>!h8hyT(fEGv5PGh8?6Xsgs-lcnT9U&n&qqp`!$%VHtL%%v;C=f_mWsUl2+ z^|#!wf`QGi8u^wXA%1?yn3#LU=EmXUS2PMKw^q4$kg<%UU;SW32JUuBP~#5KUzH~J zZzjNMkyaU&F!USk5`Xh?*+fAn>vv+F-)$H8lM@*Y=L0%v|KG%$b-R?BT3Toio7cq? z1d;F6=g2UTyb!6n_Os#&OUa>t7=(J*%m-Dh-(%YDz-r$$UzQm)HaG3ak4fF0^+=Vu z^aGM+Kc%VO{MxE%v4OSD%Y&EnAhTN&A`TJDA5y|5iO+Tezg~oVf^$T_uUXHv|8zO< z6iOPte}BMZ#3xrwDoGk{ZTs2&ZXP^a|0lhZirb@bTS*qz{e)rPbIobdVg zO_gH*>NwZMbIA07#VT4B-0Qn%*geQ16K>SJe!KLqTNG;_KR=q`Q7r+G19wG5b+H@G z8`aW2#Z9H=W)}B4`s^MsOuDnCOJiQU`t_N8YJ{qAthqGvNVfno?BT;E6EofVjOO0u zPs#VhA(SZL)AFjTr4MS{a;N@sr(XZjVKzaOXL!Tr7h0d$ol6b3be$mQ<0<>%vd#6m z5FVs&CY1uUE201`Al=Td2}{5dcLsnO!wYu_P^Be=bn73XID9+Ne5IQ29>T{8h#)JR z2>GMkI-mB%R6Y7!7u8_t&A8dP>s@?UT3()OTIgL<_bH7^ZZKl2&t{ypT@wt~Jtcma zXRFDK&Zm3#M;??~=+7t$v+9)^R@U=spWY5Sd8DbOnQbnlthn>uJF&CVj^%CUPn74f zHG!egxX3Nh)=Kq+O5_KQ4#558VETQKu zrzHTG`F3&)Ma;>p@RvVk+1Ypa(mhp;$tpj6A(S!s(*3uWbZc3NT7{;Kr^9US@1wx8 ziC~MRw^ChDG)F{G@)10@j!bfMRY=yF3KTbxMxyLzPluXrP`_WcsLg;+=8{8wV>}F( zGacPma)rvIUW+`~ee%lE(7 z;$Z^9<&h)KQF2{ONg7;%8~m0+44~T4J`^MA@qVLj`y9mwD1Uei%F(tQr?=F1@!x|D ztvpknr&}eSF(H(8`CI<6$@3A1q#yw{#_~)lT(^VdvzmaA&;#H(g@B@Y6i;*sye;yb zUS&A#4eiL6G-Ig0vras~!UCauaS0KW<`Wo

2_VIZUe8x6qux` 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 J^(r`V4 literal 0 HcmV?d00001 diff --git a/resources/language/English/strings.xml b/resources/language/English/strings.xml new file mode 100644 index 0000000..d7ebb15 --- /dev/null +++ b/resources/language/English/strings.xml @@ -0,0 +1,20 @@ + + + Transmission + + + Add + Remove + Pause + Start + Pause All + Start All + Exit + + + RPC Settings + Host + Port + User + Password + \ No newline at end of file diff --git a/resources/lib/basictypes/__init__.py b/resources/lib/basictypes/__init__.py new file mode 100644 index 0000000..117c691 --- /dev/null +++ b/resources/lib/basictypes/__init__.py @@ -0,0 +1,8 @@ +"""Common data-modeling Python types + +The idea of the basictypes package is to provide +types which provide enough metadata to allow an +application to use introspection to perform much +of the housekeeping required to create business +applications. +""" diff --git a/resources/lib/basictypes/basic_types.py b/resources/lib/basictypes/basic_types.py new file mode 100644 index 0000000..1c02855 --- /dev/null +++ b/resources/lib/basictypes/basic_types.py @@ -0,0 +1,274 @@ +"""Stand-alone type-definition objects for basic data types + +Rather than add class-methods to the built-in data types +module designs stand in datatypes which can be used to +define basicproperty property classes. +""" +from basictypes import latebind, datatypedefinition, registry, booleanfix +import types, traceback + +class Object_DT( datatypedefinition.BaseType_DT ): + """Generic "object" data-type + """ + dataType = 'object' + baseType = object + def coerce(cls, value): + """Coerce value to the appropriate data type""" + if cls.check( value): + return value + raise TypeError( """Don't know how to convert %r to a %s"""%( value, cls.dataType)) + coerce = classmethod( coerce ) + +registry.registerDT( object, Object_DT ) +class String_DT( datatypedefinition.BaseType_DT ): + """String (Unicode) data-type specifier""" + dataType = "str" + baseType = unicode + def coerce(cls, value): + """Coerce value to Unicode value + + Accepted values: + None -- u"" + str instance -- value.decode() + int,float,long,complex -- unicode(value) + """ + if cls.check( value ): + return value + if value is None: + return u"" + if isinstance( value, str ): + value = value.decode() + if isinstance( value, (int, float, long, complex)): + value = unicode( value) + ### XXX Should be raising an error here! + return value + coerce = classmethod( coerce ) +registry.registerDT( unicode, String_DT ) +class Numeric_DT( datatypedefinition.BaseType_DT ): + def coerce(cls, value): + """Coerce value to Numeric value (using baseType) + + Accepted values: + "", "0" -- 0 + numeric values + ascii strings -- base type attempts to interpret + """ + if cls.check( value): + return value + try: + if value in ("0.0","0"): + value = 0 + except TypeError, err: + # something which doesn't return integer on comparison + # such as a pg_numeric data-type + pass + try: + return cls.baseType(value) + except Exception, err: + # is this potentially a floating-point-formatted long or int? + try: + test = float(value) + newValue = cls.baseType(round(test,0)) + except Exception: + raise ValueError( """Fail: Coerce %r -> %r: %s"""%( + value, cls.dataType, err, + )) + else: + if test == newValue: + return newValue + else: + raise ValueError( """Fail: Coerce %r -> %s: Data loss would occur"""%( test, cls.dataType)) + coerce = classmethod( coerce ) + +class Int_DT( Numeric_DT ): + """Integer data-type specifier""" + dataType = "int" + baseType = int +registry.registerDT( int, Int_DT ) +class Float_DT( Numeric_DT ): + """Integer data-type specifier""" + dataType = "float" + baseType = float +registry.registerDT( float, Float_DT ) +class Long_DT( Numeric_DT ): + """Long-integer data-type specifier""" + dataType = "long" + baseType = long +registry.registerDT( long, Long_DT ) +class Boolean_DT( datatypedefinition.BaseType_DT ): + """Boolean-integer data-type specifier""" + dataType = 'bool' + falseValues = ( + 0, + None, + '0', + 'zero', + 'null', + 'none', + 'false', + 'f', + 'no', + '', + ) + baseType = booleanfix.bool + def coerce(cls, value): + """Coerce value to Boolean value + + Accepted Values: + (any value in self.falseValues) -- False + __nonzero__ False -- False + otherwise True + """ + # interpret as a Boolean... + if cls.check( value ): + return value + test = value + if type(value) in (str, unicode): + test = str(test.lower()) + if test in cls.falseValues: + return booleanfix.False + elif not test: + return booleanfix.False + else: + return booleanfix.True + coerce = classmethod( coerce ) + def check( cls, value ): + """Determine whether value conforms to definition""" + if not isinstance( value, cls.baseType ): + return 0 + if value not in (booleanfix.False,booleanfix.True): + return 0 + return 1 + check = classmethod( check ) +try: + registry.registerDT( bool, Boolean_DT ) +except NameError: + pass +registry.registerDT( booleanfix.bool, Boolean_DT ) + +class StringLocale_DT( datatypedefinition.BaseType_DT ): + """String data-type specifier""" + dataType = "str.locale" + baseType = str + def coerce(cls, value): + """Coerce the value to string (true string) value + + Acceptable Values: + Unicode -- value.encode() + None -- "" + integer, float, long, complex -- str(value) + """ + if cls.check( value ): + return value + if value is None: + return "" + if isinstance( value, unicode ): + value = value.encode() + if isinstance( value, (int, float, long, complex)): + value = str( value) + return value + coerce = classmethod( coerce ) +registry.registerDT( str, StringLocale_DT ) + +class ClassName_DT( datatypedefinition.BaseType_DT ): + """Class-name data-type specifier""" + dataType = 'str.classname' + baseType = str + def coerce( cls, value ): + """Coerce to a string + + Acceptable Values: + class name (string or Unicode, Unicode will be encoded) + class object (with __module__ and __name__) + """ + if cls.check( value ): + return value + if hasattr( value, "__module__") and hasattr(value, "__name__"): + return ".".join( (value.__module__, value.__name__)) + elif isinstance( value, str ): + return value + elif isinstance( value, unicode): + return value.encode() + else: + raise ValueError( """Unable to convert value %r to a class specifier"""%(value)) + coerce = classmethod( coerce ) + +class Class_DT( datatypedefinition.BaseType_DT ): + """Class-object data-type specifier""" + dataType = 'class' + baseType = ( + type, + types.ClassType, + types.FunctionType, + types.MethodType, + types.BuiltinFunctionType, + types.BuiltinMethodType, + types.InstanceType, + types.LambdaType, + types.UnboundMethodType, + ) + def coerce( cls, value ): + """Coerce to a class + + Acceptable Values: + Unicode/string class name + a class + """ + if cls.check( value ): + return value + if isinstance( value, unicode ): + value = str(value) + if isinstance( value, str): + try: + return latebind.bind( value ) + except ImportError, error: + raise ValueError( + """ImportError loading class %r: %s"""%( + value, error + ) + ) + + except Exception, error: + traceback.print_exc() + raise ValueError( + """%s loading class from specifier %r: %s"""%( + error.__class__.__name__, value, error, + ) + ) + else: + raise TypeError( """Unable to convert value %s (%s) to a class"""%(value, )) + coerce = classmethod( coerce ) +## def factories( cls ): +## """Determine a sequence of factory objects""" +## return [_classFactory] +## factories = classmethod( factories ) +## +##def _classFactory( ): +## """Create a new default class object""" +## return type( "", (object,), {} ) + + +class List_DT( datatypedefinition.BaseType_DT ): + """List-of-objects data-type (no coercion of items) + + Conceptually this is a listof_objects, but that would + make an inefficient type for such a common datatype. + """ + baseType = list + def coerce(cls, value ): + """Attempt to coerce the value to a list + + Strings and unicode values are converted to + [ value ]. Anything else which can be processed with + list( value ) is, everything else raises errors + when list(value) is called. + """ + if cls.check( value ): + return value + if isinstance( value, (str,unicode)): + value = [value] + value = list(value) + return value + coerce = classmethod( coerce ) +registry.registerDT( list, List_DT ) + diff --git a/resources/lib/basictypes/booleanfix.py b/resources/lib/basictypes/booleanfix.py new file mode 100644 index 0000000..15258aa --- /dev/null +++ b/resources/lib/basictypes/booleanfix.py @@ -0,0 +1,66 @@ +"""Hack to provide Python 2.3-style boolean operation in 2.2 +""" +try: + if str(True) != 'True': + # Python 2.2.3 has True, but it's just 1 and 0 refs... + raise NameError + True = True + False = False + bool = bool +except NameError: + class bool(int): + def __new__(cls, val=0): + # This constructor always returns an existing instance + if val: + return True + else: + return False + + def __repr__(self): + if self: + return "True" + else: + return "False" + + __str__ = __repr__ + + def __and__(self, other): + if isinstance(other, bool): + return bool(int(self) & int(other)) + else: + return int.__and__(self, other) + + __rand__ = __and__ + + def __or__(self, other): + if isinstance(other, bool): + return bool(int(self) | int(other)) + else: + return int.__or__(self, other) + + __ror__ = __or__ + + def __xor__(self, other): + if isinstance(other, bool): + return bool(int(self) ^ int(other)) + else: + return int.__xor__(self, other) + + __rxor__ = __xor__ + + # Bootstrap truth values through sheer willpower + False = int.__new__(bool, 0==1) + True = int.__new__(bool, 1==1) + + def install(): + """Install the enhanced bool, True and False in __builtin__""" + import __builtin__ + __builtin__.True = True + __builtin__.False = False + __builtin__.bool = bool + #install() + +if __name__ == "__main__": + assert True == 1 + assert False == 0 + diff --git a/resources/lib/basictypes/boundary.py b/resources/lib/basictypes/boundary.py new file mode 100644 index 0000000..4875fe4 --- /dev/null +++ b/resources/lib/basictypes/boundary.py @@ -0,0 +1,303 @@ +"""Boundary objects for checking data values + +You use a boundary object by passing a sequence of boundaries +in to a BasicProperty as the keyword argument "boundaries". +Boundaries must conform to the interface described by the +Boundary class, but do not necessarily need to be derived from +them. For instance, if you would like to define boundaries +as functions or methods, feel free. + +The Boundary will always be called with all three arguments +from BasicProperty, the allowance for property or client being +None is just a convenience if you want to re-use the boundary +checking code. + +NOTE: + The API for Boundary objects changed the order of the + arguments in version 0.6.2! If you were somehow using + Boundary objects before this you *must* change your code + to use the new API! +""" +NULL = [] +from basictypes import latebind + +class Boundary(object): + """Base class from which boundary conditions should be derived""" + def __call__(self, value, property=None, client=None): + """Check value against boundary conditions + + Your boundary should override this method, check the value + and raise appropriate BoundaryError's if the value is + outside of bounds + """ + +class Type(Boundary): + """Restrict the type of the value to a subclass of a boundary type (or types) + + Type provides a way of checking that a value + is an instance of a particular type, or one of a set of + types. Objects are within the boundary if: + isinstance( object, boundaryTypes ) + """ + __resolved = 0 + def __init__(self, boundaryType): + """Initialize the Type object with a boundaryType specifier + + The boundaryType specifier can be any of the following: + + string -- dotted-name specifying the full class name + (including module) for a single class/type + for example "wxPython.wx.wxFramePtr" + + This specification allows for late-binding of the + data type, which avoids mutual import problems in certain + situations. + + Note: if this specification is used, the type boundary + may raise BoundaryTypeError exceptions on the first + __call__ of the Boundary when the attempt is made + to import the class/type. + + class -- a single class/type object, + for example str or wxPython.wx.wxFramePtr + + tuple -- a tuple of class/type objects, + for example ( str, list, tuple, unicode ) or + string specifiers (as above) + """ + self.boundaryType = boundaryType + def __repr__( self ): + return """"""%(self.boundaryType,) + def __call__(self, value, property=None, client=None): + """Check value against boundary conditions""" + if not self.__resolved: + self.boundaryType = self.resolveBoundary( self.boundaryType, property, client, value ) + self.__resolved = 1 + if not isinstance(value, self.boundaryType): + raise BoundaryTypeError( + property, self, client, value, + "Value %s was not of required type %s"%( repr(value), self.boundaryType) + ) + def resolveBoundary( self, boundarySpecifier, property, client, value ): + """Resolve a particular boundary specifier into a boundary class""" + try: + return latebind.bind( boundarySpecifier ) + except (ImportError, AttributeError): + raise BoundaryTypeError( + property, self, client, value, + "Class/type %s could not be imported"""%(boundarySpecifier,) + ) + +class Range(Boundary): + """Restrict the value to between/above/below boundary minimum and/or maximum values + + The Range allows you to constrain values based on + comparisons with minimum and/or maximum values. The class + allows for specifying one or both of the boundary conditions. + + Note: minimum and maximum are included in the set of valid values + + Note: although the obvious use for Range boundaries is for + simple data types (integers, floats, strings), there is nothing + in the Boundary itself which restricts the use to simple data + types. All that is required is the ability to compare instances + using the < and > operators + """ + def __init__(self, minimum = NULL, maximum = NULL): + """Specify minimum and/or maximum, if one or both is left off, that bound is not checked + + Note: minimum and maximum are included in the set of valid values + (i.e. the range is inclusive of the end points) + """ + self.minimum = minimum + self.maximum = maximum + def __repr__( self ): + return """"""%(repr(self.minimum), repr(self.maximum)) + def __call__(self, value, property=None, client=None): + """Check value against boundary conditions""" + if self.minimum is not NULL and value < self.minimum: + raise BoundaryValueError( + property, self, client, value, + "Value was < minimum" + ) + if self.maximum is not NULL and value > self.maximum: + raise BoundaryValueError( + property, self, client, value, + "Value was > maximum" + ) + +class Function( Boundary ): + """Boundary where function( value ) must return given value""" + TRUE_VALUES = [] + FALSE_VALUES = [] + def __init__(self, function, required=TRUE_VALUES): + """Specify the function, and the required result to pass the test + + function -- the boundary function, taking a single value as parameter + required -- if Function.TRUE_VALUES, test is that the value returned + from function is "true" in the Python sense, + if Function.FALSE_VALUES, test for "falseness" in Python sense, + otherwise, require that result value be == to required to pass + """ + self.function = function + self.required = required + def __call__(self, value, property=None, client=None): + """Check value against boundary conditions""" + result = self.function( value ) + if self.required is self.TRUE_VALUES: + if not result: + raise BoundaryValueError( + property, self, client, value, + "%s(%s) gave false value, required a true value"%( + getattr(self.function, '__name__', self.function), + repr(value)[:50], + ) + ) + elif self.required is self.FALSE_VALUES: + if result: + raise BoundaryValueError( + property, self, client, value, + "%s(%s) gave true value, required a false value"%( + getattr(self.function, '__name__', self.function), + repr(value)[:50], + ) + ) + elif self.required != result: + raise BoundaryValueError( + property, self, client, value, + "%s(%s) gave value different from required value %r"%( + getattr(self.function, '__name__', self.function), + repr(value)[:50], + self.required, + ) + ) + + +class Length( Boundary ): + """Restrict the length of value to between/above/below boundary minimum and/or maximum lengths + + Conceptually, Length boundary is a very minor sub-class of + Range, where the result of passing the value to + a function (in this case len) is compared with the boundary + values, rather then the initial value. This implementation + doesn't currently take advantage of this abstraction. + """ + def __init__(self, minimum = NULL, maximum = NULL): + """Specify minimum and/or maximum, if one or both is left off, that bound is not checked""" + self.minimum = minimum + self.maximum = maximum + def __repr__( self ): + return """"""%(self.minimum, self.maximum) + def __call__(self, value, property=None, client=None): + """Check value against boundary conditions""" + length = len(value) + if self.minimum is not NULL and length < self.minimum: + raise BoundaryValueError( + property, self, client, value, + "Value was shorter than minimum, length == %s"%(len(value)) + ) + if self.maximum is not NULL and length > self.maximum: + raise BoundaryValueError( + property, self, client, value, + "Value was longer than maximum, length == %s"%(len(value)) + ) + +class NotNull( Boundary ): + """Require that value evaluate to true (non-null) + """ + def __call__(self, value, property=None, client=None): + """Check value against boundary conditions""" + if not value: + raise BoundaryValueError( + property, self, client, value, + """Value was "null" (evaluates as false)""" + ) + +class ForEach( Boundary ): + """For iterable objects, checks a given boundary for each item in object + + The ForEach boundary is used to apply another Boundary + object to each object in an iterable value. This allows you + to define checks such as this: + + constraints = [ + Type( list ), + ForEach( Type( int )), + ForEach( Range( min=0, max=100 )), + ] + + which would require that the property value be a list of + integers from 0 to 100 (inclusive). + """ + def __init__(self, base): + self.base = base + def __repr__( self ): + return """"""%( repr(self.base)) + def __call__(self, value, property=None, client=None): + """Check each item in value against base boundary condition""" + try: + index = 0 + for item in value: + self.base( item, property, client ) + index = index + 1 + except BoundaryError, error: + error.boundary = self + error.message = error.message + """ (Offending element was %s (index %s))"""%(item,index) + error.index = index + error.value = value + raise error + + + +class BoundaryError: + """Base class for all Boundary exceptions + + This class keeps references to the objects involved in the + transgression of the boundary. This allows for higher level + systems (such as a GUI application) to provide interactive + support for fixing the boundary transgression. + """ + index = None + def __init__( self, property, boundary, client, value, message="" ): + """Initialize the error, just stores the references to minimize overhead where the error isn't actually needed""" + self.property, self.boundary, self.client, self.value, self.message = property, boundary, client, value, message + def __repr__( self ): + """Get a short user-friendly representation of the error""" + return """%s val=%s type=%s prop=%s bound=%s obj=%s msg=%s"""%( + self.__class__.__name__, + repr( self.value ), + type(self.value), + self.property, + self.boundary, + self.client, + self.message, + ) + def __str__( self ): + """Get a full user-friendly string representation of the error""" + return """%s: value %s (type %s) for property %s failed boundary check %s for object %s with message %s"""%( + self.__class__.__name__, + repr( self.value ), + repr( type(self.value)), + self.property, + self.boundary, + self.client, + self.message, + ) +class BoundaryTypeError( BoundaryError, TypeError ): + """A Boundary object which checks data type found a non-conforming value/type + + This error is primarily raised by the TypeBoundary class. + + It can be caught explicitly, or as a TypeError, depending + on your application's requirements. + """ + +class BoundaryValueError( BoundaryError, ValueError ): + """A Boundary object which checks data value found a non-conforming value + + This error is raised by most Boundary classes. + + It can be caught explicitly, or as a TypeError, depending + on your application's requirements. + """ + diff --git a/resources/lib/basictypes/bytes.py b/resources/lib/basictypes/bytes.py new file mode 100644 index 0000000..12c7b7e --- /dev/null +++ b/resources/lib/basictypes/bytes.py @@ -0,0 +1,76 @@ +"""Simple class providing formatting of byte values (gigabytes, megabytes, etceteras)""" +from basictypes import basic_types + + +class Bytes( long ): + """Special data-type for byte values""" + KILOBYTES = 1024.0 + MEGABYTES = KILOBYTES*1024 + GIGABYTES = MEGABYTES*1024 + TERABYTES = GIGABYTES*1024 + + displayNames = [ + (TERABYTES, 'TB'), + (GIGABYTES, 'GB'), + (MEGABYTES, 'MB'), + (KILOBYTES, 'KB'), + (0, 'B'), + ] + + def coerce( cls, value ): + """Coerce the value to byte value""" + if isinstance( value, cls ): + return value + elif isinstance( value, (str,unicode)): + value = value.strip().upper() + for multiplier,name in cls.displayNames: + if value.endswith( name ): + value = (value[:-len(name)]).strip() + try: + return cls( long( value ) * multiplier ) + except ValueError, err: + try: + return cls( long(float(value)*multiplier)) + except ValueError, err: + raise ValueError( + """Unable to coerce to a Bytes type, invalid numeric component: %r"""%( + value, + ) + ) + # had no recognised suffix, try to convert directly with long + # numeric or string with right format will succeed, + # everything else will go boom + result = cls( value ) + return result + coerce = classmethod( coerce ) + def format( cls, value, multiplier=None, asBits=False ): + """Format as a string which is back-coercable + + multiplier -- pass in the appropriate multiplier for + the value (i.e. request 'KB' to get back as kilobytes, + default (None) indicates that the nearest should + be used + asBits -- if True, format a Byte value as bits, suitable + for display in a "bandwidth" setting, as distinct + from a simple measure of bytes. + """ + if value < 0: + value = abs(value) + neg = '-' + else: + neg = "" + if asBits: + value = value * 8 + for threshold, name in cls.displayNames: + if value >= threshold: + if threshold: + value = value/threshold + value = '%3.1f'%(value,) + if asBits: + name = name[:-1] + name[-1].lower() + return '%s%s %s'%( neg, value, name) + raise RuntimeError( """A value %r both > 0 and < 0 was encountered?"""%(value,)) + format = classmethod( format ) + +# backwards compatibility +Bytes_DT = Bytes diff --git a/resources/lib/basictypes/callable.py b/resources/lib/basictypes/callable.py new file mode 100644 index 0000000..f7399b2 --- /dev/null +++ b/resources/lib/basictypes/callable.py @@ -0,0 +1,309 @@ +"""Preliminary callable-object modelling classes""" +from basicproperty import propertied, basic, common +import inspect +from basictypes import list_types + +__NULL__ = [] + +class Argument( propertied.Propertied ): + """Representation of a single argument on a callable object""" + name = common.StringLocaleProperty( + 'name', """The argument's name, as a simple string""", + ) + default = basic.BasicProperty( + 'default', """Default-value for the argument, may be NULL/unavailable""", + ) + baseType = basic.BasicProperty( + 'baseType', """Base data-type for the argument, may be NULL/unavailable""", + ) + def __init__(self, name, default =__NULL__, baseType=__NULL__, **named): + """Initialize the Callable object + + name -- the argument name + default -- if provided, will provide the default value + for the argument + baseType -- if provided, will allow for type checking + and coercion of arguments before calling the callable + object. + """ + if default is not __NULL__: + named ["default"] = default + if baseType is not __NULL__: + named ["baseType"] = baseType + super (Argument, self).__init__( + name = name, + **named + ) + def __str__(self,): + """Create a friendly string representation""" + fragments = [repr(self.name)] + if hasattr( self, "default"): + fragments.append (repr(self.default)) + if hasattr( self, "baseType"): + fragments.append (repr(self.baseType)) + return """%s(%s)"""%( + self.__class__.__name__, + ", ".join(fragments), + ) + __repr__=__str__ + def __eq__( self, other ): + """Determine whether other is our equivalent + + returns true if other is of the same class, with + the same primary attributes + """ + if self.__class__ is not other.__class__: + return 0 + NULL = [] + for nm in ['name','default','baseType']: + if hasattr( self, nm) and not hasattr( other, nm): + return 0 + elif not hasattr( self, nm) and hasattr( other, nm): + return 0 + elif hasattr( self, nm ): + if getattr( self, nm) != getattr(other,nm): + return 0 + return 1 + + ### Data-type API + def check( cls, value ): + """Strict check to see if value is an instance of cls""" + return isinstance( value, cls) + check = classmethod(check) + def coerce( cls, value ): + """Coerce value to a cls instance + + Accepted forms: + ("name",) + ("name",default) + ("name",default,baseType) + "name" + { ** } # passed to the initialiser + """ + if cls.check( value ): + return value + if isinstance( value, (tuple, list)) and value and len(value) < 4: + items = {} + for item,name in zip(value,['name','default','baseType'][:len(value)]): + items[name] = item + return cls( **items ) + elif isinstance( value, str ): + return cls( name = value ) + elif isinstance( value, dict ): + return cls( **value ) + raise TypeError( """Don't know how to convert %r to a %s object"""%( value, cls.__name__)) + coerce = classmethod(coerce) + + +listof_Arguments = list_types.listof( + Argument, + name = "listof_Arguments", + dataType = 'list.Arguments', +) + +class Callable( propertied.Propertied ): + """Modelling of a callable Python object""" + name = common.StringProperty( + 'name', """The callable object's-name (may be different from underlying object)""", + ) + implementation = basic.BasicProperty( + "implementation", """The underlying implementation (callable Python object)""", + ) + arguments = common.ListProperty( + 'arguments', """Argument-list for the callable object""", + baseType = listof_Arguments, + ) + shortHelp = common.StringProperty( + 'shortHelp', """Short help-string suitable for tooltips/status-bars""", + ) + longHelp = common.StringProperty( + 'longHelp', """Longer help-string suitable for context-sensitive help""", + ) + coerce = common.BooleanProperty ( + "coerce","""Whether to coerce arguments if possible""", + defaultValue = 0, + ) + def __init__( + self, implementation, name=__NULL__, + arguments=__NULL__, + shortHelp = __NULL__, longHelp=__NULL__, + **named + ): + """Initialize the Callable object + + implementation -- a callable python object + name -- if provided, will override the given name + arguments -- if provided, will override calculated arguments + shortHelp -- short help-string, first line of __doc__ if not given + longHelp -- long help-string, entire __doc__ string if not given + """ + if name is __NULL__: + name = self._name( implementation ) + if arguments is __NULL__: + arguments = self._arguments (implementation) + if shortHelp is __NULL__: + shortHelp = self._shortHelp(implementation) + if longHelp is __NULL__: + longHelp = self._longHelp(implementation) + super (Callable, self).__init__( + implementation = implementation, + name = name, + arguments = arguments, + **named + ) + def __str__(self): + """Return a friendly string representation""" + return """%s( %s )"""% (self.__class__.__name__, self.implementation) + def __call__( self, *arguments, **named ): + """Do the actual calling of the callable object""" + set = {} + for argument,value in zip(arguments,self.arguments): + set[argument.name] = (argument,value) + # XXX potentially there are missing positional arguments! + if named: + nameSet = dict([(arg.name,arg) for arg in self.arguments]) + for key,value in named.items(): + if set.has_key( key ): + raise ValueError("""Redefinition of argument order for argument %s"""%(set.get(key))) + else: + # note that argument may be None + set [key] = nameSet.get(key), value + for key,(argument,value) in set.items(): + if self.coerce and argument and argument.baseType and hasattr(argument.baseType, "coerce"): + value = argument.baseType.coerce(argument) + set[key] = value + # XXX Should keep arguments in order to allow for *args set :( + return self.implementation( **set ) + def getArgument( self, name ): + """Retieve an argument by name""" + for argument in self.arguments: + if argument.name == name: + return argument + raise KeyError( """%r object doesn't have a %s argument"""%(self, name)) + + def _name( self, value ): + """Try to find a decent name for a callable object""" + name = "" + for attribute in [ '__name__','name','func_name','co_name','__file__',"friendlyName"]: + if hasattr( value, attribute): + v = getattr( value, attribute) + if isinstance( v, (str,unicode)): + name = v + if '.' in name: + return name.split('.')[-1] + return name + + def _shortHelp( self, value ): + """Try to find the short-docstring for an object""" + if hasattr( value, '__doc__') and value.__doc__: + return value.__doc__.split( '\n')[0] + else: + return "" + def _longHelp( self, value ): + """Try to find the short-docstring for an object""" + if hasattr( value, '__doc__') and value.__doc__: + return value.__doc__ + else: + return "" + + def _useCall( self, value ): + """Can we use __call__ to call this object? + + returns true if we should be able to use it + """ + return ( + # must have __call__ + hasattr( value, '__call__') and + ( + # call should be a function or method... + hasattr( value.__call__, 'im_func') or + hasattr( value.__call__, 'im_code') + ) + ) + + def _arguments( self, value ): + """Get a list of arguments for a callable object""" + if self._useCall( value ): + value = value.__call__ + if hasattr(value, 'im_func'): + # receiver is a method. Drop the first argument, usually 'self'. + func = value.im_func + arguments = inspect.getargspec( func ) + if value.im_self is not None: + # a bound instance or class method + arguments = inspect.getargspec( func ) + del arguments[0][0] + else: + # an un-bound method + pass + elif hasattr(value, 'func_code') or hasattr(value, 'im_code'): + # receiver is a function. + func = value + arguments = inspect.getargspec( func ) + else: + raise ValueError('unknown reciever type %s %s'%(receiver, type(receiver))) + names, vararg, varnamed, defaults = arguments + defaults = defaults or () + result = [ Argument( name = name ) for name in names ] + for name,default in zip( names[-len(defaults):],defaults): + for item in result: + if item.name == name: + item.default = default + return result + + + def check( cls, value ): + """Strict check to see if value is an instance of cls""" + return isinstance( value, cls) + check = classmethod(check) + + def coerce( cls, value ): + """Coerce value to a Callable-object""" + if cls.check( value ): + return value + if callable( value ): + return cls( + implementation = value, + ) + else: + raise TypeError( "Don't know how to convert %r to a %s object"%( + value, cls.__name__, + )) + coerce = classmethod(coerce) + + def __eq__( self, other ): + """Determine whether other is our equivalent + + returns true if other is of the same class, with + the same primary attributes + """ + if self.__class__ is not other.__class__: + return 0 + NULL = [] + for nm in ['name','implementation','arguments']: + if hasattr( self, nm) and not hasattr( other, nm): + return 0 + elif not hasattr( self, nm) and hasattr( other, nm): + return 0 + elif hasattr( self, nm ): + if getattr( self, nm) != getattr(other,nm): + return 0 + return 1 + +Callables = list_types.listof( + Callable, + name = "Callables", + dataType = 'list.Callables', +) + + +##class Curry( propertied.Propertied ): +## """A curried Callable with particular arguments pre-set""" +## values = common.DictionaryProperty( +## "values", """Partial value-set to be applied to callable""", +## ) +## implementation = basic.BasicProperty( +## 'implementation', """The underlying implementation of the curry""", +## baseType = callable.Callable, +## ) +## diff --git a/resources/lib/basictypes/datatypedefinition.py b/resources/lib/basictypes/datatypedefinition.py new file mode 100644 index 0000000..269e11e --- /dev/null +++ b/resources/lib/basictypes/datatypedefinition.py @@ -0,0 +1,91 @@ +"""Interface/base class for data type definitions""" + +class DataTypeDefinition( object ): + """Interface for explicit data type definitions + + The data-type definition allows for creating + stand-alone mechanisms for annotating a + particular type without actually modifying the + type itself. + + The API for the DataTypeDefinition can easily + be implemented for new classes, but it is + desirable to allow, for instance, built-in + and extension classes to be annotated without + requiring explicit support in those classes + for basictypes. + + dataType "" -- required dotted-string identifier for data-type + coerce( cls, value ) -- coerce loose value to type + check( cls, value ) -- strict check for conformance + factories( cls ) -- list of factory objects for the type + commonValues( cls ) -- list of common values for the type + format( cls, value ) -- get a coercable representation of value + """ + def coerce(cls, value): + """Coerce value to the appropriate data type + + This is a method for "fuzzy" conversion of values, + and it should be fairly forgiving. With that said, + it should not be so forgiving that will allow user + errors to be ignored. + """ + if cls.check( value ): + return value + raise TypeError ("""Value %r is not appropriate for data type %s"""%(value, self)) + coerce = classmethod(coerce) + def factories( cls ): + """Determine a sequence of factory objects + + Factory objects are used to generate new instances + conforming to this definition. For many datatypes + this is simply the class itself. For others, + it is the list of all sub-classes, or all + specifically-registered sub-classes, or something + entirely different. + + XXX The factory object's API has not yet been determined + """ + return () + factories = classmethod(factories) + def check( cls, value ): + """Determine whether value conforms to definition + + This method is used to determine whether a particular + value conforms to this definition. This is a strict + check, that is, it should return false if the value is + in any way non-conformant, so that coercian can be + attempted. + + Note: + Must be callable as definition.check( value ), which + requires classmethods for class-based definitions. + + Note: + Because this method is called from coerce and from + basicproperty objects, it should be as minimal as + possible to avoid the possibility of infinite + recursion errors. + """ + return 1 + check = classmethod(check) + +class BaseType_DT( DataTypeDefinition ): + """Abstract base DataTypeDefinition w/ "defer-to-base" implementation + """ + baseType = None + def check( cls, value ): + """Determine whether value conforms to definition""" + if not isinstance( value, cls.baseType ): + return 0 + return 1 + check = classmethod( check ) + def factories( cls ): + """Determine a sequence of factory objects""" + if callable( cls.baseType ): + return [cls.baseType] + return [] + factories = classmethod( factories ) + def __new__( cls, *args, **named ): + """Create a new instance of our base-type""" + return cls.baseType( *args, **named ) diff --git a/resources/lib/basictypes/date_types.py b/resources/lib/basictypes/date_types.py new file mode 100644 index 0000000..25bf504 --- /dev/null +++ b/resources/lib/basictypes/date_types.py @@ -0,0 +1,108 @@ +"""Stand-alone type-definition objects for date-based data types + +Three possible sources (1 implemented): + + * mx.DateTime (prefered, and implemented) + * Python 2.3 datetime + * standard time module (least interesting) + +XXX Would be nice to get a Python 2.3 datetime module +implementation, but it's pretty low on my list of +priorities +""" +try: + from datemx_types import * + from mx import DateTime as mx_DateTime + haveMX = 1 + DateTime_DT = mxDateTime_DT + DateTimeDelta_DT = mxDateTimeDelta_DT + TimeOfDay = mxTimeOfDay + + DateTime = mx_DateTime.DateTimeFrom + DateTimeDelta = mx_DateTime.DateTimeDelta + now = mx_DateTime.now + today = mx_DateTime.today +except ImportError: + haveMX = 0 + +haveImplementation = haveMX # or havePy23 or haveTimeModule + +# month enumeration... +from basictypes import enumeration +import calendar + +def allInstances( cls ): + """Return cls instances for each of this class's set""" + items = [ + (choice.value, cls( name= choice.name)) + for choice in cls.set.values() + ] + items.sort() + items = [ v[1] for v in items ] + return items + + +class WeekDay( enumeration.Enumeration ): + """Locale-specific day-of-week enumeration + + Uses both calendar and mx.DateTime's standard of + Monday = 0, Sunday = 6 + """ + dataType = 'enumeration.weekday' + set = enumeration.EnumerationSet.coerce( + zip( + calendar.day_name, + range(len(calendar.day_name)) + ) + ) + allInstances = classmethod( allInstances ) + +class WeekDayAbbr( enumeration.Enumeration ): + """Locale-specific day-of-week (abbreviated) enumeration + + Uses both calendar and mx.DateTime's standard of + Mon = 0, Sun = 6 + """ + dataType = 'enumeration.weekday.abbr' + set = enumeration.EnumerationSet.coerce( + zip( + calendar.day_abbr, + range(len(calendar.day_abbr)) + ) + ) + allInstances = classmethod( allInstances ) + +class Month( enumeration.Enumeration ): + """Locale-specific month enumeration + + Uses calendar/mx.DateTime standard of January=1, + December = 12 + """ + dataType = 'enumeration.month' + data = zip( + calendar.month_name[1:], + range(len(calendar.month_name))[1:] + ) + set = enumeration.EnumerationSet.coerce( + data + ) + allInstances = classmethod( allInstances ) + +class MonthAbbr( enumeration.Enumeration ): + """Locale-specific month (abbreviated) enumeration + + Uses calendar/mx.DateTime standard of January=1, + December = 12 + """ + dataType = 'enumeration.month.abbr' + set = enumeration.EnumerationSet.coerce( + zip( + calendar.month_abbr[1:], + range(len(calendar.month_abbr))[1:] + ) + ) + allInstances = classmethod( allInstances ) + + +del calendar +del enumeration diff --git a/resources/lib/basictypes/datedatetime_types.py b/resources/lib/basictypes/datedatetime_types.py new file mode 100644 index 0000000..b4bca80 --- /dev/null +++ b/resources/lib/basictypes/datedatetime_types.py @@ -0,0 +1,196 @@ +"""Python 2.3 datetime (+dateutils) implementation +""" +import datetime +from dateutil import parser +from dateutil import relativedelta +from basictypes import datatypedefinition, registry +import time, re, traceback + +class DateTime( datetime.datetime ): + """Datatype for the standard Python 2.3+ datetime.datetime type + """ + dataType = 'datetime.datetime' + __slots__ = () +## def __new__( cls, value=None ): +## if value is None: +## return cls.copy(cls.now()) +## elif isinstance( value, datetime.datetime + def check (cls, value): + """Determine whether value conforms to definition""" + return isinstance( value, cls ) + check = classmethod (check) + def copy( cls, source ): + """Produce a version of given datetime as this class' instance""" + return cls( + source.year, + source.month, + source.day, + source.hour, + source.minute, + source.second, + source.microsecond, + source.tzinfo + ) + copy = classmethod( copy ) + def coerce(cls, value): + """Coerce value to the appropriate data type + + Accepts: + datetime.datetime instances + datetime.date instances (assumes midnight) + datetime.time instances (assumes today for local tz (watch out!)) + string/unicode (using parser.parse) + float (interpreted as time module times) + time.struct_time instances (note that DST setting is not retained!) + + """ + if cls.check( value ): + return value + elif isinstance( value, datetime.datetime ): + return cls.copy( value ) + elif isinstance( value, datetime.date ): + return cls( value.year, value.month, value.day, tzinfo=value.tzinfo ) + elif isinstance( value, datetime.time ): + # XXX May be corner cases here where due to timezone, + # today is actually tomorrow or yesterday... + # what we'd really like to do is figure out what day it is + # in the value's timezone right now and use *that* + return cls.combine( + datetime.date.today(), + value + ) + if isinstance(value, (str,unicode)): + return cls.copy( parser.parse( value ) ) + elif isinstance(value, float): + # interpreted as a local-time second-since-the-epoch + return cls.fromtimestamp( value ) + elif isinstance( value, time.struct_time ): + # no built-in function for this!?! + return cls( + value[0], # year + value[1], # month + value[2], # day + value[3], # hour + value[4], # minute + int(value[5]), # second + int((value[5]%1.0)*1000000), # microseconds + # XXX note that we lose the daylight savings time info! + ) + elif type(value).__name__ == 'DateTime': + return cls( + value.year, + value.month, + value.day, + value.hour, + value.minute, + int(value.second), + int(round((value.second%1)*1000, 0)), + # tz is the *name* of the timezone, which we likely won't have... + ) + else: + raise TypeError ( + """Could not convert %r (type %s) to DateTime type"""% (value,type (value)) + ) + coerce = classmethod (coerce) + def asMx( self ): + """Produce an mxDateTime instance for this value""" + from mx.DateTime import DateTime + return DateTime.DateTime( + source.year, + source.month, + source.day, + source.hour, + source.minute, + source.second + (source.microsecond/1000.0), + #source.tzinfo + ) + +class _TimeParser(object): + """Class providing time-parsing functionality""" + HOUR_RE = '\d+' + MINUTE_RE = '\d+' + SECOND_RE = '(\d+([.]\d+)?)|([.]\d+)' + PM_RE = 'p[.]?[m]?[.]?' + AM_RE = 'a[.]?[m]?[.]?' + + TEMPLATE_RE = """ + (?P%(hour)s) + ( + [:,.] + (?P%(minute)s)? + ( + [:,.] + (?P%(second)s) + )? + )? + [ \t]* + ( + (?P%(am)s) + | + (?P%(pm)s) + )? + """ + + def parse( cls, text ): + """Takes user input and returns partial value dict + + Defaults to 24 hours clock + + Example inputs: + 2:13pm -> 14:13:00 + 2:13 -> 2:13:00 + 14:13:00 -> 14:13:00 + 3pm -> 15:00:00 + 4 -> 04:00:00 + AM and PM formats: + a, p, am, pm, a.m., p.m., + """ + re_fragments = { + 'hour':cls.HOUR_RE, 'minute':cls.MINUTE_RE, 'second':cls.SECOND_RE, + 'am':cls.AM_RE, 'pm':cls.PM_RE, + } + searcher = re.compile( cls.TEMPLATE_RE % re_fragments, re.IGNORECASE|re.VERBOSE ) + + result = searcher.search( text ) + if result: + if len( result.group(0)) != len(text.strip()): + raise ValueError( """Could not parse the entirety of %r as a TimeOfDay value, parsed %r"""% (text, result.group(0))) + if result.group('minute'): + minute = int( result.group('minute'), 10) + else: + minute = 0 + values = { + 'hour': int( result.group('hour'), 10), + 'minute': minute, + 'second': float( result.group('second') or 0), + } + if result.group( 'pm'): + # Forces the value to be in the PM, regardless + # of whether it already is (so 14pm works fine). + if (values['hour']%24) != 12: + values['hour'] = (values['hour'] % 12)+12 + if result.group( 'am'): + # 12am gets subtraction... + if (values['hour'] %24) == 12: + values['hour'] = 0 + return values + raise ValueError( """Unable to parse value %r into a TimeOfDay value"""%(text,)) + parse = classmethod (parse) + +class _TimeDeltaParser( _TimeParser ): + """Time parser with negative-value support""" + HOUR_RE = '[+ -]*\d+' + def parse( cls, text ): + """Takes user input and returns partial value dict + + This just adds support for negative values, which + consists of negating all values if the hour value is + negative. + """ + values = super( _TimeDeltaParser, cls).parse( text ) + if values['hour'] < 0: + values['minute'] = -values['minute'] + values['second'] = -values['second'] + return values + parse = classmethod( parse ) + diff --git a/resources/lib/basictypes/datemx_types.py b/resources/lib/basictypes/datemx_types.py new file mode 100644 index 0000000..c5ded27 --- /dev/null +++ b/resources/lib/basictypes/datemx_types.py @@ -0,0 +1,383 @@ +"""mxDateTime-based date value-types + +XXX Still need: + full RelativeDateTime definition +""" +from mx.DateTime import * +from basictypes import datatypedefinition, registry +import time, re, traceback + +__all__ = ( "mxDateTime_DT", "mxDateTimeDelta_DT", "mxTimeOfDay", 'RelativeDateTime') + +class mxDateTime_DT( datatypedefinition.BaseType_DT ): + """Data type for an mx.DateTime.DateTime value + """ + baseType = DateTimeType + dataType = 'datetime.mx' + def check (cls, value): + """Determine whether value conforms to definition""" + return isinstance( value, DateTimeType) + check = classmethod (check) + def coerce(cls, value): + """Coerce value to the appropriate data type + + Will accept: + DateTimeType + string or Unicode representations (DateTimeFrom) + float (DateTimeFromTicks) + time.struct_time (mktime) + """ + if cls.check( value ): + return value + if isinstance( value, unicode): + value = value.encode() + if isinstance(value, str): + # need to parse the data... + # XXX this isn't good, DateTimeFrom only raise an exception + # if the format is close enough to "right" that it can determine + # a format which "should" work. As a result, it will ignore + # such things as "2" or "23" and just treat them as though + # they were start-of-today + return DateTimeFrom(value) + elif isinstance(value, float): + # interpreted as a local-time second-since-the-epoch + return DateTimeFromTicks( value ) + elif isinstance( value, time.struct_time ): + return mktime( value ) + else: + raise TypeError ( + """Could not convert %r (type %s) to mxDateTime type"""% (value,type (value)) + ) + coerce = classmethod (coerce) +## def factories ( cls ): +## """Get the factories for this data type""" +## return [now,today] +## factories = classmethod (factories) + +# def __store__( cls, value ): +# """Return a stable, low-level representation of the value +# +# In this case, an ISO date-string for the UTC value of the +# DateTime +# """ +# gm = value.gmtime() +# return gm.Format('%Y-%m-%dT%H:%M:')+str(gm.second) +# __store__ = classmethod( __store__ ) +# def __unstore__( cls, value ): +# """Take our opaque date-store value and convert to an instance +# """ +# gm = DateTimeFrom( value ) +# return gm.localtime() +# __unstore__ = classmethod( __unstore__ ) +registry.registerDT( DateTimeType, mxDateTime_DT ) + +class _TimeParser(object): + """Class providing time-parsing functionality""" + HOUR_RE = '\d+' + MINUTE_RE = '\d+' + SECOND_RE = '(\d+([.]\d+)?)|([.]\d+)' + PM_RE = 'p[.]?[m]?[.]?' + AM_RE = 'a[.]?[m]?[.]?' + + TEMPLATE_RE = """ + (?P%(hour)s) + ( + [:,.] + (?P%(minute)s)? + ( + [:,.] + (?P%(second)s) + )? + )? + [ \t]* + ( + (?P%(am)s) + | + (?P%(pm)s) + )? + """ + + def parse( cls, text ): + """Takes user input and returns partial value dict + + Defaults to 24 hours clock + + Example inputs: + 2:13pm -> 14:13:00 + 2:13 -> 2:13:00 + 14:13:00 -> 14:13:00 + 3pm -> 15:00:00 + 4 -> 04:00:00 + AM and PM formats: + a, p, am, pm, a.m., p.m., + """ + re_fragments = { + 'hour':cls.HOUR_RE, 'minute':cls.MINUTE_RE, 'second':cls.SECOND_RE, + 'am':cls.AM_RE, 'pm':cls.PM_RE, + } + searcher = re.compile( cls.TEMPLATE_RE % re_fragments, re.IGNORECASE|re.VERBOSE ) + + result = searcher.search( text ) + if result: + if len( result.group(0)) != len(text.strip()): + raise ValueError( """Could not parse the entirety of %r as a TimeOfDay value, parsed %r"""% (text, result.group(0))) + if result.group('minute'): + minute = int( result.group('minute'), 10) + else: + minute = 0 + values = { + 'hour': int( result.group('hour'), 10), + 'minute': minute, + 'second': float( result.group('second') or 0), + } + if result.group( 'pm'): + # Forces the value to be in the PM, regardless + # of whether it already is (so 14pm works fine). + if (values['hour']%24) != 12: + values['hour'] = (values['hour'] % 12)+12 + if result.group( 'am'): + # 12am gets subtraction... + if (values['hour'] %24) == 12: + values['hour'] = 0 + return values + raise ValueError( """Unable to parse value %r into a TimeOfDay value"""%(text,)) + parse = classmethod (parse) + +class _TimeDeltaParser( _TimeParser ): + """Time parser with negative-value support""" + HOUR_RE = '[+ -]*\d+' + def parse( cls, text ): + """Takes user input and returns partial value dict + + This just adds support for negative values, which + consists of negating all values if the hour value is + negative. + """ + values = super( _TimeDeltaParser, cls).parse( text ) + if values['hour'] < 0: + values['minute'] = -values['minute'] + values['second'] = -values['second'] + return values + parse = classmethod( parse ) + +class mxDateTimeDelta_DT( datatypedefinition.BaseType_DT ): + """Data type for an mx.DateTime.DateTimeDelta value + """ + baseType = DateTimeDeltaType + dataType = 'datetimedelta.mx' + def check (cls, value): + """Determine whether value conforms to definition""" + return isinstance( value, DateTimeDeltaType) + check = classmethod (check) + def coerce(cls, value): + """Coerce value to the appropriate data type + + Will accept: + DateTimeType + string or Unicode representations (DateTimeFrom) + float (DateTimeFromTicks) + """ + if cls.check( value ): + return value + if isinstance(value, (str,unicode)): + # need to parse the data... + return cls.parse(value) + elif isinstance (value, (tuple,list)): + return DateTimeDelta( * value ) + elif isinstance( value, float ): + return DateTimeDelta( 0,0,0, value ) + else: + raise TypeError ( + """Could not convert %r (type %s) to mxDateTime type"""% (value,type (value)) + ) + coerce = classmethod (coerce) +## def factories ( cls ): +## """Get factories for this data type""" +## return [] +## factories = classmethod (factories) + def parse( cls, text ): + """Takes text (user input) and returns a DateTimeDelta object + + Example inputs: + 2 hours, 3 days, 45 minutes + 3d2h45m + 45m + 2hours + H:M:S (i.e. standard time format) + + XXX should eventually allow: + 2,3,45 -> directly to the constructor (d,h,m,s) + 2h 15 -> imply order based on previous item + 2.5 -> fractional day or hour (see next note) + XXX should we take bare integer as _day_, not hour, as currently??? + seems more useful as-is, but it's not really in line + with the base type + """ + if ':' in text: + try: + values = _TimeDeltaParser.parse( text ) + return DateTimeDelta( + 0, # days + values['hour'], + values['minute'], + values['second'], + ) + except (TypeError, ValueError): + traceback.print_exc() + units = [ 'd','h','m','s',] + basePattern = '(\d+([.]\d+)?)\W*%s' + fragments = [] + for unit in units: + result = re.compile( basePattern%unit, re.I ).search( text ) + if result: + fragment = result.group( 1 ) + if not result.group( 2 ): + fragments.append( int(fragment)) + else: + fragments.append( float(fragment)) + else: + fragments.append( 0 ) + if fragments == [0,0,0,0] and text.strip(): + try: + fragments[1] = int( text ) + except ValueError: + pass + + fragments = cls._normalise(fragments) + return DateTimeDelta( * fragments ) + parse = classmethod (parse) + def _normalise( cls, value ): + """Local utility function... Push overflows into higher units, push fractions into lower units""" + value = list(value) + d,h,m,s = range(4) + # push up + for a,b,divisor in [(s,m,60),(m,h,60),(h,d,24)]: + if value[a] > divisor: # more than x in y + value[b] = value[b] + int( value[a]/divisor) + value[a] = value[a] % divisor + # push down + for a,b,divisor in [(h,d,24),(m,h,60),(s,m,60),]: + if value[b] % 1.0: # fraction present + value[a] = value[a] + (value[b]%1.0 * divisor) + value[b] = int(value[b]) + return tuple(value) + _normalise = classmethod (_normalise) + def format( cls, value ): + """Format as a string which is back-coercable""" + result = [] + for (attr,fmt,always) in (('day','%i',0),('hour','%02i',1),('minute','%02i',1),('second','%0.2f',0)): + v = getattr( value, attr ) + if v or always: + result.append( fmt%v+attr[0] ) + return ", ".join( result ) + format = classmethod( format ) +registry.registerDT( DateTimeDeltaType, mxDateTimeDelta_DT ) + + +class mxTimeOfDay( _TimeParser, RelativeDateTime ): + """Representation of a time during a particular day + + This implementation is simply a sub-class of + RelativeDateTime which provides the functionality + of a data-type definition + """ + dataType = 'timeofday.mx' + ## Apparently the object type's __init__ is overriding the RelativeDateTime's + __init__ = RelativeDateTime.__init__ + + def __repr__( self ): + """Get a code-like representation of the time of day""" + return """%s( %r )"""%( self.__class__.__name__, self.__class__.format( self )) + def __str__( self ): + """Get the string representation of the time of day""" + return self.__class__.format( self ) + def __eq__( self, other ): + """Are we equal to the other value?""" + if not isinstance( other, RelativeDateTime ): + return 0 + try: + for attr in ( + 'hour','minute','second', + 'year','month','day', + 'hours','minutes','seconds', + 'years','months','days', + ): + if getattr( self, attr) != getattr( other, attr ): + return 0 + return 1 + except (ValueError,TypeError,AttributeError): + return 0 + ### Data type definition API + def check( cls, value ): + """Check that this is a RDT with only hour, minute and second""" + if isinstance( value, cls ): + for attribute in [ 'year','month','day','years','months','days','hours','minutes','seconds']: + if getattr(value, attribute): + return 0 + return 1 + return 0 + check = classmethod( check ) + def coerce( cls, value ): + """Coerce the value to our internal format (RelativeDateTime) + + Accepts: + RelativeDateTime with only hour, minute, and second values + tuple/list with up to 4 values for (default 0): + hour, minute, second, millisecond + RelativeDateTime with more data (copies to new with just time data) + DateTime (creates a RelativeDateTime for the DateTime's TimeOfDay) + float, int or long -> bare hours values + """ + def normalise( hour=0, minute=0, second=0.0 ): + day, hour,minute,second = mxDateTimeDelta_DT._normalise( + [0,hour,minute,second] + ) + hour = hour % 24 + return hour, minute, second + if cls.check( value ): + return value + elif isinstance( value, RelativeDateTime ): + # create new with just time-of-day values + hour, minute,second = normalise( value.hour, value.minute, value.second ) + elif isinstance( value, (str,unicode)): + hour, minute,second = normalise( **cls.parse( value )) + elif isinstance( value, (tuple, list)): + # new RDT from: + # up to 4 values, hour, minute, second, millisecond + hour, minute, second, millisecond = list(value) + [0,0,0,0][len(value):] + if millisecond: + second = second + (millisecond/1000.0) + hour, minute,second = normalise( hour, minute, second ) + elif isinstance( value, (float,int,long)): + # interpreted as an hour value (can include fractions) + hour, minute,second = normalise( value ) + else: + try: + DT = mxDateTime_DT.coerce( value ) + hour, minute,second = normalise( DT.hour, DT.minute, DT.second ) + except TypeError: + raise TypeError( + """Unable to extract a time-of-day from value %r"""%(value) + ) + # almost every path gets here... + return cls( + hour = hour, + minute= minute, + second = second + ) + + coerce = classmethod( coerce ) + def format( cls, value ): + """Format as a string which is back-coercable""" + result = [] + for (attr,fmt,always) in (('hour','%02i',1),('minute','%02i',1)): + v = getattr( value, attr ) + if v or always: + result.append( fmt%(v or 0) ) + if value.second: + if value.second < 10.0: + result.append( '0'+str(value.second)) + else: + result.append( str(value.second) ) + return ":".join( result ) + format = classmethod( format ) diff --git a/resources/lib/basictypes/debug.py b/resources/lib/basictypes/debug.py new file mode 100644 index 0000000..470e7c0 --- /dev/null +++ b/resources/lib/basictypes/debug.py @@ -0,0 +1,57 @@ +"""Logging facilities for basictypes + +If the logging package (from Python 2.3) is available, +we use it for our logging needs, otherwise we use a +simplistic locally-defined class for logging. +""" +import traceback, cStringIO +def getException(error): + """Get formatted exception""" + exception = str(error) + file = cStringIO.StringIO() + try: + traceback.print_exc( limit=10, file = file ) + exception = file.getvalue() + finally: + file.close() + return exception + +try: + import logging + Log = logging.getLogger + logging.basicConfig() + WARN = logging.WARN + ERROR = logging.ERROR + INFO = logging.INFO + DEBUG = logging.DEBUG + logging.Logger.getException = staticmethod( getException ) + logging.Logger.err = logging.Logger.error +except ImportError: + # does not have the logging package installed + import sys + DEBUG = 10 + INFO = 20 + WARN = 30 + ERROR = 40 + class Log( object ): + """Stand-in logging facility""" + level = WARN + def __init__( self, name ): + self.name = name + def debug(self, message, *arguments): + if self.level <= DEBUG: + sys.stderr.write( 'DEBUG:%s:%s\n'%(self.name, message%arguments)) + def warn( self, message, *arguments ): + if self.level <= WARN: + sys.stderr.write( 'WARN:%s:%s\n'%(self.name, message%arguments)) + def error( self, message, *arguments ): + if self.level <= ERROR: + sys.stderr.write( 'ERR :%s:%s\n'%(self.name, message%arguments)) + def info( self, message, *arguments ): + if self.level <= INFO: + sys.stderr.write( 'INFO:%s:%s\n'%(self.name, message%arguments)) + def setLevel( self, level ): + self.level = level + getException = staticmethod( getException ) + + diff --git a/resources/lib/basictypes/decimaldt.py b/resources/lib/basictypes/decimaldt.py new file mode 100644 index 0000000..cfd515c --- /dev/null +++ b/resources/lib/basictypes/decimaldt.py @@ -0,0 +1,21 @@ +"""Wrapper for Python 2.4 (which also works with 2.3) decimal datatype + +You can find the 2.3 decimal module described in the PEP for it +here: + http://www.python.org/peps/pep-0327.html + +This is a floating-point decimal data-type, not the "fixedpoint" module. +""" +from basictypes import basic_types +try: + import decimal +except ImportError, err: + decimal = None + +if decimal: + class DecimalDT( basic_types.Numeric_DT ): + """Numeric data-type descriptor for the new standard Decimal type""" + dataType = "decimal" + baseType = decimal.Decimal + basic_types.registry.registerDT( decimal.Decimal, DecimalDT ) + diff --git a/resources/lib/basictypes/domainname.py b/resources/lib/basictypes/domainname.py new file mode 100644 index 0000000..0722227 --- /dev/null +++ b/resources/lib/basictypes/domainname.py @@ -0,0 +1,37 @@ +"""String sub-class representing a domain name""" + +class DomainName( str ): + """Domain-name data-type""" + def __new__( cls, value ): + """Create a new DomainName from a (non-null) string value""" + if not value: + raise ValueError( """Null domain-name specified""" ) + else: + return str.__new__( cls, value ) + def check( cls, value ): + """Check whether value is a valid domain-name + + Just checks that the value is an instance of the class. + """ + if isinstance( value, cls ): + return 1 + return 0 + check = classmethod( check ) + def coerce( cls, value ): + """Coerce value to a string domain-name + + Will accept a string value, a unicode value (encoded to + utf-8), must be a non-null value. + """ + if cls.check( value ): + return value + if not isinstance( value, (str,unicode)): + raise TypeError( """Don't know how to convert %r type %r to a domain name object"""%( + value, value.__class__, + )) + if isinstance( value, unicode ): + value = value.encode( 'utf-8') + if not value: + raise ValueError( """Null domain-name %r specified"""%(value,) ) + return cls( value ) + coerce = classmethod( coerce ) diff --git a/resources/lib/basictypes/enumeration.py b/resources/lib/basictypes/enumeration.py new file mode 100644 index 0000000..7b8c317 --- /dev/null +++ b/resources/lib/basictypes/enumeration.py @@ -0,0 +1,282 @@ +"""Simple Enumeration (choice-from-set) data-type""" +from basicproperty import basic, propertied +from basictypes import basic_types + +def defaultFriendly(property, client): + """Determine the default friendly name (the name)""" + return client.name + +class EnumerationChoice( propertied.Propertied ): + """A particular choice within an enumeration set + + The enumeration choice is a particular choice + stored within the enumeration set. Its name + is used to index the choice within its set, while + its value is the actual value being enumerated. + """ + name = basic.BasicProperty( + "name","""The internal name/key used to identify the choice""", + baseType = basic_types.String_DT, + ) + value = basic.BasicProperty( + "value","""The data value associated with this choice""", + ) + friendlyName = basic.BasicProperty( + "friendlyName","""Friendly name used to describe this choice to users""", + setDefaultOnGet = 0, + defaultFunction = defaultFriendly, + baseType = basic_types.String_DT, + ) + def __repr__( self ): + """Get a code-like representation of this choice""" + if self.friendlyName != self.name: + return """%s( name=%r, value=%r, friendlyName=%r)"""%( + self.__class__.__name__, + self.name, + self.value, + self.friendlyName, + ) + else: + return """%s( name=%r, value=%r)"""%( + self.__class__.__name__, + self.name, + self.value, + ) + +class EnumerationSet( dict ): + """EnumerationSet classes (set from which values may be chosen) + + The struct mimics a C enumeration with + names mapping to integer values. + + Note: + name values must be hashable + + + XXX Needed features: + * ordered sets (e.g. month names) + * multiple input (name -> value) mappings + * preferred name-set (value -> name) mappings + * set-union, difference + """ + choiceClass = EnumerationChoice + def getName( self, value ): + """Get the name of a choice whose value matches value or None""" + for choice in self.values(): + if choice.value == value: + return choice.name + return None + def new( self, **namedarguments ): + """Add a new choice to this enumeration + + namedarguments -- passed to self.choiceClass initialiser + """ + choice = self.choiceClass( **namedarguments) + self.append( choice ) + return choice + def append( self, choice ): + """Register a choice with the set""" + self[choice.name] = choice + __iter__ = dict.itervalues + def coerce( cls, value ): + """Coerce a value to an enumeration-set value + + Accepted value formats: + None # empty dictionary/set + [ stringValue, ... ] # value == name + { 'name': value, ... } + [ (name,value), ... ] + [ choiceClass(), ... ] + [ { }, ... ] # arguments for choice-class + """ + if cls.check( value ): + return value + elif value is None: + value = () + if isinstance( value, dict ): + value = value.items() + try: + set = [ cls.coerceSingle(item) for item in value ] + return cls( + [(choice.name,choice) for choice in set] + ) + except (TypeError, KeyError,ValueError), err: + raise TypeError( """Couldn't coerce %r to a %s value: %s"""%(value,cls.__name__, err)) + coerce = classmethod( coerce ) + def check( cls, value ): + """Check whether item is compatible with this set""" + return isinstance( value, cls ) + check = classmethod( check ) + def checkSingle( cls, item ): + """Check whether item is compatible with this set""" + return isinstance( item, cls.choiceClass ) + checkSingle = classmethod( checkSingle ) + def coerceSingle( cls, item ): + """Coerce an individual value/values to an item + + This doesn't actually add the item, as the cls + doesn't store such data. + + Accepted formats: + 'key' # str or unicode only, converted to unicode for key + ('key',value) + {'name':'key','value':value,...} # passed directly to the initialiser + choiceClass instance + """ + if cls.checkSingle( item ): + return item + elif isinstance( item, (str,unicode)): + return cls.choiceClass( name = item, value=item ) + elif isinstance( item, (tuple,list)) and len(item) == 2: + if cls.checkSingle( item[1] ): + return item[1].clone( name = item[0]) + else: + return cls.choiceClass( name = item[0], value=item[1]) + elif isinstance( item, dict ): + return cls.choiceClass( **item ) + else: + raise TypeError( """%r unknown item-type"""%item) + coerceSingle = classmethod( coerceSingle ) + + +class Enumeration (propertied.Propertied): + """A choice from an enumerated set of data values + + This class also operates as the base-type for the + enumeration properties, via the data-type-definition + API. + """ + dataType = "enumeration" + ## set must be class-data, not just instance data + ## should probably be a metaclass property of EnumerationSet type + set = None + name = basic.BasicProperty( + "name", """Data-value choice within one of our sets""", + defaultValue = "", + baseType = unicode, + ) + def __init__( self, name="", *arguments, **named ): + if not isinstance( name, (str,unicode)): + name = self.__class__.set.getName( name ) + super( Enumeration, self).__init__( name=name, *arguments, **named ) + if not self.choice(): + raise ValueError( """Name %r is not part of %s"""%(self.name, self.__class__.__name__)) + def choice( self ): + """Get the choice object associated with this value or None""" + return self.set.get( self.name ) + def value( self ): + """Get the value associated with this choice""" + choice = self.choice( ) + if choice is not None: + return choice.value + raise ValueError ("""Could not get value for name %r for %s"""%(self.name,self.__class__.__name__)) + def __cmp__( self, other ): + """Compare this value to another value""" + if isinstance( other, Enumeration): + return cmp( self.value(), other.value()) + else: + return cmp( self.value(), other ) + def __repr__( self ): + """Return a code-like representation of this object""" + return """%s( name=%r)"""%( self.__class__.__name__, self.name ) + def __str__( self ): + """Return the enumeration value as a name""" + return self.name or self.value() + + ### Data-type-definition API + def check( cls, value ): + """Check whether value is of cls type, and has the same set""" + return isinstance( value, cls ) and cls.set == value.set + check = classmethod( check ) + def coerce (cls, value): + """Coerce a value into an Enumeration value + + Accepted types: + Enumeration objects + integers/longs + ([name,name,name],remainder) tuples + [name,name,name,value] lists (values are |'d together) + """ + if cls.check( value ): + return value + elif isinstance( value, (str, unicode)): + return cls.parse( value) + else: + return cls.fromValue( value ) + coerce = classmethod( coerce ) + def fromValue( cls, value ): + """Create from an integer value""" + name = cls.set.getName( value ) + if name is None: + raise ValueError( """Value %r is not part of %s"""%(value, cls.__name__)) + else: + return cls( name = name ) + fromValue = classmethod( fromValue ) + + def parse ( cls, value): + """Create from a string value + + Possible formats: + "coreName" + "23" + "friendlyName" + """ + value = value.strip () + current = cls.set.get( value) + if current is not None: + return cls( name = value ) + else: + return cls.fromValue( value ) + parse = classmethod (parse) + + def allInstances( cls ): + """Return cls instances for each of this class's set""" + items = [ + (choice.friendlyName, cls( name= choice.name)) + for choice in cls.set.values() + ] + items.sort() + items = [ v[1] for v in items ] + return items + allInstances = classmethod( allInstances ) + +def new( dataType, names, values ): + """Utility function to create a new enumeration set""" + enum = EnumerationSet.coerce( + map(None, names, values ), + ) + enum.dataType = dataType + return enum + + +class EnumerationProperty( object ): + """Mix-in for Enumeration properties to return/accept enums""" + def _getValue( self, client ): + """Retrieve the current value of the property for the client + + returns an instance of self.baseType if possible + """ + raw = super( EnumerationProperty,self)._getValue( client ) + base = self.getBaseType() + if base: + return base.fromValue( raw ) + return raw + def _setValue( self, client, value ): + """Set the current value of the property for the client + + accepts instances of self.baseType as well as raw values + """ + if isinstance(value, Enumeration ): + value = value.value() + return super( EnumerationProperty,self)._setValue( client, value ) +## +##try: +## from wxoo.resources import enumeration32_png, enumeration16_png +## from wxoo import typeregistry +##except ImportError: +## pass +##else: +## typeregistry.TYPEICONSNORMAL.Register( Enumeration, enumeration32_png.getBitmap()) +## typeregistry.TYPEICONSSMALL.Register( Enumeration, enumeration16_png.getBitmap()) +## + \ No newline at end of file diff --git a/resources/lib/basictypes/factory.py b/resources/lib/basictypes/factory.py new file mode 100644 index 0000000..77051be --- /dev/null +++ b/resources/lib/basictypes/factory.py @@ -0,0 +1,20 @@ +"""(preliminary) Model of a Factory Callable object""" +from basicproperty import propertied, basic, common +from basictypes import list_types, callable + +class Factory( callable.Callable ): + """An object intended to create instances of a type + + The factory allows you to create instances of a type + through the GUI. Most factories will allow for + entirely-default calling (i.e. Factory() creates a + new, valid instance). Others may require interactive + definition of certain parameters. + """ + +listof_Factories = list_types.listof( + Factory, + name = "listof_Factories", + dataType = 'list.Factories', +) + \ No newline at end of file diff --git a/resources/lib/basictypes/interfaces.py b/resources/lib/basictypes/interfaces.py new file mode 100644 index 0000000..d753a71 --- /dev/null +++ b/resources/lib/basictypes/interfaces.py @@ -0,0 +1,257 @@ +"""Interfaces for basictypes and basicproperty + +XXX Should we do adapters from basicproperty objects to + zope schema field objects? +""" +from zope.interface import Interface, Attribute + +### Really generic interfaces... +class IName( Interface ): + """Provide a generic name for an object""" + name = Attribute ( + "name", + """Provides an internal name for an object, may be + used for user interface, but this is of secondary + importance to internal use. Should be, as much as + possible, a valid name in most programming contexts. + """, + ) +class IFriendlyName( Interface): + """Provide a friendly name for an object""" + friendlyName = Attribute ( + "friendlyName", + """user-friendly name for use in UIs and the like, + defaults to the current value of name""", + ) +class IPyName( Interface): + """Object providing a generic name as __name__""" + __name__ = Attribute ( + "__name__", + """Provides an internal name for an object, may be + used for user interface, but this is of secondary + importance to internal use. Should be, as much as + possible, a valid name in most programming contexts. + """, + ) +class IPyDocumented(Interface): + """Object providing documentation strings""" + __doc__ = Attribute ( + "__doc__", """Documentation string for the object""", + ) + +class ICloneProperties(Interface): + """Live-object duplication mechanism with property substitution""" + def clone( **newValues ): + """Clone the object, with (optional) new property values + """ + + +### General DataTypeDefinition interfaces +class ITypeCoercion( Interface ): + """Convert/coerce a value to instance of type""" + def coerce( value ): + """Coerce value to the appropriate data type + + This is a method for "fuzzy" conversion of values, + and it should be fairly forgiving. With that said, + it should not be so forgiving that will allow user + errors to be ignored. + """ +class ITypeCheck( Interface ): + """Interface checking whether value is proper instance of type""" + def check (value): + """Determine whether value value is proper instance of type + + This method is used to determine whether a particular + value conforms to this type's restrictions. This is + a strict check, that is, it should return false if + the value is in any way non-conformant, so that + coercian can be attempted. + """ +class ITypeFactories(Interface): + """Interface providing factory instances for a given type""" + def factories( ): + """Determine a sequence of factory objects for type + + Factory objects are used to generate new instances + conforming to this definition. For many datatypes + this is simply the class itself. For others, + it is the list of all sub-classes, or all + specifically-registered sub-classes, or something + entirely different. + """ + +class IDataTypeDeclaration (Interface): + """Object provides a dataType compatible with wxoo""" + dataType = Attribute ("dataType","""The string data type specifier + + The specifier is used throughout wxoo to identify + an abstract data type for processing. + """) + +class ITypeBaseType (Interface): + """Objects with base data types for dependent objects""" + baseType = Attribute ( + "baseType","""A type or type-like object providing type-like services""", + ) + + +### Propertied object interfaces +class ITypeProperties(Interface): + """Allows retrieval of property-set for a type""" + def getProperties( ): + """Get the properties for the type""" + +### Callable-object interfaces +class ICallableArgument( IName ): + """Describes an argument to a callable object + + Note that ITypeBaseType may be provided by particular + subclasses to allow for type checking. + """ + default = Attribute( + 'default', """Default-value for the argument, may be NULL/unavailable""", + ) + def __eq__( other ): + """Determine whether other is our equivalent + + returns true if other is of the same class, with + the same primary attributes + """ + +class ICallable (IName): + """Describes and provides access to a callable object""" + name = Attribute( + 'name', """The callable-object's name""", + ) + arguments = Attribute( + 'arguments', """Argument-list for the callable object""", + ) + shortHelp = Attribute( + 'shortHelp', """Short help-string suitable for tooltips/status-bars""", + ) + longHelp = Attribute( + 'longHelp', """Longer help-string suitable for context-sensitive help""", + ) + coerce = Attribute( + "coerce","""Whether to coerce arguments if possible""", + ) + def __init__( + implementation, name=None, + arguments=None, + shortHelp = None, longHelp=None, + **named + ): + """Initialize the Callable object + + implementation -- a callable python object + name -- if provided, will override the given name + arguments -- if provided, will override calculated arguments + shortHelp -- short help-string, first line of __doc__ if not given + longHelp -- long help-string, entire __doc__ string if not given + """ + def __call__( *arguments, **named ): + """Do the actual calling of the callable object""" + def getArgument( name ): + """Retieve an argument-wrapper object by name""" + +### Boundary-related interfaces +class IBoundary (Interface): + """A boundary object for checking a value""" + def __call__( value, client = None, property = None ): + """Check value against boundary conditions + + Raises BoundaryError exceptions if the value + is not within the bounds defined by the boundary. + """ +class IBoundaryError (Interface): + """Provides rich information about a boundary error""" + def __init__( property, boundary, client, value, message="" ): + """Initialize the error with data values""" + property = Attribute ("property","""The property passed to the boundary's __call__ method""") + boundary = Attribute ("boundary","""The boundary object raising the exception""") + client = Attribute ("client","""The client passed to the boundary's __call__ method""") + value = Attribute ("value","""The value which failed the boundary check""") + message = Attribute ("message","""Human-friendly string describing the error""") + +### XXX Enumeration-related interfaces, when we get those sorted out +### Property-related interfaces... +class IPropertyDefaults(Interface): + """Property interface providing default-value semantics""" + setDefaultOnGet = Attribute ( + "setDefaultOnGet", + """if true (default), then retrieving a + default value causes the value to be explicitly set as the + current value""", + ) + default = Attribute ( + "default", + """If present, an IPropertyDefaultHolder object returning an object + to be used as the default for the property""", + ) +class IPropertyDefaultHolder(Interface): + """Callable-object producing a default value for property""" + def __call__( property, client ): + """Return the appropriate default value""" + +class IProperty(Interface): + """High-level functionality of BasicProperty-like objects""" + name = Attribute ( + "name","""name of the property, used for storage and reporting""", + ) + trueProperty = Attribute ( + "trueProperty", + """if true, this property really does describe a + property, that is, a descriptor for an attribute which is + accessed using object.x notation. + + if false, this property is used to interact with the + property system, but is not actually a property of an + object (for instance when the object is an old-style class + which cannot support properties, you can define virtual + properties for use with the class) The property system + can examine the value of trueProperty to determine whether + to use setattr(object,name,value) or call + property.__set__(object, value) to use the property.""", + ) + + def __get__( client, klass=None ): + """Retrieve the current value of the property for the client + + Performs coercion and retrieval of the property value + from the client, including potential default-value + retrieval. + """ + def __set__( client, value ): + """Set the current value of the property for the client + + Perform coercion and storage of the property value + for the client. Returns the actual value set (which + may be different than the passed value). + """ + def __delete__( client ): + """Delete the current value of the property for the client + """ +class IPropertyPickle (Interface): + """Provide pickle support to retrieve/set property values""" + def getState( client ): + """Helper for client.__getstate__, gets storable value for this property""" + def setState( client, value ): + """Helper for client.__setstate__, sets storable value""" +class IPropertyMethodStore(Interface): + """Objects using client methods for data storage/retrieval""" + setMethod = Attribute ( + "setMethod","""Method name used to set the data value on client""", + ) + getMethod = Attribute ( + "getMethod","""Method name used to get the data value from the client""", + ) + delMethod = Attribute ( + "delMethod","""Method name used to delete the data value from the client""", + ) + +class IPropertyReadOnly(Interface): + """Read-only flags for Property-like objects""" + readOnly = Attribute( + 'readOnly', """If true, disallow editing of the property through the property editors (doesn't change the underlying property's capabilities, just prevents changes through the property editors)""", + ) diff --git a/resources/lib/basictypes/latebind.py b/resources/lib/basictypes/latebind.py new file mode 100644 index 0000000..4badba4 --- /dev/null +++ b/resources/lib/basictypes/latebind.py @@ -0,0 +1,68 @@ +"""Module providing "late-binding" for type specifiers + +This is a generically useful utility module, it is +provided here just because this is where it is used +the most. +""" +import sys + +def bind( specifier ): + """Find the class(es) specified by specifier + + Allows you to pass a type specifier, one of: + + string -> fully-qualified string specifying an importable class + tuple/list -> list of specifiers + class/other -> a class or other type (untouched) + + and get back either a single class, or a tuple of + classes. + + This allows you to specify types like so: + + "wxPython.wx.wxFramePtr" + (str,unicode,"my.special.StringClass") + + in many places within the basicproperty and wxoo packages + for use as a sequence of classes without getting messed up + by mutual-import problems. + + Note: the only time you get back a single class (as opposed to + a tuple with a single class as it's only item) is when you + specify a string or class as the root specifier. + """ + if isinstance( specifier, unicode ): + specifier = str(specifier) + if isinstance( specifier, str): + return importByName( specifier ) + elif isinstance( specifier, (tuple,list)): + return tuple(flatten([ + bind(spec) + for spec in specifier + ])) + else: + return specifier + +def importByName( fullName ): + """Import a class by name""" + name = fullName.split(".") + moduleName = name[:-1] + className = name[-1] + module = __import__( ".".join(moduleName), {}, {}, moduleName) + return getattr( module, className ) + +def flatten(inlist, type=type, ltype=(list,tuple), maxint= sys.maxint): + """Flatten out a list, code developed by myself and modified by Tim Peters, then by me again :)""" + try: + # for every possible index + for ind in xrange( maxint): + # while that index currently holds a list + while isinstance( inlist[ind], ltype): + # expand that list into the index (and subsequent indicies) + inlist[ind:ind+1] = list(inlist[ind]) + #ind = ind+1 + except IndexError: + pass + return inlist + + diff --git a/resources/lib/basictypes/license.txt b/resources/lib/basictypes/license.txt new file mode 100644 index 0000000..0abae9e --- /dev/null +++ b/resources/lib/basictypes/license.txt @@ -0,0 +1,35 @@ +BasicTypes for Python + Copyright (c) 2002-2003, Michael C. Fletcher + All rights reserved. + +THIS SOFTWARE IS NOT FAULT TOLERANT AND SHOULD NOT BE USED IN ANY +SITUATION ENDANGERING HUMAN LIFE OR PROPERTY. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + The name of Michael C. Fletcher may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/resources/lib/basictypes/list_types.py b/resources/lib/basictypes/list_types.py new file mode 100644 index 0000000..53aebd6 --- /dev/null +++ b/resources/lib/basictypes/list_types.py @@ -0,0 +1,227 @@ +"""Restricted lists with base-datatype meta-type support + +This module is normally used to easily create a baseType +definition for a property like so: + + listof_Blarghs = list_types.listof( + name = "listof_Blarghs", + baseType = Blargh, + dataType = "list.Blargh", + ) + class X(propertied.Propertied): + blarghs = common.ListProperty( + 'blarghs', "A sequence of Blarghs", + baseType = listof_Blarghs, + ) + +The listof_Blarghs type (a sub-class of list) will +have coercion, data-type checking, and factories support, +and a dataType attribute which allows the wxoo system +to service instances in a number of useful ways. + +The module also includes a set of "basic" list-of-types +mirroring those in the basic_types module. +""" +from basictypes import basic_types, rlist, latebind +import types, inspect, os + +class ListOf( rlist.rlist ): + """List of a particular object-type + + This is the default base class for the classes + generated by the listof meta-class. It is a + simple restrictive list (see the superclass) + which calls its class'es coerce_single method + on every value added. + """ + def beforeAdd( self, value ): + """Called before all attempts to add an item""" + return type(self).coerce_single( value ) + +class listof( type ): + """Meta-class which creates a new typed list-class + + The listof meta-class is normally called like so: + + classname = listof( + "classname", + baseType, + dataType = "list.something", + ) + + with baseType being the basictypes specifier for the + base object type, or a simple data-class. + + Note: there is a horrible hack that tries to figure + out the correct __module__ name for the resulting class, + this is very annoyingly set to list_types by default, + rather than the module which calls listof() :( . + """ + def __new__( cls, baseType, name= "", bases=(ListOf,), **named): + if named.has_key( 'dataType'): + dataType = named.get('dataType') + elif hasattr( baseType, 'dataType'): + dataType = baseType.dataType + elif hasattr( baseType, '__name__'): + dataType = baseType.__name__ + elif isinstance( baseType, str): + # probably a string-specified data-type + dataType = (baseType.split('.')[-1]) + else: + raise ValueError( """listof couldn't determine dataType specifier for %r"""%(baseType)) + if not name: + name = "list_%s"%(dataType.replace(".",'_')) + if not named.has_key( 'dataType'): + # we're auto-calculating a data-type, add list. to the front + dataType = 'list.' + dataType + 's' + named ["dataType"] = dataType + baseObject = super( listof, cls).__new__( cls, name, bases,{} ) + baseObject.baseType = baseType + ## Following is the code to try and figure out the + ## module in which the class should reside, this is + ## fragile, as there might be some code that doesn't + ## setup the class in the root of the module. Like + ## any other class, that class will be unpickle-able. + stack = inspect.stack(1) + module = stack[1][0].f_globals['__name__'] + baseObject.__module__ = module + from basicproperty import linearise + linearise.Lineariser.registerHelper( baseObject, linearise.SequenceLin() ) + return baseObject + def __init__( self, *args, **named ): + """Dummy init to avoid conflicts in Python 2.6""" + def coerce(cls, value ): + """Attempt to coerce the value using one of our baseType""" + if isinstance( value, (str,unicode)): + value = [ value ] + if cls.check_single( value ): + value = [ value ] + assert issubclass( cls, rlist.rlist ) + assert issubclass( cls, ListOf ) + newValue = cls() + if isinstance( value, (str,unicode)): + value = [value] + newValue[:] = value + return newValue + def factories(cls): + """Retrieve the list of factories for this class""" + base = cls.baseType + if base: + if hasattr( base, 'factories'): + return base.factories() + else: + return base + return () + + def coerce_single( cls, value ): + """coerce a single value to an acceptable type""" + if cls.check_single( value ): + return value + # needs actual coercion + base = cls.baseType + if base and hasattr( base, 'coerce'): + return base.coerce( value ) + elif base: + return base(value) + return value + def check( cls, value ): + """Check the whole set (debugging checks)""" + if not isinstance( value, list ): + return 0 + base = cls.baseType + if base: + for item in value: + if base and hasattr( base, 'check'): + if not base.check( item ): + return 0 + elif base: + if not isinstance( item, base ): + return 0 + return 1 + + def check_single( cls, value ): + """Check whether a value is an instance of an acceptable type""" + base = cls.baseType + if base and hasattr( base, 'check'): + return base.check( value ) + elif base: + return isinstance( value, base ) + return 1 + + def _get_name( self ): + if named.has_key( 'dataType'): + dataType = named.get('dataType') + elif hasattr( baseType, 'dataType'): + dataType = baseType.dataType + elif hasattr( baseType, '__name__'): + dataType = baseType.__name__ + elif isinstance( baseType, str): + # probably a string-specified data-type + dataType = baseType.split('.')[-1] + else: + raise ValueError( """listof couldn't determine dataType specifier for %r"""%(baseType)) + + + + def _get_baseType( self ): + """Get the baseType as an object/class""" + base = getattr( self, '_baseType') + if isinstance( base, type): + return base + if isinstance( base, unicode): + base = str(base) + if isinstance( base, (str,tuple)): + new = latebind.bind( base ) + if isinstance( new, (tuple,list) ): + base = type(base)( new ) + else: + base = new + assert ( + isinstance( base, (type,types.ClassType)) or + ( + hasattr( base,'coerce') and + hasattr( base, 'check') + ) + ), """Specified base type %r for listof is not a class/type, and doesn't define both coerce and check methods"""%( + base, + ) + setattr( self, '_baseType', base) + return base + def _set_baseType( self, value ): + setattr( self, '_baseType', value) + def _del_baseType( self, ): + delattr( self, '_baseType') + baseType = property( + _get_baseType, _set_baseType, _del_baseType, + doc="""The base-type specifier for the listof type""" + ) + + +listof_strings = listof( + basic_types.String_DT, + "listof_strings", +) +listof_ints = listof( + basic_types.Int_DT, + "listof_ints", +) +listof_bools = listof( + basic_types.Boolean_DT, + "listof_bools", +) +listof_longs = listof( + basic_types.Long_DT, + "listof_longs", +) +listof_floats = listof( + basic_types.Float_DT, + "listof_floats", +) +listof_classnames = listof( + basic_types.ClassName_DT, + "listof_classnames", +) +listof_classes = listof( + basic_types.Class_DT, + "listof_classes", +) diff --git a/resources/lib/basictypes/pythoninterfaces.py b/resources/lib/basictypes/pythoninterfaces.py new file mode 100644 index 0000000..3ec4abf --- /dev/null +++ b/resources/lib/basictypes/pythoninterfaces.py @@ -0,0 +1,893 @@ +"""Core-python interface definitions""" +from protocols import Interface, Attribute, declareImplementation +import sys +### Python-object protocols +class IObjectPyDoc(Interface): + """Object which contains python doc string + """ + __doc__ = Attribute( + "__doc__","""Python documentation string for the object""", + ) +class IObjectPyDict(Interface): + """Object with a Python __dict__ attribute + """ + __dict__ = Attribute( + "__dict__","""Python object dictionary""", + ) +class IObjectContains(Interface): + """Object which can determine whether it contains other + """ + def __contains__( other ): + """Determine whether object contains other""" + +class IObjectEq(Interface): + """Object which can compute whether other is equal + + XXX should have adapters both ways for eq and ne + """ + def __eq__( other ): + """Determine whether object == other""" +class IObjectNe(Interface): + """Object which can compute whether other is not equal + + XXX should have adapters both ways for eq and ne + """ + def __ne__( other ): + """Determine whether object != other""" + +class IObjectPyName(Interface): + """Object with a __name__ attribute""" + __name__ = Attribute( + "__name__","""Integral name for the object""", + ) + +class IObjectComparable(Interface): + """Object which can be compared to other objects using cmp + + There's a considerable number of methods, or a + very large number of interfaces. Not sure what + should be done, so for now it's just a marker. + """ + +class IObjectGetItem( Interface): + """Object which retrieves a sub-item by key (random access)""" + def __getitem__( key ): + """Get sub-item by key or index""" +class IObjectSetItem( Interface): + """Object which sets a sub-item by key (random access)""" + def __setitem__( key, other ): + """Set sub-item by key or index""" +class IObjectDelItem( Interface): + """Object which deletes a sub-item by key (random access)""" + def __delitem__( key ): + """Delete sub-item by key or index""" + +class IObjectLength( Interface ): + """Objects which can report a total length (number of sub-elements)""" + def __len__( ): + """Return the length as an integer or long""" +class IObjectNonZero( Interface ): + """Objects which can determine their Boolean truth value directly + + XXX Should be an adapter for IObjectLength? + """ + def __nonzero__( ): + """Determine if the object is True (not False)""" + +class IObjectHash( Interface ): + """Objects which can calculate a hash/key value""" + def __hash__( ): + """Return the hash as an integer""" + +class IObjectIter(Interface): + """Object which provides explicit iteration support""" + def __iter__(): + """Return an iterator for the items of this object""" + +### Pickle (and copy) protocols +## The code for these mechanisms includes "fallback" interfaces +## such as "has a dictionary", along with the ability to exclude +## 0,1,2 or even all 3 sub-interface. An object is pickleable/copyable +## even without any of these interfaces, they are merely extra +## functionality interfaces that can be used. +class IPickleable(Interface): + """Marker interface declaring that object is pickleable""" +class IPickleGetState(Interface): + """Object which allows retrieval of current state""" + def __getstate__(): + """Retrieve an object representing the current state""" +class IPickleSetState(Interface): + """Object which allows initialization from an archive of current state""" + def __setstate__(state): + """Initialize the object from the given state""" +class IPickleGetInitArgs(Interface): + """Object which allows retrieval of "recreation" arguments""" + def __getinitargs__(): + """Retrieve initialization arguments to re-create current state""" +# XXX should have the __reduce__ interface as well, but I've +# never actually used that to document it. + +# I don't like the names for these interfaces, suggestions? -- mcf +class ICopyable(Interface): + """Marker interface declaring that object is copyable""" +class ICopyCopy(ICopyable): + """Object which defines explicit shallow __copy__ method""" + def __copy__(): + """Return a shallow copy of the object""" +class IDeepCopyable(Interface): + """Marker interface declaring that object is copyable""" +class ICopyDeepCopy(IDeepCopyable): + """Object which defines explicit __deepcopy__ method""" + def __deepcopy__(memory): + """Return a deep copy of the object + + memory -- dictionary of already-copied elements + """ +### Sequence protocols +class ISequenceGetItem( Interface): + """Sequence version of get-item, integer keys + + This is the "random access" integer key retrieval + interface, whereas the IIterator interface gives + the more limited sequential interface. + """ + def __getitem__( index ): + """Get sub-item by index""" +class ISequenceSetItem( Interface): + """Sequence version of set-item, integer keys""" + def __setitem__( index, other ): + """Set sub-item by index""" +class ISequenceDelItem( Interface): + """Sequence version of get-item, integer keys""" + def __delitem__( index ): + """Delete sub-item by index""" + +class ISequenceGetSlice( Interface ): + """Sequence which can retrieve a "slice" of sub-objects by index""" + def __getslice__( start, stop): + """Get sub-items by index-range""" +class ISequenceSetSlice( Interface ): + """Sequence which can set a "slice" of sub-objects by index""" + def __setslice__( start, stop, other): + """Set sub-items by index-range""" +class ISequenceDelSlice( Interface ): + """Sequence which can delete a "slice" of sub-objects by index""" + def __delslice__( start, stop): + """Delete sub-items by index-range""" + +class ISequenceAppend(Interface): + """Sequence object to which items may be appended""" + def append( item): + """Append the particular item to the sequence""" +class ISequenceCount(Interface): + """Sequence object which can count instances of items""" + def count(item): + """Return the number of occurrences of the item in the sequence""" +class ISequenceExtend(Interface): + """Sequence object which can be extended with another sequence""" + def extend(other): + """Extend this sequence with the other sequence""" +class ISequenceIndex(Interface): + """Sequence object which can determine index of a sub-item""" + def index(item): + """Return integer index of first occurrence of item in sequence""" +class ISequenceInsert(Interface): + """Sequence object which can insert item at a given index + + XXX Should have adapters for ISequenceAppend and ISequenceExtend + """ + def insert(index, item): + """Insert the given item at the given index + + (sequence[index] should be item afterward) + """ +class ISequenceRemove(Interface): + """Sequence object which can remove an instance of an item""" + def remove(item): + """Remove the first instance of the given item from sequence""" +class ISequenceReverse(Interface): + """Sequence whose order can be reversed in-place""" + def reverse(): + """Reverse the sequence's order in-place""" +class ISequenceSort(Interface): + """Sequence whose order can be sorted in-place""" + def sort(function = None): + """Sort the sequence in-place + + function -- if specified, the comparison function + to use for sorting, otherwise cmp + """ +class ISequencePop(Interface): + """Sequence which can "pop" last item""" + def pop(): + """Remove and return the last item of the sequence""" +class ISequencePopAny(Interface): + """Sequence which can "pop" any item""" + def pop(index =-1): + """Remove and return the given item from the sequence""" + +### The rather simple iterator protocol +class IIterator(Interface): + """Object which can operate as an iterator""" + def __iter__(): + """Return the object itself to allow for x in Iterator operation""" + def next(): + """Return the next item in the sequence""" + +### Text-type objects (strings and Unicode) +## Sub-API: joining and splitting +class ITextJoin( Interface): + """Text which can join sequences of text objects""" + def join(sequence): + """Return texts within sequence joined by this text""" +class ITextSplit( Interface): + """Text which can create sequences by splitting on a sub-string""" + def split(substring, maximum=None): + """Return text intervals between instances of substring in text""" +class ITextReplace(Interface): + """Text which can generate copies with replaced sub-strings""" + def replace(old, new, maximum = None): + """Return text with instances of old substring replaced by new substring + + maximum -- if specified, limits total number of substitutions + """ +class ITextSplitLines(Interface): + """Text which can split itself on line breaks""" + def splitlines(keepends= 0): + """Return text intervals between newline characters + + keepends -- if true, retain the newline characters + as part of the intervals (lines) + """ + +## Sub-API: Create new versions of objects with different formatting/encoding +class ITextCapitalize(Interface): + """Text which can generate word-capitalized copies""" + def capitalize(): + """Return copy of text with the first characters capitalized""" +class ITextCenterAlign(Interface): + """Text which can generate center-aligned copy of a given width""" + def center(width): + """Return copy of text centered in string of given width""" +class ITextRightAlign(Interface): + """Text which can generate right-aligned copy of a given width""" + def rjust(width): + """Return copy of text right-aligned in string of given width""" +class ITextLeftAlign(Interface): + """Text which can generate left-aligned copy of a given width""" + def ljust(width): + """Return copy of text left-aligned in string of given width""" +class ITextZeroFill(Interface): + """Text which can generate left-zero-padded copies of itself""" + def zfill(width): + """Return copy of text left-zero-padded in string of given width""" + +class ITextTranslate(Interface): + """Text which can generate translation-table modified copies of itself""" + def translate(table, toDelete=""): + """Return copy of text translated via table with to toDelete characters removed""" + +class ITextExpandTabs( Interface): + """Text which can generate tab-expanded copies""" + def expandtabs( tabsize = 8 ): + """Return copy of text with tabs expanded to tabsize spaces""" + +## Case manipulation +class ITextCaseUpper(Interface): + """Text which can generate upper case copies""" + def upper(): + """Return a copy of text in all uppercase""" +class ITextCaseLower(Interface): + """Text which can generate lower case copies""" + def lower(): + """Return a copy of text in all lowercase""" +class ITextCaseSwap(Interface): + """Text which can generate case-swapped copies""" + def swapcase(): + """Return a copy of text with case of all characters swapped""" +class ITextCaseTitle(Interface): + """Text which can generate title-cased copies""" + def title(): + """Return a copy of text in title-case""" + + +class ITextStripLeft(Interface): + """Text which can generate copies with leftmost whitespace trimmed""" + def lstrip(whitespace = None): + """Return copy of text with leftmost whitespace trimmed + + whitespace -- None, indicating regular whitespace, otherwise + set of characters which should be trimmed. + """ +class ITextStripRight(Interface): + """Text which can generate copies with rightmost whitespace trimmed""" + def rstrip(whitespace = None): + """Return copy of text with rightmost whitespace trimmed + + whitespace -- None, indicating regular whitespace, otherwise + set of characters which should be trimmed. + """ +class ITextStrip(Interface): + """Text which can generate copies with leading and trailing whitespace trimmed""" + def strip(whitespace = None): + """Return copy of text with leading and trailing whitespace trimmed + + whitespace -- None, indicating regular whitespace, otherwise + set of characters which should be trimmed. + """ + +class ITextDecode(Interface): + """Text which can be decoded using a particular codec""" + def decode(encoding = None, errors = "strict"): + """Decode text using the codec registered for encoding. + + encoding defaults to the default encoding. errors may be given + to set a different error handling scheme. Default is 'strict' + meaning that encoding errors raise a ValueError. Other possible + values are 'ignore' and 'replace'. + """ +class ITextEncode(Interface): + """Text which can be encoded using a particular codec""" + def encode(encoding = None, errors = "strict"): + """Encode text using the codec registered for encoding. + + encoding defaults to the default encoding. errors may be given + to set a different error handling scheme. Default is 'strict' + meaning that encoding errors raise a ValueError. Other possible + values are 'ignore' and 'replace'. + """ +## Sub-API: Query for contents based on sub-strings +class ITextStartsWith( Interface): + """Text which can determine whether it starts with a particular sub-string""" + def startswith( prefix, start = 0, end = sys.maxint): + """Return true if the text (in the given slice) starts with the given suffix """ +class ITextEndsWith( Interface): + """Text which can determine whether it ends with a particular sub-string""" + def endswith( suffix, start = 0, end = sys.maxint): + """Return true if the text (in the given slice) ends with the given suffix """ +class ITextCount(ISequenceCount): + """Text which can count substring occurrences in a given range""" + def count( sub, start= 0, end=sys.maxint): + """Count the number of occurrences of substring in given slice""" +class ITextFind(Interface): + """Text which can find start of contained sub-strings""" + def find( sub, start = 0, end =sys.maxint): + """Return lowest index where substring found in slice, -1 if not found""" +class ITextIndex( ISequenceIndex ): + """Text providing sequence-style index method with extra arguments""" + def index(sub, start=0, end= sys.maxint): + """Return lowest index where substring found in slice, ValueError if not found""" +class ITextFindRight(Interface): + """Text which can find start of contained sub-strings from end of text""" + def rfind( sub, start = 0, end =sys.maxint): + """Return highest index where substring found in slice, -1 if not found""" +class ITextIndexRight( ISequenceIndex ): + """Text which can find start of contained sub-strings from end of text, sequence style""" + def rindex(sub, start=0, end= sys.maxint): + """Return highest index where substring found in slice, ValueError if not found""" + +class ITextIsAlphaNumeric( Interface ): + """Text providing test whether the text is all-alphanumeric (and non-null)""" + def isalnum(): + """Return whether len(text) > 0 and text is entirely alphanumeric""" +class ITextIsAlpha( Interface ): + """Text providing test whether the text is all-alphabetic (and non-null)""" + def isalpha(): + """Return whether len(text) > 0 and text is entirely alphabetic""" +class ITextIsDigit( Interface ): + """Text providing test whether the text is all-digits""" + def isdigit(): + """Return whether text is entirely composed of digit characters""" +class ITextIsNumeric( Interface ): + """Text providing test whether the text is all-numeric characters""" + def isdigit(): + """Return whether text is entirely composed of numeric characters""" +class ITextIsLower( Interface ): + """Text providing test whether the text is all-lowercase (and non-null)""" + def islower(): + """Return whether len(text) > 0 and text is entirely lowercase""" +class ITextIsSpace( Interface ): + """Text providing test whether the text is all-whitespace (and non-null)""" + def isspace(): + """Return whether len(text) > 0 and text is entirely whitespace""" +class ITextIsTitleCased( Interface): + """Text providing test whether text is in title case format""" + def istitle(): + """Return whether text is entirely formatted in title case""" +class ITextIsUpperCased( Interface): + """Text providing test whether text is in upper case format""" + def isupper(): + """Return whether text is entirely formatted in upper case""" + +### Dictionary/mapping protocol +class IMappingClear(Interface): + """Mapping object able to clear all subelements""" + def clear(): + """Remove all subelements from this object""" +class IMappingCopy(Interface): + """Mapping object able to create a shallow copy of itself""" + def copy(): + """Return a shallow copy of the mapping""" +class IMappingUpdate(Interface): + """Mapping object able to update from another mapping object""" + def update(other): + """Add all keys from other, overriding local key-value combinations""" + +class IMappingGet(Interface): + """Mapping object providing call to retrieve an item or return default""" + def get(key, default = None): + """Return the item for the giving key, or default""" +class IMappingPopItem(Interface): + """Mapping object providing method to retrieve and remove random value""" + def popitem(): + """Return some (key,value) pair from the dictionary, KeyError if empty""" +class IMappingSetDefault(Interface): + """Mapping object providing method to retrieve or set-default key value""" + def setdefault(key, default = None): + """Retrieve current value, or set default value and return that""" + +class IMappingHasKey(Interface): + """Mapping object providing call to determine whether key is defined""" + def has_key(key): + """Determine whether the key exists in the mapping""" + +class IMappingItems(Interface): + """Mapping object able to return all items as a (key, value) list""" + def items(): + """Return all items in mapping as a (key, value) list""" +class IMappingIterItems(Interface): + """Mapping object able to return all items as a (key, value) iterable""" + def iteritems(): + """Return all items in mapping as a (key, value) iterable""" +class IMappingKeys(Interface): + """Mapping object able to return all keys as a list""" + def keys(): + """Return all keys in mapping as a list""" +class IMappingIterKeys(Interface): + """Mapping object able to return all keys as an iterable""" + def iterkeys(): + """Return all keys in mapping as an iterable""" +class IMappingValues(Interface): + """Mapping object able to return all values as a list""" + def values(): + """Return all values in mapping as a list""" +class IMappingIterValues(Interface): + """Mapping object able to return all values as an iterable""" + def itervalues(): + """Return all values in mapping as an iterable""" + + +### Stream and file protocols +class IStreamClose(Interface): + """Stream providing a close method to release resources""" + closed = Attribute ( + "closed","""Boolean displaying the current open/closed status""", + ) + def close(): + """flush internal buffers, close the stream, and release resources""" +class IStreamFlush(Interface): + """Stream providing a flush method to flush internal buffers""" + def flush(): + """Flush (write) internal buffers to the stream""" + +class IStreamIsTTY(Interface): + """Stream allowing query for whether it is a TTY-like device""" + def isatty(): + """Return Boolean representing whether is a TTY-like device""" + +class IStreamRead(Interface): + """Stream providing basic read method""" + def read(size = None): + """read available bytes from stream, limit to size if specified""" +class IStreamWrite(Interface): + """Stream providing basic write method""" + def write(string): + """Write the string to the stream""" + +class IStreamReadLine(Interface): + """Stream providing line-reading method""" + def readline(size = None): + """read a line from stream, limit bytes read to ~ size if specified""" +class IStreamReadLines(Interface): + """Stream providing multiple-line-reading method""" + def readlines(size = None): + """read lines from stream, limit bytes read to ~ size if specified""" +class IStreamXReadLines(Interface): + """Stream providing optimized multiple-line-reading method + + XXX This probably shouldn't be an interface unto itself, + or at least it should be a child of IStreamReadLines + """ + def xreadlines(size = None): + """read lines from stream, limit bytes read to ~ size if specified""" +class IStreamWriteLines(Interface): + """Stream providing multiple-line-writing method""" + def writelines(iterable): + """Iterate over the iterable writing each resulting string to stream""" + +class IStreamSeek(Interface): + """Stream providing random-access seeking to position""" + def seek(offset, whence): + """seek(offset[, whence]) -> None. Move to new stream position + + Argument offset is a byte count. Optional argument whence defaults to + 0 (offset from start of file, offset should be >= 0); other values are 1 + (move relative to current position, positive or negative), and 2 (move + relative to end of file, usually negative, although many platforms allow + seeking beyond the end of a file). + """ + +class IStreamTell(Interface): + """Stream providing feedback regarding current position""" + def tell(): + """return current file position (integer or long)""" +class IStreamTruncate(Interface): + """Stream providing feedback regarding current position + + XXX Documentation seems to suggest that this interface requires + IStreamTell, though only in cases where size is not specified + """ + def truncate(size = None): + """Truncated stream to given size, or current position if not specified""" + +class IStreamMode(Interface): + """Stream having a mode attribute""" + mode = Attribute ( + "mode", """The I/O mode for the file""", + ) +class IStreamName(Interface): + """Stream having a name attribute""" + name = Attribute ( + "name", """Filename or data-source description""", + ) + +class IStringIOGetValue(Interface): + """Provides access to current value of StringIO buffer""" + def getvalue (): + """Retrieve the current value of the string buffer""" + + + +### DBM database protocol +class IDBMDatabase( + IObjectContains, + IObjectIter, + IObjectGetItem, + IObjectSetItem, + IObjectDelItem, + IMappingIterKeys, + IMappingKeys, + IStreamClose, + IMappingHasKey, +): + """(Dumb/G)DBM Interface + + XXX Note this interface is derived from the DumbDBM + runtime class, there may be items which are not + officially considered part of interface. + """ + +class IBSDIteration(Interface): + """BSDDB iteration interface + + This is the interface provided by the dbhash module's + "database" objects (in addition to the IDBMDatabase + interface). + """ + def first(): + """return the first key in the database""" + def next(key): + """return the key in the database after given key""" + def last(): + """return the last key in the database""" + def previous(key): + """return the key in the database before given key""" + def sync(): + """synchronize in-memory database with on-disk database""" + +class IBSDIterationSetLocation(IBSDIteration): + """Adds ability to set database cursor location by key + """ + def set_location( key ): + """Set cursor to item indicated by key, return (key,value)""" + + +### Array-specific +class IArrayIOString(Interface): + """Array-object to/from string method interfaces""" + def tostring(): + """Convert to array of machine values and return as string""" + def fromstring( string ): + """Appends items from string (sequence of machine values)""" +class IArrayIOList(Interface): + """Array-object to/from list method interfaces""" + def tolist(): + """Convert to list of elements""" + def fromlist( string ): + """Appends items from list""" +class IArrayIOFile(Interface): + """Array-object to/from file method interfaces""" + def tofile(): + """Write to file as array of machine values""" + def fromfile( string ): + """Appends from file/stream as array of machine values""" +class IArrayMetadata( Interface ): + """Array-object providing item-type metadata""" + typecode = Attribute( + "typecode", """The typecode character used to create the array""", + ) + itemsize = Attribute( + "itemsize", """The length in bytes of one array item in the internal representation""", + ) + +class IArrayByteswap( Interface ): + """Mutable-array interface""" + def byteswap( ): + """Byte-swap the array data""" + +list__implements__ = [ + IObjectContains, + IObjectEq, + IObjectNe, + IObjectComparable, + IObjectLength, + #IObjectIter, # list doesn't have __iter__ + + IPickleable, + ICopyable, + IDeepCopyable, + + ISequenceGetItem, + ISequenceSetItem, + ISequenceDelItem, + ISequenceGetSlice, + ISequenceSetSlice, + ISequenceDelSlice, + ISequenceAppend, + ISequenceCount, + ISequenceExtend, + ISequenceIndex, + ISequenceInsert, + ISequenceRemove, + ISequenceReverse, + ISequenceSort, + ISequencePopAny, +] +str__implements__= [ + IObjectContains, + IObjectEq, + IObjectNe, + IObjectComparable, + IObjectLength, + IObjectHash, + #IObjectIter, # str doesn't have __iter__ :( + + IPickleable, + ICopyable, + IDeepCopyable, + + ISequenceGetItem, + ISequenceGetSlice, + ITextCount, + ITextJoin, + ITextSplit, + ITextReplace, + ITextSplitLines, + ITextCapitalize, + ITextCenterAlign, + ITextRightAlign, + ITextLeftAlign, + ITextZeroFill, + ITextTranslate, + ITextExpandTabs, + ITextCaseUpper, + ITextCaseLower, + ITextCaseSwap, + ITextCaseTitle, + ITextStripLeft, + ITextStripRight, + ITextStrip, + ITextDecode, + ITextEncode, + ITextStartsWith, + ITextEndsWith, + ITextCount, + ITextFind, + ITextIndex, + ITextFindRight, + ITextIndexRight, + ITextIsAlphaNumeric, + ITextIsAlpha, + ITextIsDigit, + ITextIsNumeric, + ITextIsLower, + ITextIsSpace, + ITextIsTitleCased, + ITextIsUpperCased, +] +unicode__implements__= [ + IObjectContains, + #IObjectEq, # doesn't implement it :( + #IObjectNe, # doesn't implement it :( + IObjectComparable, + IObjectLength, + IObjectHash, + #IObjectIter, # unicode doesn't have __iter__ :( + + IPickleable, + ICopyable, + IDeepCopyable, + + ISequenceGetItem, + ISequenceGetSlice, + ITextCount, + ITextJoin, + ITextSplit, + ITextReplace, + ITextSplitLines, + ITextCapitalize, + ITextCenterAlign, + ITextRightAlign, + ITextLeftAlign, + ITextZeroFill, + ITextTranslate, + ITextExpandTabs, + ITextCaseUpper, + ITextCaseLower, + ITextCaseSwap, + ITextCaseTitle, + ITextStripLeft, + ITextStripRight, + ITextStrip, + #ITextDecode, + ITextEncode, + ITextStartsWith, + ITextEndsWith, + ITextCount, + ITextFind, + ITextIndex, + ITextFindRight, + ITextIndexRight, + ITextIsAlphaNumeric, + ITextIsAlpha, + ITextIsDigit, + ITextIsNumeric, + ITextIsLower, + ITextIsSpace, + ITextIsTitleCased, + ITextIsUpperCased, +] +tuple__implements__= [ + IObjectContains, + IObjectEq, + IObjectNe, + IObjectComparable, + IObjectLength, + IObjectHash, + + IPickleable, + ICopyable, + IDeepCopyable, + + ISequenceGetItem, + ISequenceGetSlice, +] +dict__implements__= [ + IObjectContains, + IObjectEq, + IObjectNe, + IObjectComparable, + IObjectGetItem, + IObjectSetItem, + IObjectDelItem, + IObjectLength, + IObjectIter, + + IPickleable, + ICopyable, + IDeepCopyable, + + IMappingClear, + IMappingCopy, + IMappingUpdate, + IMappingGet, + IMappingPopItem, + IMappingSetDefault, + IMappingHasKey, + IMappingItems, + IMappingIterItems, + IMappingKeys, + IMappingIterKeys, + IMappingValues, + IMappingIterValues, +] + +array_ArrayType__implements__= [ + ### The array object in Python 2.2.2, although it works + ## as though it had the commented out interfaces doesn't + ## actually provide the interface's signature :( + ## The interface signatures even show up in the ArrayType + ## class, they just aren't showing up in the objects :( + #IObjectContains, + #IObjectEq, + #IObjectNe, + IObjectComparable, + #IObjectLength, + #IObjectIter, # list doesn't have __iter__ + + # not sure arrays really are all three of these + IPickleable, + ICopyable, + IDeepCopyable, + + #ISequenceGetItem, + #ISequenceSetItem, + #ISequenceDelItem, + #ISequenceGetSlice, + #ISequenceSetSlice, + #ISequenceDelSlice, + ISequenceAppend, + ISequenceCount, + ISequenceExtend, + ISequenceIndex, + ISequenceInsert, + ISequenceRemove, + ISequenceReverse, + ISequenceSort, + ISequencePopAny, + IArrayIOString, + IArrayIOList, + IArrayIOFile, + IArrayMetadata, + IArrayByteswap, +] + +bsddb__implements__= [ + IDBMDatabase, + IBSDIterationSetLocation, +] +dbhash__implements__= [ + IDBMDatabase, + IBSDIteration, +] +dumbdbm__implements__= [ + IDBMDatabase, +] +file__implements__ = [ + IObjectIter, + IObjectHash, + IStreamClose, + IStreamFlush, + IStreamIsTTY, + IStreamRead, + IStreamWrite, + IStreamReadLine, + IStreamReadLines, + IStreamXReadLines, + IStreamWriteLines, + IStreamSeek, + IStreamTell, + IStreamTruncate, + IStreamMode, + IStreamName, +] +StringIO_StringIO__implements__= file__implements__ + [ + # XXX does it actually support everything the file does? + IStringIOGetValue, +] +baseTypeImplements = [ + (list, list__implements__), + (tuple, tuple__implements__), + (str, str__implements__), + (unicode, unicode__implements__), + (dict, dict__implements__), +## (array.ArrayType, array_ArrayType__implements__), +] + +def register(): + for classObject, interfaceList in baseTypeImplements: + declareImplementation( + classObject, + interfaceList, + ) +register() diff --git a/resources/lib/basictypes/registry.py b/resources/lib/basictypes/registry.py new file mode 100644 index 0000000..4de5887 --- /dev/null +++ b/resources/lib/basictypes/registry.py @@ -0,0 +1,16 @@ +"""Mapping from core types/classes to stand-in DataTypeDefinitions""" +REGISTRY = { +} + +def registerDT( base, DT ): + """Register a DataTypeDefinition for a given base-class""" + REGISTRY[ base ] = DT + +def getDT( base ): + """Return the appropriate DT for the given base-class + + This looks up the base in the registry, returning + either a registered stand-alone data-type-definition + or the base itself. + """ + return REGISTRY.get( base, base ) diff --git a/resources/lib/basictypes/rlist.py b/resources/lib/basictypes/rlist.py new file mode 100644 index 0000000..e409891 --- /dev/null +++ b/resources/lib/basictypes/rlist.py @@ -0,0 +1,48 @@ +"""Restrictive-List base class""" + +class rlist( list ): + """Sub-class of list that calls a method before insertion allowed + """ + def __init__(self, value= None): + """Initialize the restricted list object""" + if value is not None: + value = self.beforeMultipleAdd([ self.beforeAdd(item) for item in value ]) + else: + value = [] + super (rlist, self).__init__(value) + def __setslice__( self, start, stop, value ): + """__setslice__ with value checking""" + value = self.beforeMultipleAdd([ self.beforeAdd(item) for item in value ]) + return super(rlist,self).__setslice__( start, stop, value ) + def extend( self, value ): + """extend with value checking""" + value = self.beforeMultipleAdd([ self.beforeAdd(item) for item in value ]) + return super(rlist,self).extend( value ) + __iadd__ = extend + def append( self, value ): + """append with value checking""" + value = self.beforeAdd( value ) + return super(rlist,self).append( value ) + def insert( self, index, value ): + """insert with value checking""" + value = self.beforeAdd( value ) + return super(rlist,self).insert( index, value ) + def __setitem__( self, index, value ): + """__setitem__ with value checking""" + value = self.beforeAdd( value ) + return super(rlist,self).__setitem__( index, value ) + def beforeAdd( self, value ): + """Called before all attempts to add an item""" + return value + def beforeMultipleAdd( self, value ): + """Called before attempts to add more than one item (beforeAdd has already be called for each item)""" + return value + +if __name__ == "__main__": + a = rlist( [1,2,3,4,5] ) + print a + print a[:].__class__ + m = rlist( [1,2,3,4,5] ) + m.append( 's' ) + + \ No newline at end of file diff --git a/resources/lib/basictypes/rstring.py b/resources/lib/basictypes/rstring.py new file mode 100644 index 0000000..9cd3c0c --- /dev/null +++ b/resources/lib/basictypes/rstring.py @@ -0,0 +1,67 @@ +"""This belongs over in basicproperty/basictypes, obviously""" +class RestrictedString( unicode ): + """Data-type definition for a string with restricted contents + + ACCEPTED_CHARACTERS -- set of (unicode) characters accepted by + the string-type + REPLACE_CHARACTER -- character with which to replace unaccepted + characters (*must* be in ACCEPTED_CHARACTERS!) + """ + ACCEPTED_CHARACTERS = u'' + REPLACE_CHARACTER = u'' + def __new__( cls, value ): + """Initialise the restricted string/unicode value""" + if isinstance( value, unicode ): + cleaned = cls.clean( value ) + return super(RestrictedString,cls).__new__( cls, cleaned ) + else: + return cls.coerce( value ) + def coerce( cls, value ): + """Coerce the value to the correct data-type""" + # first get a unicode value... + if value is None: + value = u"" + if isinstance( value, str ): + value = value.decode( ) # default encoding must be set... + if isinstance( value, (int,float,long)): + value = unicode( value ) + if not isinstance( value, unicode ): + raise TypeError( """Don't know how to convert a %r instance (%r) to a restricted unicode value"""%( + type(value), value, + )) + return cls( cls.clean( value )) + coerce = classmethod( coerce ) + def clean( cls, value ): + """Return only those characters in value in ACCEPTED_CHARACTERS""" + result = [] + for x in value: + if x in cls.ACCEPTED_CHARACTERS: + result.append( x ) + else: + result.append( cls.REPLACE_CHARACTER ) + return u"".join( result ) + clean = classmethod( clean ) + +if __name__ == "__main__": + from basicproperty import common, propertied, basic + class Test( RestrictedString ): + ACCEPTED_CHARACTERS = ( + 'tis' + + "' ." + ).decode( 'latin-1' ) + class Test2( Test ): + REPLACE_CHARACTER = ' ' + + class PTest( propertied.Propertied ): + value = basic.BasicProperty( + "value", """Testing value""", + baseType = Test2, + ) + t = Test( 'this\tand that' ) + print t + t = Test2( 'this\tand that' ) + print t + c = PTest( value = 'this\tand that' ) + print c.value + c = PTest( value = '2322.5' ) + print c.value diff --git a/resources/lib/basictypes/typeunion.py b/resources/lib/basictypes/typeunion.py new file mode 100644 index 0000000..3ecab69 --- /dev/null +++ b/resources/lib/basictypes/typeunion.py @@ -0,0 +1,87 @@ +"""Object representing functional union of two types + +(wrt. the basictypes/basicproperty type interfaces) +""" + +class TypeUnion( tuple ): + """An object providing, as much as possible, the union of two types + + The TypeUnion is intended to allow specifying + baseTypes which are actually 2 or more sub- + types. The TypeUnion is responsible for + mediating between the sub-types (for instance + making sure that items which are instances of + one type are not arbitrarily converted to + instances of another). + """ + def __new__( cls, *arguments, **named ): + """Create a new TypeUnion object + + A class-name will be calculated by cls.createName + """ + base = super( TypeUnion, cls).__new__( cls, *arguments, **named ) + base.__name__ = cls.createName( base ) + return base + def __repr__( self ): + return self.__name__ + def createName( cls, base ): + """Try to create a type-name from base (tuple of sub-types)""" + set = [] + for typ in base: + if hasattr( typ, '__name__'): + set.append( typ.__name__.split('.')[-1] ) + else: + set.append( str(typ).split('.')[-1]) + return "".join( set ) + createName = classmethod( createName ) + def check( self, value ): + """Is the value acceptable as one of our types""" + for typ in self: + if hasattr( typ, 'check'): + if typ.check( value ): + return 1 + elif isinstance( value, typ ): + return 1 + return 0 + def coerce( self, value ): + """Coerce the value to one of our types""" + if self.check( value ): + return value + best = self.bestMatch( value ) + if best is not None: + return best.coerce( value ) + else: + err = None + for typ in self: + try: + return typ.coerce( value ) + except (ValueError,TypeError), err: + pass + raise TypeError( """Couldn't convert %r value to any of %r (%s)"""%( + value, tuple(self), err + )) + def factories( self ): + """Get the default set of factory objects""" + result = [] + for item in self: + if hasattr( item, 'factories'): + result.extend( list(item.factories())) + elif callable( item ): + result.append( item ) + return result + def bestMatch( self, value ): + """Find the closest item to value's type + + Defaults to the first item + """ + # is value an instance of item or item.baseType? + for typ in self: + if isinstance(value,typ) or ( + hasattr( typ,'baseType') and + isinstance(value, typ.baseType) + ): + return typ + # XXX should have meta-data on the types to allow better + # recovery here + return None + \ No newline at end of file diff --git a/resources/lib/basictypes/vfs/__init__.py b/resources/lib/basictypes/vfs/__init__.py new file mode 100644 index 0000000..b34a0ea --- /dev/null +++ b/resources/lib/basictypes/vfs/__init__.py @@ -0,0 +1,18 @@ +"""URL manipulation and object-oriented class hierarchy""" + + +def path( value, target = None, force=0 ): + """Convert value to the target path-type + + XXX this becomes a hook-point for creating + virtual file-systems, with force true requiring + the particular target and false allowing + substitutes + """ + if target is None: + from basictypes.vfs import filepath + target = filepath.FilePath + if not isinstance( value, target ): + value = target( value ) + return value + diff --git a/resources/lib/basictypes/vfs/basepath.py b/resources/lib/basictypes/vfs/basepath.py new file mode 100644 index 0000000..ba74b29 --- /dev/null +++ b/resources/lib/basictypes/vfs/basepath.py @@ -0,0 +1,154 @@ +"""Base-class for file-path strings +""" +import os + +class BasePath (str): + """Representation of a path in a virtual file system + + Interact with the paths in an object-oriented way + (following are ideas for what to do) + * Support for standard os and os.path queries + * listdir + * isfile/dir/symlink + * create sub-directory + * join-with-string to get sub-path + * absolute-path -> Path object + * support .. and . directory resolution (and elimination) + * Mime-types + * assoc values + * comparisons + * parent, child -> boolean + * shared path -> fragments + * shared root -> boolean + * open( *, ** ) + * for directories, create/open file based on standard file() call + * for zipfile-embedded paths, use zipfile transparently to create/open sub-file + * for directories, create the directory (possibly recursively) + * for files, error normally, possibly useful for things + like zipfiles and db-interface files which want to provide + directory-like interface + * file( name ) -> Path + * create a sub-file path + * sub( name ) -> Path + * create a sub-directory path + * Eventually support zipfiles as Directory paths + + XXX Need to raise appropriate exceptions and look at ways to + reduce overhead beyond the naive implementation of many of the + methods. + + XXX Need to deal with upcoming switch to unicode values for path + names on OSes which support them. + """ + __slots__ = () + def check( cls, value ): + """Is the value an instance of this class?""" + return isinstance( value, BasePath ) + check = classmethod( check ) + def coerce( cls, value ): + """Coerce value to an instance of this class""" + if cls.check( value ): + return value + elif isinstance( value, BasePath ): + return value + elif isinstance( value, (str, unicode)): + return cls( value ) + elif isinstance( value, file ) or hasattr( value, 'name'): + return cls( value.name ) + else: + raise TypeError( """Unable to coerce value %r to a %s object"""%( + value, cls.__name__ + )) + coerce = classmethod( coerce ) + + def __repr__( self ): + return '%s(%s)'%(self.__class__.__name__, super(BasePath,self).__repr__( )) + def __eq__( self, other ): + """Attempt to determine if we are equal to other__""" + other = self.__class__.coerce( other ) + return self.canonical() == other.canonical() + def isParent (self, other): + """Return true if we are the parent of the other path + + Other can be a string specifier or a Path object + """ + other = self.__class__.coerce( other ) + return other.parent() == self + def isChild (self, other): + """Return true if we are a child of the other path""" + other = self.__class__.coerce( other ) + return self.parent() == other + def isAncestor( self, other ): + """Return true if we are an ancestor of the other path""" + other = self.__class__.coerce( other ) + if self.shareRoot( other ): + for item in self.__class__.coerce(other).parents(): + if item == self: + return 1 + return 0 + def isDescendent( self, other ): + """Return true if we are a descendent of the other path""" + other = self.__class__.coerce( other ) + return other.isAncestor( self ) + + def shareRoot( self, other): + """Return true if we are descended from the same root in the file system""" + other = self.__class__.coerce( other ) + return other.root() == self.root() + + def walk( self, file=None, pre=None, post=None ): + """Simple walking method + + For directories: + pre(path) is called before starting to process each directory + submember.walk(file,pre,post) is called on each sub-member + post(path) is called after processing all sub-members of the directory + For files: + file( path ) is called for each file in each directory + """ + if not file and not pre and not post: + return + if self.isFile(): + # what to do about file+directory types? + if file: + file(self) + if self.isDir(): + # is a directory + if pre: + pre( self ) + children = self.list() + for child in children: + child.walk( file, pre, post ) + if post: + post( self ) + + ### virtual methods... + def isFile( self ): + """Return true if we are a file path""" + def isAbsolute (self): + """Return true if this path is an absolute path (i.e. fully specified from a root)""" + def isRoot( self ): + """True iff this object is the root of its filesystem""" + def baseOnly( self ): + """Is this path reachable using only the base file system""" + + def sharedRoot(self, other): + """Return the path of the longest shared prefix for ourselves and other""" + def canonical(self): + """Get a canonical version of this path + + The new path will be absolute, expanded, + case-normalized, normalized, and converted + to a path of the same type as this one. + + It will include, where required, a pointer + to the parent-filesystem-path which points + to this path's root. + """ + def join( self, name ): + """Create a new Path from this path plus name""" + def split( self ): + """Return our parent path (if available) and our name""" + # make string split and join available via aliases + sjoin = str.join + ssplit = str.split diff --git a/resources/lib/basictypes/vfs/filepath.py b/resources/lib/basictypes/vfs/filepath.py new file mode 100644 index 0000000..4a6df2e --- /dev/null +++ b/resources/lib/basictypes/vfs/filepath.py @@ -0,0 +1,360 @@ +"""Spike test for filesystem-path objects + + +## Create a path representing an existing directory + +>>> from filepath import path +>>> p = path( 'c:\\temp' ) +>>> p +FileSystemPath('c:\\temp') + +## Lists the current contents of the directory + +>>> p.list() +[FileSystemPath('c:\\temp\\abook.mab'), FileSystemPath('c:\\temp\\impab.mab'), FileSystemPath('c:\\temp\\test.dat')] + +## Create a new path pointing to a non-existent directory + +>>> sd = p+'somewhere' +>>> sd.exists() +0 + +## Create the directory pointed to by our path +>>> sd.createDirectory() +>>> sd.exists() +1 + +## Get the parent of the path +>>> sd.parent() +FileSystemPath('c:\\temp') + +## Compare two different versions of the same path +>>> sd.parent() == p +1 + +## Explore the hierarchy of parents a little +## note that sd.parent().parent().parent() returns None +## so isn't really fun to look at in an interactive session +>>> sd.parent().parent() +FileSystemPath('c:\\') +>>> sd.root() +FileSystemPath('c:') + +## Create a deeply nested directory +>>> deep = sd.join( 'this', 'that', 'those' ) +>>> deep.createDirectory() +>>> deep.exists() +1 + +## Create a path for a file (deep + 'test.txt') also works +>>> f = deep.join( 'test.txt' ) +>>> f.open('w').write( 'some text' ) +>>> f +FileSystemPath('c:\\temp\\somewhere\\this\\that\\those\\test.txt') +>>> f.exists() +1 +>>> f.size() +9L +>>> f.remove() +>>> f.exists() +0 +>>> f.open('w').write( 'some text' ) + +## Remove the entire deeply nested directory +## including files +>>> sd.remove() +>>> f.exists() +0 + +## Demonstrate walking a path hierarchy with simple callbacks +>>> newDirectories = ["why", "not", "me"] +>>> for directory in newDirectories: +... sub = sd+directory +... sub.createDirectory () +... (sub + 'test.txt').open('w').write( "hello world!") +... +>>> fileList = [] +>>> sd.walk( file = fileList.append ) +>>> fileList +[FileSystemPath('c:\\temp\\somewhere\\me\\test.txt'), FileSystemPath('c:\\temp\\somewhere\\not\\test.txt'), FileSystemPath('c:\\temp\\somewhere\\why\\test.txt')] +>>> directoryList = [] +>>> sd.walk( pre = directoryList.append ) +>>> directoryList +[FileSystemPath('c:\\temp\\somewhere'), FileSystemPath('c:\\temp\\somewhere\\me'), FileSystemPath('c:\\temp\\somewhere\\not'), FileSystemPath('c:\\temp\\somewhere\\why')] +>>> +""" + +import os +from basictypes.vfs import path, basepath + +class FilePath( basepath.BasePath ): + """Representation of a path in the FileSystem + + XXX More documentation + XXX Need better support for unc names + + """ + root = None + fragments = None + + def isFile( self ): + """Return true if we are a file path""" + return os.path.isfile( self ) + def isDir( self ): + """Return true if we are a directory path""" + return os.path.isdir( self ) + def isRoot( self ): + """True if this object is the root of its filesystem""" + unc = self.unc() + if not unc: + return os.path.ismount( self ) + else: + return unc == self.canonical() + def isAbsolute (self): + """Return true if this path is an absolute path""" + return os.path.isabs( self ) + + def baseOnly( self ): + """Is this path reachable using only the base file system""" + return 1 + def parent( self ): + """Get the parent of this path as a Path""" + # rather than using canonical, we should instead + # first try splitting ourselves, only forcing the + # canonical conversion if we find that doesn't tell + # us whether we have parents... alternately, raise + # an error saying we can't tell what the parent is + # at the moment... + if self.isRoot(): + return None + parent, rest = os.path.split( self.canonical() ) + if rest and parent: + # managed to split something off + return path(parent, self.__class__) + else: + return None + def baseName (self): + """Get the final fragment of the path as a string""" + return os.path.basename( self ) + + def exists( self ): + """Return true if this path exists + + XXX Should catch primitive errors and raise more useful ones + """ + if os.path.exists( self ): + return 1 + else: + return 0 + def root( self ): + """Get the root of this path""" + full = path(self.canonical(), self.__class__) + unc = full.unc() + if unc: + return unc + drive = full.drive() + if drive: + return drive + else: + return None + + def unc( self, ): + """Get the root UNC Path, or None if it doesn't exist + + XXX This appears to always return the unc name as lowercase? + """ + unc,rest = os.path.splitunc( self.canonical()) + if unc: + return path( unc, self.__class__ ) + else: + return None + def drive (self,): + """Get the root drive Path, or None if it doesn't exist""" + drive,rest = os.path.splitdrive( self.canonical()) + if drive: + return path( drive+os.sep, self.__class__ ) + else: + return None + + def fragments (self): + """Get the path as a set of string fragments""" + fragments = [] + fragment = 1 + full = path(self.canonical(), self.__class__ ) + while full and fragment: + full, fragment = full.split() + if fragment: + fragments.append( fragment ) + else: + fragments.append( full ) + fragments.reverse() + return fragments + def parents( self ): + """Return all of our parents up to our root""" + fragments = self.fragments() + if not fragments: + # XXX fix this + raise ValueError( "parents of a NULL path?" ) + current = None + result = [] + for value in fragments[:-1]: + if current is None: + current = value + else: + current = current + value + result.append( current ) + return result + + + def canonical(self): + """Get a canonical version of this path + + The new path will be absolute, expanded, + case-normalized, and normalized. + """ + return os.path.normcase( + os.path.normpath( + os.path.expanduser( + os.path.expandvars( + os.path.realpath(self) + ) + ) + ) + ) + + + def join( self, * name ): + """Create a new Path from this path plus name""" + return path( + os.path.join(str(self), *name), + self.__class__ + ) + __add__ = join + + def split( self ): + """Return our parent path (if available) and our name""" + head, tail = os.path.split( self ) + return path(head, self.__class__), path(tail, self.__class__) + def extension (self): + """Return the file extension, or "" if there is no extension""" + return os.path.splitext(self)[1] + splitext = extension + + def stat( self ): + """Attempt to run a stat on the object""" + return os.stat( self ) + def size( self ): + """Attempt to get the (byte) size of the object on disk + + Note: calling this on directories does a recursive call + adding up the sizes up the files in the directory, which can + be rather expensive. + """ + if self.exists(): + if self.isFile(): + return os.stat( self).st_size + else: + class collect(object): + total = 0 + def __call__( self, filePath ): + self.total = self.total + filePath.size() + c = collect() + self.walk( file = c ) + return c.total + raise NotImplementedError( """Couldn't get size for path %s"""%(repr(self))) + def permissions (self, mode=None ): + """Attempt to update and/or read permissions for the path + + if mode is None --> attempt to read permissions, return None if couldn't succeed + if mode is anything else --> call chmod with the value + + XXX Eventually, this should support platform-specific permission + specifications, such as Secure Linux or WinNT permissions, + though I'm not sure how + """ + if mode is None: + # get + if self.exists(): + if self.isFile(): + return os.stat( self).st_mode + else: + return None + raise NotImplementedError( """Couldn't get permissions for path %s"""%(repr(self))) + else: + if self.exists(): + os.chmod( self, mode ) + + def remove( self ): + """(Recursively) remove this object from the filesystem + + XXX Should provide options to change permissions if they are + incorrectly set (e.g. read-only), and maybe clobber + locks/holds if they exist (not even sure that's possible) + """ + self.walk( + file=os.remove, + post= os.rmdir + ) + + ### APIs that assume directory/file status... + def list( self, glob="" ): + """Return a list of Path objects representing the current contents of this directory""" + return [ + self.join( name ) + for name in os.listdir( self ) + ] + def createDirectory(self,*arguments,**namedarguments): + """Ensure that a directory exists, if possible + + Note: will not work with zipfile directories as they + don't really exist, zipfiles should probably recurse + down to the ZIP file, create the ZIP file and then, + if there is an embedded filesystem (such as an embedded + zipfile) create that, otherwise ignore the remainder + of the path. + """ + return os.makedirs( self, *arguments, **namedarguments ) + def file (self, name ): + """Create a new file path within this directory""" + if self.isDir(): + return self.join( name ) + else: + raise ValueError( """Can't currently create a file in a file""" ) + + def subDir(self, name,*arguments,**namedarguments): + """Create a new subdirectory path within this directory""" + if self.isDir(): + return self.join( name ) + else: + raise ValueError( """Can't currently create a directory in a file""" ) + + def open(self, *arguments,**namedarguments): + """Attempt to open a file path for reading/writing/appending + + returns file( self, *arguments, **namedarguments) for the moment + might return a file sub-class eventually + """ + return file( self, *arguments, **namedarguments) + + ### "Somday" functionality + def mimeType( self ): + """Attempt to determine the platform-specific mime type mapping for this path + + XXX Only source I know with this info is wxPython + """ + def association (self): + """Attempt to determine the platform-specific application association for the path + + XXX This is going to be a guess on most platforms I'd assume + Windows -- assoc + ftype, or a registry access + Mac -- resource fork of the file + """ + def start (self): + """Attempt to start the system's default application for this file + + This is a serious security consideration, but it's something people + are wanting to do all the time, not sure where to stand on it. + """ + def touch( self ): + """Attempt to update times on the path""" + diff --git a/resources/lib/basictypes/vfs/test_filepath.py b/resources/lib/basictypes/vfs/test_filepath.py new file mode 100644 index 0000000..8803861 --- /dev/null +++ b/resources/lib/basictypes/vfs/test_filepath.py @@ -0,0 +1,116 @@ +import unittest, os +from basictypes.vfs import path + +class NTFilePathTests(unittest.TestCase): + """Note: these tests are Windows-specific""" + def testRepr( self ): + """Test representation is as expected""" + value = path( "test" ) + result = repr( value ) + expected = "%s(%s)"%( value.__class__.__name__, repr(str(value))) + self.failUnlessEqual( result, expected, """Got:\n%s\t\nExpected:\n\t%s"""% (result, expected)) + def testSimpleRelative( self ): + """Test a simple relative path for basic operations""" + fileName = "test.tmp" + testFile = path(fileName) + assert testFile == fileName,"""Path did not match an equal string""" + assert str(testFile) == fileName,"""str(Path) did not match an equal string""" + assert not testFile.isAbsolute(),"""relative path declared itself absolute""" + assert not testFile.isRoot(),"""non-root path declared itself root""" + assert testFile.baseOnly(),"""base file system path declared itself non-base""" + open( fileName,'w' ).write( 'ha' ) + assert testFile.exists(),"""could not create file in current working directory, or exists method failure""" + assert testFile.parent() == os.getcwd(),"""file created in current working directory does not report current working directory as parent""" + assert testFile.size() == 2,"""file with two bytes written reports size other than 2, possible bug in size (or data writing)""" + + open( testFile, 'w').write( 'ham' ) + assert testFile.exists(),"""could not create file in current working directory, or exists method failure""" + assert testFile.parent() == os.getcwd(),"""file created in current working directory does not report current working directory as parent""" + assert testFile.size() == 3,"""file with 3 bytes written reports size other than 3, possible bug in size (or data writing)""" + def testFullySpecified (self): + """Test a fully specified file path""" + # now a fully-specified path + fileName = "c:\\test.tmp" + testFile = path(fileName) + assert testFile == fileName,"""Path did not match an equal string""" + assert str(testFile) == fileName,"""str(Path) did not match an equal string""" + assert testFile.isAbsolute(),"""absolute path declared itself relative""" + assert not testFile.isRoot(),"""root path declared itself non-root""" + assert testFile.baseOnly(),"""base file system path declared itself non-base""" + + result = testFile.parent() + assert result == "c:\\","""parent reported as %s"""% (result) + assert result == path( "c:\\" ),"""parent reported as %s"""% (result) + + assert testFile.isChild( "c:\\" ) + assert testFile.drive() == 'c:\\', "got %s"%( repr(testFile.drive())) + assert testFile.root() == 'c:\\' + assert path( "c:\\" ).isParent( testFile ) + def testRoot(self): + """Test a root for the file system""" + # test a real root + roots = [path("c:\\"), path( r"\\Raistlin\c")] + for root in roots: + assert root.isRoot() + assert root.parent() == None + assert root.root() == root + assert path("c:\\").unc() == None + assert path("c:\\").drive() == "c:\\" + assert path("c:\\temp").drive() == "c:\\" + assert path("c:\\temp").root() == "c:\\" + assert path("c:\\temp").drive()[-1] == os.sep + + assert path(r"\\Raistlin\c").drive() == None + assert path(r"\\Raistlin\c").unc() == r"\\raistlin\c" + assert path(r"\\Raistlin\c").parent() == None + assert path(r"\\Raistlin\c").root() == r"\\raistlin\c" + def testFragments (self): + """Test ability to break paths into fragments""" + assert path( + "p:\\temp\\this\\that\\thos\\test.tmp" + ).fragments() == [ 'p:\\', 'temp','this','that','thos','test.tmp'] + assert path( + "c:" + ).fragments() == [ 'c:\\'] + assert path( + "p:\\temp\\this\\that\\thos\\test.tmp" + ).parents() == [ + 'p:\\', + 'p:\\temp', + 'p:\\temp\\this', + 'p:\\temp\\this\\that', + 'p:\\temp\\this\\that\\thos', + ], "Got: %s"%( path( + "p:\\temp\\this\\that\\thos\\test.tmp" + ).parents() ) + def testWalk (self): + """Test three-method walking functions""" + dir = path( + "p:\\temp" + ) + assert dir.join('test') == "p:\\temp\\test" + result = [] + # need a testing directory for this to be automated... + dir.walk( result.append ) + def testFileDirectoryOperations (self): + """Test file and/or directory-specific operations""" + dir = path( + "p:\\temp\\this\\that" + ) + try: + dir.walk( file=os.remove, post= os.rmdir) + except OSError, err: + print 'failed to remove', err + dir.createDirectory( mode = 0777 ) + f = dir+'test.txt' + f.open('w').write( 'testing' ) + assert f.exists() + assert f.open('r').read() == 'testing' + + + +def getSuite(): + return unittest.makeSuite(NTFilePathTests,'test') + +if __name__ == "__main__": + unittest.main(defaultTest="getSuite") diff --git a/resources/lib/basictypes/wx/__init__.py b/resources/lib/basictypes/wx/__init__.py new file mode 100644 index 0000000..5f59d4f --- /dev/null +++ b/resources/lib/basictypes/wx/__init__.py @@ -0,0 +1 @@ +"""wxPython data-type models""" diff --git a/resources/lib/basictypes/wx/colour.py b/resources/lib/basictypes/wx/colour.py new file mode 100644 index 0000000..7379ee8 --- /dev/null +++ b/resources/lib/basictypes/wx/colour.py @@ -0,0 +1,59 @@ +"""wxPython colour data-type definition +""" +import wx +from basictypes import datatypedefinition, registry +#from basictypes.wxtypes import wxcopyreg + +from wxPython.lib import colourdb +COLOUR_DB_INITIALISED = 0 + +__all__ = ( "wxColour_DT", ) + +class wxColour_DT( datatypedefinition.BaseType_DT ): + """Colour data-modelling type stand-in""" + dataType = "wx.colour" + baseType = wx.Colour + def coerce(cls, value): + """Attempt to convert the given value to a wx.Colour + + Accepted Values: + wx.Colour(Ptr) + '#FFFFFF' style strings + 'black' string colour names + 3-tuple or 3-list of 0-255 integers + None -- (gives black) + """ + if cls.check( value ): + return value + elif isinstance( value, (str,unicode) ): + if value and value[0] == '#': + rest = value[1:] + if rest: + value = int( rest, 16) + return wx.Colour( value >> 16 & 255, value >> 8 & 255, value & 255 ) + else: + return wx.Colour( 0,0,0) + else: + try: + obj = wx.Colour( value ) + except (ValueError,TypeError): + global COLOUR_DB_INITIALISED + if not COLOUR_DB_INITIALISED: + COLOUR_DB_INITIALISED = 1 + colourdb.updateColourDB() + obj = wx.NamedColour( value ) + if not obj.Ok(): + raise ValueError( """Unrecognised string value %r for Colour value"""%(value)) + elif isinstance( value, (tuple,list) ): + if len(value) == 3: + obj = wx.Colour( *value ) + else: + raise ValueError( """Unable to create wx.Colour from %r, incorrect length"""%( value )) + elif value is None: + return wx.Colour( 0,0,0) + else: + raise TypeError( """Unable to convert value %r (type %s) to wx.Colour object"""%( value, type(value))) + return obj + coerce = classmethod( coerce ) +registry.registerDT( wx.Colour, wxColour_DT) +registry.registerDT( wx.ColourPtr, wxColour_DT) diff --git a/resources/lib/basictypes/wx/font.py b/resources/lib/basictypes/wx/font.py new file mode 100644 index 0000000..f7ec03a --- /dev/null +++ b/resources/lib/basictypes/wx/font.py @@ -0,0 +1,13 @@ +"""Data-type definition for wxPython font class""" +from wxPython.wx import * +from basictypes import datatypedefinition, registry +##from basictypes.wx import wxcopyreg + +__all__ = ( "wxFont_DT", ) + +class wxFont_DT( datatypedefinition.BaseType_DT ): + """Data-type definition for wxPython font class""" + dataType = "wx.font" + baseType = wxFontPtr +registry.registerDT( wxFontPtr, wxFont_DT) +registry.registerDT( wxFont, wxFont_DT) diff --git a/resources/lib/basictypes/wx/pen.py b/resources/lib/basictypes/wx/pen.py new file mode 100644 index 0000000..9962cb5 --- /dev/null +++ b/resources/lib/basictypes/wx/pen.py @@ -0,0 +1,212 @@ +"""wxPython colour data-type definition +""" +import wx +from basictypes import datatypedefinition, enumeration, registry +##from basictypes.wx import wxcopyreg +from basicproperty import basic + +__all__ = ( "wxPen_DT", "PenStyleProperty", "PenCapProperty") + +class wxPen(wx.Pen): + """A somewhat easier-to-use Pen class for use with basictypes""" + dataType = "wx.pen" + coreAttributes = ('colour','width','style','cap','join',) + extraAttributes = ('stipple','dashes') + def __init__( + self, + colour="BLACK", + width=1, + style=wx.SOLID, + cap=wx.CAP_ROUND, + join=wx.JOIN_ROUND, + stipple=None, + dashes=None, + ): + """Initialize the wxPen object + + colour -- wxColour specifier, a wxColour, a named colour + or a #ffffff formatted string value + width -- pen-width in pixels + style -- one of the wxPen style constants + wxSOLID + wxVERTICAL_HATCH + wxUSER_DASH + wxCROSSDIAG_HATCH + wxHORIZONTAL_HATCH + wxSTIPPLE + wxBDIAGONAL_HATCH + wxFDIAGONAL_HATCH + wxDOT_DASH + wxSHORT_DASH + wxLONG_DASH + wxCROSS_HATCH + wxTRANSPARENT + cap -- one of the wxPen cap constants + wxCAP_ROUND + wxCAP_BUTT + wxCAP_PROJECTING + join -- one of the wxPen join constants + wxJOIN_BEVEL + wxJOIN_MITER + wxJOIN_ROUND + stipple -- when style == wxSTIPPLE, a bitmap used to + control the drawing style + dashes -- when style == wxUSER_DASH, an array used to + control the drawing style + XXX what is the array of? lengths? I assume it's + just a python list of something, but I don't + know what. + """ + if isinstance( style, enumeration.Enumeration ): + style = style.value() + wx.Pen.__init__( self, colour, width, style ) + if isinstance( join, enumeration.Enumeration ): + join = join.value() + self.SetJoin( join ) + if isinstance( cap, enumeration.Enumeration ): + cap = cap.value() + self.SetCap( cap ) + if style == wx.STIPPLE and stipple is not None: + self.SetStipple( stipple ) + elif style == wx.USER_DASH and dashes is not None: + self.SetDashes( dashes ) + def coreValues( self ): + """Get the core values for this instance""" + return dict([ + (attr,getattr(self,'Get%s'%attr.capitalize())()) + for attr in self.coreAttributes + ]) + def __repr__( self ): + """Get a nice debugging representation of this object""" + v = self.coreValues() + v = ", ".join([ + '%s=%r'%(attr,v.get(attr)) + for attr in self.coreAttributes + if v.get(attr) is not None + ]) + return "%s(%s)"%( self.__class__.__name__, v) + + + def __eq__( self, other ): + """Compare our core values to pen defined in other""" + if not isinstance( other, wx.Pen): + other = self.__class__.coerce( other ) + a,b = self.coreValues(), other.coreValues() + if a != b: + return 0 + # possibility of a stipple or dashes type diff + if a['style'] == wx.STIPPLE: + return self.GetStipple() == other.GetStipple() + elif a['style'] == wx.USER_DASH: + return self.GetDashes() == other.GetDashes() + else: + return 1 + + + def check( cls, value ): + """Check that value is a wxPen instance""" + return isinstance( value, cls ) + check = classmethod( check ) + + def coerce( cls, value ): + """Coerce value to an instance of baseType + + Accepted: + object: w/ style, colour and width props (cap, join, and stipple optional) + tuple (colour,width,style,cap,join,stipple) + dict w/ names + """ + if cls.check( value ): + return value + if isinstance( value, (tuple,list)): + return cls( *value ) + elif isinstance( value, dict ): + return cls( **value ) + else: + set = {} + for attribute in cls.coreAttributes+cls.extraAttributes: + method = 'Get%s'%(attribute.capitalize()) + if hasattr( value, attribute ): + set[attribute] = getattr(value,attribute) + elif hasattr( value, method): + set[attribute] = getattr(value,method)() + return cls( **set ) + coerce = classmethod( coerce ) + +registry.registerDT( wx.PenPtr, wxPen) + +def defaultPen( ): + return wx.BLACK_PEN + +PenStyleSet = enumeration.EnumerationSet() +PenStyleSet.new(name='wxSHORT_DASH',value=wx.SHORT_DASH,friendlyName='Short Dash') +PenStyleSet.new(name='wxSOLID',value=wx.SOLID,friendlyName='Solid ') +PenStyleSet.new(name='wxCROSS_HATCH',value=wx.CROSS_HATCH,friendlyName='Cross-Hatching') +PenStyleSet.new(name='wxVERTICAL_HATCH',value=wx.VERTICAL_HATCH,friendlyName='Vertical Hatching') +PenStyleSet.new(name='wxFDIAGONAL_HATCH',value=wx.FDIAGONAL_HATCH,friendlyName='Forward Diagonal Hatching') +PenStyleSet.new(name='wxLONG_DASH',value=wx.LONG_DASH,friendlyName='Long Dash') +PenStyleSet.new(name='wxUSER_DASH',value=wx.USER_DASH,friendlyName='User Defined Dash') +PenStyleSet.new(name='wxCROSSDIAG_HATCH',value=wx.CROSSDIAG_HATCH,friendlyName='Cross-Diagonal Hatching') +PenStyleSet.new(name='wxHORIZONTAL_HATCH',value=wx.HORIZONTAL_HATCH,friendlyName='Horizontal Hatching') +PenStyleSet.new(name='wxSTIPPLE',value=wx.STIPPLE,friendlyName='Stippled') +PenStyleSet.new(name='wxBDIAGONAL_HATCH',value=wx.BDIAGONAL_HATCH,friendlyName='Diagonal Hatching') +PenStyleSet.new(name='wxTRANSPARENT',value=wx.TRANSPARENT,friendlyName='Transparent') +PenStyleSet.new(name='wxDOT_DASH',value=wx.DOT_DASH,friendlyName='Dot Dash') +PenCapSet = enumeration.EnumerationSet() +PenCapSet.new(name='wxCAP_BUTT',value=wx.CAP_BUTT,friendlyName='Flat') +PenCapSet.new(name='wxCAP_PROJECTING',value=wx.CAP_PROJECTING,friendlyName='Projecting') +PenCapSet.new(name='wxCAP_ROUND',value=wx.CAP_ROUND,friendlyName='Rounded') +PenJoinSet = enumeration.EnumerationSet() +PenJoinSet.new(name='wxJOIN_BEVEL',value=wx.JOIN_BEVEL,friendlyName='Bevel') +PenJoinSet.new(name='wxJOIN_MITER',value=wx.JOIN_MITER,friendlyName='Miter') +PenJoinSet.new(name='wxJOIN_ROUND',value=wx.JOIN_ROUND,friendlyName='Round') + +class PenStyle(enumeration.Enumeration): + """Enumeration representing a pen-drawing style""" + set = PenStyleSet + dataType = enumeration.Enumeration.dataType+'.penstyle' + +class PenCap(enumeration.Enumeration): + """Enumeration representing a pen-cap style""" + set = PenCapSet + dataType = enumeration.Enumeration.dataType+'.pencap' + +class PenJoin(enumeration.Enumeration): + """Enumeration representing a pen-join style""" + set = PenJoinSet + dataType = enumeration.Enumeration.dataType+'.penjoin' + + +##class PenStandIn( propertied.Propertied ): +## """Stand-in object for editing (immutable) wxPen values""" +## style = basic.BasicProperty( +## 'style', """The line style for the pen""", +## friendlyName = """Line Style""", +## baseType = PenStyle, +## defaultValue = 'wxSOLID', +## ) +## cap = basic.BasicProperty( +## 'cap', """The cap (end-of-line) style for the pen""", +## friendlyName = """Cap Style""", +## baseType = PenCap, +## defaultValue = 'wxCAP_ROUND', +## ) +## join = basic.BasicProperty( +## 'join', """The cap (end-of-line) style for the pen""", +## friendlyName = """Join Style""", +## baseType = PenJoin, +## defaultValue = 'wxJOIN_ROUND', +## ) +## colour = common.ColourProperty( +## "colour", """The pen colour""", +## friendlyName = "Colour", +## defaultValue = (0,0,0), +## ) +## width = common.IntegerProperty( +## "width", """The line width of the pen""", +## defaultValue = 1, +## ) + + + + \ No newline at end of file diff --git a/resources/lib/basictypes/wx/wxcopyreg.py b/resources/lib/basictypes/wx/wxcopyreg.py new file mode 100644 index 0000000..807137f --- /dev/null +++ b/resources/lib/basictypes/wx/wxcopyreg.py @@ -0,0 +1,131 @@ +"""wxcopyreg -- functions for storing/restoring simple wxPython data types to pickle-friendly formats + +importing this module installs the functions automatically! +""" +import pickle, zlib +from wxPython.wx import * + +## + + +def bind( classObject, outFunction, inFunction ): + """Bind get and set state for the classObject""" + classObject.__getstate__ = outFunction + classObject.__setstate__ = inFunction + + + +def wxColourOut( value ): + return value.Red(), value.Green(), value.Blue() +def wxColourIn( self, args ): + self.this = apply(gdic.new_wxColour,args) + self.thisown = 1 + +bind( wxColourPtr, wxColourOut, wxColourIn ) + + +def wxFontOut( value ): + return ( + value.GetPointSize(), + value.GetFamily(), + value.GetStyle(), + value.GetWeight(), + value.GetUnderlined(), + value.GetFaceName(), + # note that encoding is missing... + ) +def wxFontIn( self, args ): + self.this = apply(fontsc.new_wxFont,args) + self.thisown = 1 + +bind( wxFontPtr, wxFontOut, wxFontIn ) + + +def wxPenOut( value ): + colour = value.GetColour() + return ( + ( + colour.Red(), + colour.Green(), + colour.Blue() + ), + ( + value.GetWidth(), + value.GetStyle(), + ), + ( + #stipple is a bitmap, we don't currently have + #mechanisms for storing/restoring it, so ignore it +## value.GetStipple(), + value.GetJoin(), + # missing in the current wxPython pre-release + # should be available in wxPython 2.3.3 final +## value.GetDashes(), + value.GetCap(), + ), + ) +def wxPenIn( self, (colour, init, props) ): + colour = wxColour( *colour ) + self.this = apply(gdic.new_wxPen,(colour,)+init) + self.thisown = 1 + for prop, function in map( None, props, ( + #stipple is a bitmap, we don't currently have + #mechanisms for storing/restoring it, so ignore it +## self.SetStipple, + self.SetJoin, + # missing in the current wxPython pre-release + # should be available in wxPython 2.3.3 final +## self.SetDashes, + self.SetCap + )): + function( prop ) + + +def wxPyPenIn( self, (colour, init, props) ): + colour = wxColour( *colour ) + self.this = apply(gdic.new_wxPyPen,(colour,)+init) + self.thisown = 1 + for prop, function in map( None, props, ( + #stipple is a bitmap, we don't currently have + #mechanisms for storing/restoring it, so ignore it +## self.SetStipple, + self.SetJoin, + # missing in the current wxPython pre-release + # should be available in wxPython 2.3.3 final +## self.SetDashes, + self.SetCap + )): + function( prop ) + + +bind( wxPenPtr, wxPenOut, wxPenIn ) +bind( wxPyPenPtr, wxPenOut, wxPyPenIn ) + + +def wxImageOut( value ): + width,height = value.GetWidth(), value.GetHeight() + data = value.GetData() + data = zlib.compress( data ) + return ( width, height, data ) +def wxImageIn( self, (width, height, data) ): + self.this = apply(imagec.wxEmptyImage,(width,height)) + self.thisown = 1 + self.SetData( zlib.decompress( data) ) + +bind( wxImagePtr, wxImageOut, wxImageIn ) + + + +def test(): + for o in [ + wxColour( 23,23,23), + wxFont( 12, wxMODERN, wxNORMAL, wxNORMAL ), + wxPen(wxColour( 23,23,23),1,wxSOLID), + wxImage( 'test.jpg', wxBITMAP_TYPE_ANY ), + ]: + o2 = pickle.loads(pickle.dumps(o)) + print o2 + +if __name__ == "__main__": + wxInitAllImageHandlers() + test() \ No newline at end of file diff --git a/resources/lib/basictypes/wxtypes/__init__.py b/resources/lib/basictypes/wxtypes/__init__.py new file mode 100644 index 0000000..5f59d4f --- /dev/null +++ b/resources/lib/basictypes/wxtypes/__init__.py @@ -0,0 +1 @@ +"""wxPython data-type models""" diff --git a/resources/lib/basictypes/wxtypes/colour.py b/resources/lib/basictypes/wxtypes/colour.py new file mode 100644 index 0000000..7379ee8 --- /dev/null +++ b/resources/lib/basictypes/wxtypes/colour.py @@ -0,0 +1,59 @@ +"""wxPython colour data-type definition +""" +import wx +from basictypes import datatypedefinition, registry +#from basictypes.wxtypes import wxcopyreg + +from wxPython.lib import colourdb +COLOUR_DB_INITIALISED = 0 + +__all__ = ( "wxColour_DT", ) + +class wxColour_DT( datatypedefinition.BaseType_DT ): + """Colour data-modelling type stand-in""" + dataType = "wx.colour" + baseType = wx.Colour + def coerce(cls, value): + """Attempt to convert the given value to a wx.Colour + + Accepted Values: + wx.Colour(Ptr) + '#FFFFFF' style strings + 'black' string colour names + 3-tuple or 3-list of 0-255 integers + None -- (gives black) + """ + if cls.check( value ): + return value + elif isinstance( value, (str,unicode) ): + if value and value[0] == '#': + rest = value[1:] + if rest: + value = int( rest, 16) + return wx.Colour( value >> 16 & 255, value >> 8 & 255, value & 255 ) + else: + return wx.Colour( 0,0,0) + else: + try: + obj = wx.Colour( value ) + except (ValueError,TypeError): + global COLOUR_DB_INITIALISED + if not COLOUR_DB_INITIALISED: + COLOUR_DB_INITIALISED = 1 + colourdb.updateColourDB() + obj = wx.NamedColour( value ) + if not obj.Ok(): + raise ValueError( """Unrecognised string value %r for Colour value"""%(value)) + elif isinstance( value, (tuple,list) ): + if len(value) == 3: + obj = wx.Colour( *value ) + else: + raise ValueError( """Unable to create wx.Colour from %r, incorrect length"""%( value )) + elif value is None: + return wx.Colour( 0,0,0) + else: + raise TypeError( """Unable to convert value %r (type %s) to wx.Colour object"""%( value, type(value))) + return obj + coerce = classmethod( coerce ) +registry.registerDT( wx.Colour, wxColour_DT) +registry.registerDT( wx.ColourPtr, wxColour_DT) diff --git a/resources/lib/basictypes/wxtypes/font.py b/resources/lib/basictypes/wxtypes/font.py new file mode 100644 index 0000000..f7ec03a --- /dev/null +++ b/resources/lib/basictypes/wxtypes/font.py @@ -0,0 +1,13 @@ +"""Data-type definition for wxPython font class""" +from wxPython.wx import * +from basictypes import datatypedefinition, registry +##from basictypes.wx import wxcopyreg + +__all__ = ( "wxFont_DT", ) + +class wxFont_DT( datatypedefinition.BaseType_DT ): + """Data-type definition for wxPython font class""" + dataType = "wx.font" + baseType = wxFontPtr +registry.registerDT( wxFontPtr, wxFont_DT) +registry.registerDT( wxFont, wxFont_DT) diff --git a/resources/lib/basictypes/wxtypes/pen.py b/resources/lib/basictypes/wxtypes/pen.py new file mode 100644 index 0000000..9962cb5 --- /dev/null +++ b/resources/lib/basictypes/wxtypes/pen.py @@ -0,0 +1,212 @@ +"""wxPython colour data-type definition +""" +import wx +from basictypes import datatypedefinition, enumeration, registry +##from basictypes.wx import wxcopyreg +from basicproperty import basic + +__all__ = ( "wxPen_DT", "PenStyleProperty", "PenCapProperty") + +class wxPen(wx.Pen): + """A somewhat easier-to-use Pen class for use with basictypes""" + dataType = "wx.pen" + coreAttributes = ('colour','width','style','cap','join',) + extraAttributes = ('stipple','dashes') + def __init__( + self, + colour="BLACK", + width=1, + style=wx.SOLID, + cap=wx.CAP_ROUND, + join=wx.JOIN_ROUND, + stipple=None, + dashes=None, + ): + """Initialize the wxPen object + + colour -- wxColour specifier, a wxColour, a named colour + or a #ffffff formatted string value + width -- pen-width in pixels + style -- one of the wxPen style constants + wxSOLID + wxVERTICAL_HATCH + wxUSER_DASH + wxCROSSDIAG_HATCH + wxHORIZONTAL_HATCH + wxSTIPPLE + wxBDIAGONAL_HATCH + wxFDIAGONAL_HATCH + wxDOT_DASH + wxSHORT_DASH + wxLONG_DASH + wxCROSS_HATCH + wxTRANSPARENT + cap -- one of the wxPen cap constants + wxCAP_ROUND + wxCAP_BUTT + wxCAP_PROJECTING + join -- one of the wxPen join constants + wxJOIN_BEVEL + wxJOIN_MITER + wxJOIN_ROUND + stipple -- when style == wxSTIPPLE, a bitmap used to + control the drawing style + dashes -- when style == wxUSER_DASH, an array used to + control the drawing style + XXX what is the array of? lengths? I assume it's + just a python list of something, but I don't + know what. + """ + if isinstance( style, enumeration.Enumeration ): + style = style.value() + wx.Pen.__init__( self, colour, width, style ) + if isinstance( join, enumeration.Enumeration ): + join = join.value() + self.SetJoin( join ) + if isinstance( cap, enumeration.Enumeration ): + cap = cap.value() + self.SetCap( cap ) + if style == wx.STIPPLE and stipple is not None: + self.SetStipple( stipple ) + elif style == wx.USER_DASH and dashes is not None: + self.SetDashes( dashes ) + def coreValues( self ): + """Get the core values for this instance""" + return dict([ + (attr,getattr(self,'Get%s'%attr.capitalize())()) + for attr in self.coreAttributes + ]) + def __repr__( self ): + """Get a nice debugging representation of this object""" + v = self.coreValues() + v = ", ".join([ + '%s=%r'%(attr,v.get(attr)) + for attr in self.coreAttributes + if v.get(attr) is not None + ]) + return "%s(%s)"%( self.__class__.__name__, v) + + + def __eq__( self, other ): + """Compare our core values to pen defined in other""" + if not isinstance( other, wx.Pen): + other = self.__class__.coerce( other ) + a,b = self.coreValues(), other.coreValues() + if a != b: + return 0 + # possibility of a stipple or dashes type diff + if a['style'] == wx.STIPPLE: + return self.GetStipple() == other.GetStipple() + elif a['style'] == wx.USER_DASH: + return self.GetDashes() == other.GetDashes() + else: + return 1 + + + def check( cls, value ): + """Check that value is a wxPen instance""" + return isinstance( value, cls ) + check = classmethod( check ) + + def coerce( cls, value ): + """Coerce value to an instance of baseType + + Accepted: + object: w/ style, colour and width props (cap, join, and stipple optional) + tuple (colour,width,style,cap,join,stipple) + dict w/ names + """ + if cls.check( value ): + return value + if isinstance( value, (tuple,list)): + return cls( *value ) + elif isinstance( value, dict ): + return cls( **value ) + else: + set = {} + for attribute in cls.coreAttributes+cls.extraAttributes: + method = 'Get%s'%(attribute.capitalize()) + if hasattr( value, attribute ): + set[attribute] = getattr(value,attribute) + elif hasattr( value, method): + set[attribute] = getattr(value,method)() + return cls( **set ) + coerce = classmethod( coerce ) + +registry.registerDT( wx.PenPtr, wxPen) + +def defaultPen( ): + return wx.BLACK_PEN + +PenStyleSet = enumeration.EnumerationSet() +PenStyleSet.new(name='wxSHORT_DASH',value=wx.SHORT_DASH,friendlyName='Short Dash') +PenStyleSet.new(name='wxSOLID',value=wx.SOLID,friendlyName='Solid ') +PenStyleSet.new(name='wxCROSS_HATCH',value=wx.CROSS_HATCH,friendlyName='Cross-Hatching') +PenStyleSet.new(name='wxVERTICAL_HATCH',value=wx.VERTICAL_HATCH,friendlyName='Vertical Hatching') +PenStyleSet.new(name='wxFDIAGONAL_HATCH',value=wx.FDIAGONAL_HATCH,friendlyName='Forward Diagonal Hatching') +PenStyleSet.new(name='wxLONG_DASH',value=wx.LONG_DASH,friendlyName='Long Dash') +PenStyleSet.new(name='wxUSER_DASH',value=wx.USER_DASH,friendlyName='User Defined Dash') +PenStyleSet.new(name='wxCROSSDIAG_HATCH',value=wx.CROSSDIAG_HATCH,friendlyName='Cross-Diagonal Hatching') +PenStyleSet.new(name='wxHORIZONTAL_HATCH',value=wx.HORIZONTAL_HATCH,friendlyName='Horizontal Hatching') +PenStyleSet.new(name='wxSTIPPLE',value=wx.STIPPLE,friendlyName='Stippled') +PenStyleSet.new(name='wxBDIAGONAL_HATCH',value=wx.BDIAGONAL_HATCH,friendlyName='Diagonal Hatching') +PenStyleSet.new(name='wxTRANSPARENT',value=wx.TRANSPARENT,friendlyName='Transparent') +PenStyleSet.new(name='wxDOT_DASH',value=wx.DOT_DASH,friendlyName='Dot Dash') +PenCapSet = enumeration.EnumerationSet() +PenCapSet.new(name='wxCAP_BUTT',value=wx.CAP_BUTT,friendlyName='Flat') +PenCapSet.new(name='wxCAP_PROJECTING',value=wx.CAP_PROJECTING,friendlyName='Projecting') +PenCapSet.new(name='wxCAP_ROUND',value=wx.CAP_ROUND,friendlyName='Rounded') +PenJoinSet = enumeration.EnumerationSet() +PenJoinSet.new(name='wxJOIN_BEVEL',value=wx.JOIN_BEVEL,friendlyName='Bevel') +PenJoinSet.new(name='wxJOIN_MITER',value=wx.JOIN_MITER,friendlyName='Miter') +PenJoinSet.new(name='wxJOIN_ROUND',value=wx.JOIN_ROUND,friendlyName='Round') + +class PenStyle(enumeration.Enumeration): + """Enumeration representing a pen-drawing style""" + set = PenStyleSet + dataType = enumeration.Enumeration.dataType+'.penstyle' + +class PenCap(enumeration.Enumeration): + """Enumeration representing a pen-cap style""" + set = PenCapSet + dataType = enumeration.Enumeration.dataType+'.pencap' + +class PenJoin(enumeration.Enumeration): + """Enumeration representing a pen-join style""" + set = PenJoinSet + dataType = enumeration.Enumeration.dataType+'.penjoin' + + +##class PenStandIn( propertied.Propertied ): +## """Stand-in object for editing (immutable) wxPen values""" +## style = basic.BasicProperty( +## 'style', """The line style for the pen""", +## friendlyName = """Line Style""", +## baseType = PenStyle, +## defaultValue = 'wxSOLID', +## ) +## cap = basic.BasicProperty( +## 'cap', """The cap (end-of-line) style for the pen""", +## friendlyName = """Cap Style""", +## baseType = PenCap, +## defaultValue = 'wxCAP_ROUND', +## ) +## join = basic.BasicProperty( +## 'join', """The cap (end-of-line) style for the pen""", +## friendlyName = """Join Style""", +## baseType = PenJoin, +## defaultValue = 'wxJOIN_ROUND', +## ) +## colour = common.ColourProperty( +## "colour", """The pen colour""", +## friendlyName = "Colour", +## defaultValue = (0,0,0), +## ) +## width = common.IntegerProperty( +## "width", """The line width of the pen""", +## defaultValue = 1, +## ) + + + + \ No newline at end of file diff --git a/resources/lib/basictypes/wxtypes/wxcopyreg.py b/resources/lib/basictypes/wxtypes/wxcopyreg.py new file mode 100644 index 0000000..807137f --- /dev/null +++ b/resources/lib/basictypes/wxtypes/wxcopyreg.py @@ -0,0 +1,131 @@ +"""wxcopyreg -- functions for storing/restoring simple wxPython data types to pickle-friendly formats + +importing this module installs the functions automatically! +""" +import pickle, zlib +from wxPython.wx import * + +## + + +def bind( classObject, outFunction, inFunction ): + """Bind get and set state for the classObject""" + classObject.__getstate__ = outFunction + classObject.__setstate__ = inFunction + + + +def wxColourOut( value ): + return value.Red(), value.Green(), value.Blue() +def wxColourIn( self, args ): + self.this = apply(gdic.new_wxColour,args) + self.thisown = 1 + +bind( wxColourPtr, wxColourOut, wxColourIn ) + + +def wxFontOut( value ): + return ( + value.GetPointSize(), + value.GetFamily(), + value.GetStyle(), + value.GetWeight(), + value.GetUnderlined(), + value.GetFaceName(), + # note that encoding is missing... + ) +def wxFontIn( self, args ): + self.this = apply(fontsc.new_wxFont,args) + self.thisown = 1 + +bind( wxFontPtr, wxFontOut, wxFontIn ) + + +def wxPenOut( value ): + colour = value.GetColour() + return ( + ( + colour.Red(), + colour.Green(), + colour.Blue() + ), + ( + value.GetWidth(), + value.GetStyle(), + ), + ( + #stipple is a bitmap, we don't currently have + #mechanisms for storing/restoring it, so ignore it +## value.GetStipple(), + value.GetJoin(), + # missing in the current wxPython pre-release + # should be available in wxPython 2.3.3 final +## value.GetDashes(), + value.GetCap(), + ), + ) +def wxPenIn( self, (colour, init, props) ): + colour = wxColour( *colour ) + self.this = apply(gdic.new_wxPen,(colour,)+init) + self.thisown = 1 + for prop, function in map( None, props, ( + #stipple is a bitmap, we don't currently have + #mechanisms for storing/restoring it, so ignore it +## self.SetStipple, + self.SetJoin, + # missing in the current wxPython pre-release + # should be available in wxPython 2.3.3 final +## self.SetDashes, + self.SetCap + )): + function( prop ) + + +def wxPyPenIn( self, (colour, init, props) ): + colour = wxColour( *colour ) + self.this = apply(gdic.new_wxPyPen,(colour,)+init) + self.thisown = 1 + for prop, function in map( None, props, ( + #stipple is a bitmap, we don't currently have + #mechanisms for storing/restoring it, so ignore it +## self.SetStipple, + self.SetJoin, + # missing in the current wxPython pre-release + # should be available in wxPython 2.3.3 final +## self.SetDashes, + self.SetCap + )): + function( prop ) + + +bind( wxPenPtr, wxPenOut, wxPenIn ) +bind( wxPyPenPtr, wxPenOut, wxPyPenIn ) + + +def wxImageOut( value ): + width,height = value.GetWidth(), value.GetHeight() + data = value.GetData() + data = zlib.compress( data ) + return ( width, height, data ) +def wxImageIn( self, (width, height, data) ): + self.this = apply(imagec.wxEmptyImage,(width,height)) + self.thisown = 1 + self.SetData( zlib.decompress( data) ) + +bind( wxImagePtr, wxImageOut, wxImageIn ) + + + +def test(): + for o in [ + wxColour( 23,23,23), + wxFont( 12, wxMODERN, wxNORMAL, wxNORMAL ), + wxPen(wxColour( 23,23,23),1,wxSOLID), + wxImage( 'test.jpg', wxBITMAP_TYPE_ANY ), + ]: + o2 = pickle.loads(pickle.dumps(o)) + print o2 + +if __name__ == "__main__": + wxInitAllImageHandlers() + test() \ No newline at end of file diff --git a/resources/lib/basictypes/xmlgenerator.py b/resources/lib/basictypes/xmlgenerator.py new file mode 100644 index 0000000..73e444a --- /dev/null +++ b/resources/lib/basictypes/xmlgenerator.py @@ -0,0 +1,55 @@ +from xml.sax import saxutils +import locale +defaultEncoding = locale.getdefaultlocale()[-1] + +class Generator( saxutils.XMLGenerator ): + """Friendly generator for XML code""" + def __init__( self, out=None, encoding="utf-8"): + """Initialise the generator + + Just overrides the default encoding of the base-class + """ + super( self, Generator ).__init__( file, encoding ) + def startElement( self, name, attributes=None ): + """Start a new element with given attributes""" + super(Generator,self).startElement( name, self._fixAttributes(attributes) ) + def _fixAttributes( self, attributes=None ): + """Fix an attribute-set to be all unicode strings""" + if attributes is None: + attributes = {} + for key,value in attributes.items(): + if not isinstance( value, (str,unicode)): + attributes[key] = unicode( value ) + elif isinstance( value, str ): + attributes[key] = value.decode( defaultEncoding ) + + +class Store( Generator ): + """Store a set of objects to an XML representation""" + def __init__( self, *arguments, **named ): + """Initialise the store""" + super( Store, self ).__init__( *arguments, **named ) + self.classMapping = { + } + self.rClassMapping = { + } + self.todo = [] + self.alreadyDone = {} + def classToElementName( self, classObject ): + """Get the element name for a given object""" + name = classObject.__name__ + if self.rClassMapping.has_key( name ): + return self.rClassMapping.get( name ) + short = name.split('.')[-1] + count = 2 + while self.classMapping.has_key( short ): + short = short + str(count) + count += 1 + self.classMapping[ short ] = name + self.rClassMapping[ name ] = short + return short + def encodeInAttributes( self, property, client ): + """Determine whether to encode this property as an element attribute""" + def handleObject( self, object ): + """Produce code for a single object""" + diff --git a/resources/lib/gui.py b/resources/lib/gui.py new file mode 100644 index 0000000..52851d5 --- /dev/null +++ b/resources/lib/gui.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- + +import os +import sys +import base64 +import xbmc +import xbmcgui +import transmissionrpc +from basictypes.bytes import Bytes +from repeater import Repeater + +_ = sys.modules[ "__main__" ].__language__ +__settings__ = xbmc.Settings(path=os.getcwd()) + +KEY_BUTTON_BACK = 275 +KEY_KEYBOARD_ESC = 61467 + +class TransmissionGUI(xbmcgui.WindowXMLDialog): + def __init__(self, strXMLname, strFallbackPath, strDefaultName, bforeFallback=0): + params = { + 'address': __settings__.getSetting('rpc_host'), + 'port': __settings__.getSetting('rpc_port'), + 'user': __settings__.getSetting('rpc_user'), + 'password': __settings__.getSetting('rpc_password') + } + self.transmission = transmissionrpc.transmission.Client(**params) + self.list = {} + self.torrents = {} + def onInit(self): + self.updateTorrents() + self.repeater = Repeater(1.0, self.updateTorrents) + self.repeater.start() + def shutDown(self): + print "terminating repeater" + self.repeater.stop() + print "closing transmission gui" + self.close() + def updateTorrents(self): + list = self.getControl(20) + torrents = self.transmission.info() + for i, torrent in torrents.iteritems(): + statusline = "[%(status)s] %(down)s down (%(pct).2f%%), %(up)s up (Ratio: %(ratio).2f)" % \ + {'down': Bytes.format(torrent.downloadedEver), 'pct': torrent.progress, \ + 'up': Bytes.format(torrent.uploadedEver), 'ratio': torrent.ratio, \ + 'status': torrent.status} + if torrent.status is 'downloading': + statusline += " ETA: %(eta)s" % \ + {'eta': torrent.eta} + if i not in self.list: + # Create a new list item + l = xbmcgui.ListItem(label=torrent.name, label2=statusline) + list.addItem(l) + self.list[i] = l + else: + # Update existing list item + l = self.list[i] + self.torrents = torrents + l.setLabel(torrent.name) + l.setLabel2(statusline) + l.setProperty('TorrentID', str(i)) + l.setProperty('TorrentProgress', "%.2ff" % torrent.progress) + l.setInfo('torrent', torrent.fields) + l.setInfo('video', {'episode': int(torrent.progress)}) + + removed = [id for id in self.list.keys() if id not in torrents.keys()] + if len(removed) > 0: + # Clear torrents from the list that have been removed + for id in removed: + del self.list[id] + list.reset() + for id, item in self.list.iteritems(): + list.addItem(item) + def onAction(self, action): + buttonCode = action.getButtonCode() + actionID = action.getId() + if (buttonCode == KEY_BUTTON_BACK or buttonCode == KEY_KEYBOARD_ESC): + self.shutDown() + def onClick(self, controlID): + list = self.getControl(20) + if (controlID == 11): + # Add torrent + d = xbmcgui.Dialog() + f = d.browse(1, _(0), 'files', '.torrent') + self.transmission.add_url(f) + if (controlID == 12): + # Remove selected torrent + item = list.getSelectedItem() + if item and xbmcgui.Dialog().yesno(_(0), 'Remove \'%s\'?' % self.torrents[int(item.getProperty('TorrentID'))].name): + remove_data = xbmcgui.Dialog().yesno(_(0), 'Remove data as well?') + self.transmission.remove(int(item.getProperty('TorrentID')), remove_data) + if (controlID == 13): + # Stop selected torrent + item = list.getSelectedItem() + if item: + self.transmission.stop(int(item.getProperty('TorrentID'))) + if (controlID == 14): + # Start selected torrent + item = list.getSelectedItem() + if item: + t = int(item.getProperty('TorrentID')) + self.transmission.start(int(item.getProperty('TorrentID'))) + if (controlID == 15): + # Stop all torrents + self.transmission.stop(self.torrents.keys()) + if (controlID == 16): + # Start all torrents + self.transmission.start(self.torrents.keys()) + if (controlID == 17): + # Exit button + self.shutDown() + if (controlID == 20): + return + # A torrent was chosen, show details + item = list.getSelectedItem() + w = TorrentInfoGUI("script-Transmission-main.xml",os.getcwd() ,"default") + w.setTorrent(int(item.getProperty('TorrentID'))) + w.doModal() + del w + def onFocus(self, controlID): + pass + +class TorrentInfoGUI(xbmcgui.WindowXMLDialog): + def __init__(self, strXMLname, strFallbackPath, strDefaultName, bforeFallback=0): + self.torrent_id = None + pass + def setTorrent(t_id): + self.torrent_id = t_id + def onInit(self): + pass + def onAction(self, action): + buttonCode = action.getButtonCode() + actionID = action.getId() + if (buttonCode == KEY_BUTTON_BACK or buttonCode == KEY_KEYBOARD_ESC): + self.close() + def onClick(self, controlID): + pass + def onFocus(self, controlID): + pass \ No newline at end of file diff --git a/resources/lib/repeater.py b/resources/lib/repeater.py new file mode 100644 index 0000000..c7a8fbc --- /dev/null +++ b/resources/lib/repeater.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- + +import threading +import time + +class Repeater: + def __init__(self, interval, action, arguments = []): + self.interval = interval + self.action = action + self.arguments = arguments + self.event = None + def start(self): + if self.event: + return + self.event = threading.Event() + self.thread = threading.Thread(target=Repeater.repeat, args=(self.event, self.interval, self.action, self.arguments)) + self.thread.start() + def stop(self): + if not self.event: + return + self.event.set() + self.thread.join() + self.event = None + def repeat(cls, event, interval, action, arguments = []): + while True: + event.wait(interval) + if event.isSet(): + break; + action(*arguments) + repeat = classmethod(repeat) + + + +if __name__ == '__main__': + def foo(a, b): + print a, b + + r = Repeater(1.0, foo, ['foo', 'bar']) + r.start() + time.sleep(10) + r.stop() \ No newline at end of file diff --git a/resources/lib/simplejson/__init__.py b/resources/lib/simplejson/__init__.py new file mode 100644 index 0000000..d5b4d39 --- /dev/null +++ b/resources/lib/simplejson/__init__.py @@ -0,0 +1,318 @@ +r"""JSON (JavaScript Object Notation) is a subset of +JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data +interchange format. + +:mod:`simplejson` exposes an API familiar to users of the standard library +:mod:`marshal` and :mod:`pickle` modules. It is the externally maintained +version of the :mod:`json` library contained in Python 2.6, but maintains +compatibility with Python 2.4 and Python 2.5 and (currently) has +significant performance advantages, even without using the optional C +extension for speedups. + +Encoding basic Python object hierarchies:: + + >>> import simplejson as json + >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}]) + '["foo", {"bar": ["baz", null, 1.0, 2]}]' + >>> print json.dumps("\"foo\bar") + "\"foo\bar" + >>> print json.dumps(u'\u1234') + "\u1234" + >>> print json.dumps('\\') + "\\" + >>> print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True) + {"a": 0, "b": 0, "c": 0} + >>> from StringIO import StringIO + >>> io = StringIO() + >>> json.dump(['streaming API'], io) + >>> io.getvalue() + '["streaming API"]' + +Compact encoding:: + + >>> import simplejson as json + >>> json.dumps([1,2,3,{'4': 5, '6': 7}], separators=(',',':')) + '[1,2,3,{"4":5,"6":7}]' + +Pretty printing:: + + >>> import simplejson as json + >>> s = json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=4) + >>> print '\n'.join([l.rstrip() for l in s.splitlines()]) + { + "4": 5, + "6": 7 + } + +Decoding JSON:: + + >>> import simplejson as json + >>> obj = [u'foo', {u'bar': [u'baz', None, 1.0, 2]}] + >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj + True + >>> json.loads('"\\"foo\\bar"') == u'"foo\x08ar' + True + >>> from StringIO import StringIO + >>> io = StringIO('["streaming API"]') + >>> json.load(io)[0] == 'streaming API' + True + +Specializing JSON object decoding:: + + >>> import simplejson as json + >>> def as_complex(dct): + ... if '__complex__' in dct: + ... return complex(dct['real'], dct['imag']) + ... return dct + ... + >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}', + ... object_hook=as_complex) + (1+2j) + >>> import decimal + >>> json.loads('1.1', parse_float=decimal.Decimal) == decimal.Decimal('1.1') + True + +Specializing JSON object encoding:: + + >>> import simplejson as json + >>> def encode_complex(obj): + ... if isinstance(obj, complex): + ... return [obj.real, obj.imag] + ... raise TypeError(repr(o) + " is not JSON serializable") + ... + >>> json.dumps(2 + 1j, default=encode_complex) + '[2.0, 1.0]' + >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j) + '[2.0, 1.0]' + >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j)) + '[2.0, 1.0]' + + +Using simplejson.tool from the shell to validate and pretty-print:: + + $ echo '{"json":"obj"}' | python -m simplejson.tool + { + "json": "obj" + } + $ echo '{ 1.2:3.4}' | python -m simplejson.tool + Expecting property name: line 1 column 2 (char 2) +""" +__version__ = '2.0.9' +__all__ = [ + 'dump', 'dumps', 'load', 'loads', + 'JSONDecoder', 'JSONEncoder', +] + +__author__ = 'Bob Ippolito ' + +from decoder import JSONDecoder +from encoder import JSONEncoder + +_default_encoder = JSONEncoder( + skipkeys=False, + ensure_ascii=True, + check_circular=True, + allow_nan=True, + indent=None, + separators=None, + encoding='utf-8', + default=None, +) + +def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, + allow_nan=True, cls=None, indent=None, separators=None, + encoding='utf-8', default=None, **kw): + """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a + ``.write()``-supporting file-like object). + + If ``skipkeys`` is true then ``dict`` keys that are not basic types + (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) + will be skipped instead of raising a ``TypeError``. + + If ``ensure_ascii`` is false, then the some chunks written to ``fp`` + may be ``unicode`` instances, subject to normal Python ``str`` to + ``unicode`` coercion rules. Unless ``fp.write()`` explicitly + understands ``unicode`` (as in ``codecs.getwriter()``) this is likely + to cause an error. + + If ``check_circular`` is false, then the circular reference check + for container types will be skipped and a circular reference will + result in an ``OverflowError`` (or worse). + + If ``allow_nan`` is false, then it will be a ``ValueError`` to + serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) + in strict compliance of the JSON specification, instead of using the + JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). + + If ``indent`` is a non-negative integer, then JSON array elements and object + members will be pretty-printed with that indent level. An indent level + of 0 will only insert newlines. ``None`` is the most compact representation. + + If ``separators`` is an ``(item_separator, dict_separator)`` tuple + then it will be used instead of the default ``(', ', ': ')`` separators. + ``(',', ':')`` is the most compact JSON representation. + + ``encoding`` is the character encoding for str instances, default is UTF-8. + + ``default(obj)`` is a function that should return a serializable version + of obj or raise TypeError. The default simply raises TypeError. + + To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the + ``.default()`` method to serialize additional types), specify it with + the ``cls`` kwarg. + + """ + # cached encoder + if (not skipkeys and ensure_ascii and + check_circular and allow_nan and + cls is None and indent is None and separators is None and + encoding == 'utf-8' and default is None and not kw): + iterable = _default_encoder.iterencode(obj) + else: + if cls is None: + cls = JSONEncoder + iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii, + check_circular=check_circular, allow_nan=allow_nan, indent=indent, + separators=separators, encoding=encoding, + default=default, **kw).iterencode(obj) + # could accelerate with writelines in some versions of Python, at + # a debuggability cost + for chunk in iterable: + fp.write(chunk) + + +def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, + allow_nan=True, cls=None, indent=None, separators=None, + encoding='utf-8', default=None, **kw): + """Serialize ``obj`` to a JSON formatted ``str``. + + If ``skipkeys`` is false then ``dict`` keys that are not basic types + (``str``, ``unicode``, ``int``, ``long``, ``float``, ``bool``, ``None``) + will be skipped instead of raising a ``TypeError``. + + If ``ensure_ascii`` is false, then the return value will be a + ``unicode`` instance subject to normal Python ``str`` to ``unicode`` + coercion rules instead of being escaped to an ASCII ``str``. + + If ``check_circular`` is false, then the circular reference check + for container types will be skipped and a circular reference will + result in an ``OverflowError`` (or worse). + + If ``allow_nan`` is false, then it will be a ``ValueError`` to + serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in + strict compliance of the JSON specification, instead of using the + JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). + + If ``indent`` is a non-negative integer, then JSON array elements and + object members will be pretty-printed with that indent level. An indent + level of 0 will only insert newlines. ``None`` is the most compact + representation. + + If ``separators`` is an ``(item_separator, dict_separator)`` tuple + then it will be used instead of the default ``(', ', ': ')`` separators. + ``(',', ':')`` is the most compact JSON representation. + + ``encoding`` is the character encoding for str instances, default is UTF-8. + + ``default(obj)`` is a function that should return a serializable version + of obj or raise TypeError. The default simply raises TypeError. + + To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the + ``.default()`` method to serialize additional types), specify it with + the ``cls`` kwarg. + + """ + # cached encoder + if (not skipkeys and ensure_ascii and + check_circular and allow_nan and + cls is None and indent is None and separators is None and + encoding == 'utf-8' and default is None and not kw): + return _default_encoder.encode(obj) + if cls is None: + cls = JSONEncoder + return cls( + skipkeys=skipkeys, ensure_ascii=ensure_ascii, + check_circular=check_circular, allow_nan=allow_nan, indent=indent, + separators=separators, encoding=encoding, default=default, + **kw).encode(obj) + + +_default_decoder = JSONDecoder(encoding=None, object_hook=None) + + +def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None, + parse_int=None, parse_constant=None, **kw): + """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing + a JSON document) to a Python object. + + If the contents of ``fp`` is encoded with an ASCII based encoding other + than utf-8 (e.g. latin-1), then an appropriate ``encoding`` name must + be specified. Encodings that are not ASCII based (such as UCS-2) are + not allowed, and should be wrapped with + ``codecs.getreader(fp)(encoding)``, or simply decoded to a ``unicode`` + object and passed to ``loads()`` + + ``object_hook`` is an optional function that will be called with the + result of any object literal decode (a ``dict``). The return value of + ``object_hook`` will be used instead of the ``dict``. This feature + can be used to implement custom decoders (e.g. JSON-RPC class hinting). + + To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` + kwarg. + + """ + return loads(fp.read(), + encoding=encoding, cls=cls, object_hook=object_hook, + parse_float=parse_float, parse_int=parse_int, + parse_constant=parse_constant, **kw) + + +def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, + parse_int=None, parse_constant=None, **kw): + """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON + document) to a Python object. + + If ``s`` is a ``str`` instance and is encoded with an ASCII based encoding + other than utf-8 (e.g. latin-1) then an appropriate ``encoding`` name + must be specified. Encodings that are not ASCII based (such as UCS-2) + are not allowed and should be decoded to ``unicode`` first. + + ``object_hook`` is an optional function that will be called with the + result of any object literal decode (a ``dict``). The return value of + ``object_hook`` will be used instead of the ``dict``. This feature + can be used to implement custom decoders (e.g. JSON-RPC class hinting). + + ``parse_float``, if specified, will be called with the string + of every JSON float to be decoded. By default this is equivalent to + float(num_str). This can be used to use another datatype or parser + for JSON floats (e.g. decimal.Decimal). + + ``parse_int``, if specified, will be called with the string + of every JSON int to be decoded. By default this is equivalent to + int(num_str). This can be used to use another datatype or parser + for JSON integers (e.g. float). + + ``parse_constant``, if specified, will be called with one of the + following strings: -Infinity, Infinity, NaN, null, true, false. + This can be used to raise an exception if invalid JSON numbers + are encountered. + + To use a custom ``JSONDecoder`` subclass, specify it with the ``cls`` + kwarg. + + """ + if (cls is None and encoding is None and object_hook is None and + parse_int is None and parse_float is None and + parse_constant is None and not kw): + return _default_decoder.decode(s) + if cls is None: + cls = JSONDecoder + if object_hook is not None: + kw['object_hook'] = object_hook + if parse_float is not None: + kw['parse_float'] = parse_float + if parse_int is not None: + kw['parse_int'] = parse_int + if parse_constant is not None: + kw['parse_constant'] = parse_constant + return cls(encoding=encoding, **kw).decode(s) diff --git a/resources/lib/simplejson/_speedups.c b/resources/lib/simplejson/_speedups.c new file mode 100644 index 0000000..23b5f4a --- /dev/null +++ b/resources/lib/simplejson/_speedups.c @@ -0,0 +1,2329 @@ +#include "Python.h" +#include "structmember.h" +#if PY_VERSION_HEX < 0x02060000 && !defined(Py_TYPE) +#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) +#endif +#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) +typedef int Py_ssize_t; +#define PY_SSIZE_T_MAX INT_MAX +#define PY_SSIZE_T_MIN INT_MIN +#define PyInt_FromSsize_t PyInt_FromLong +#define PyInt_AsSsize_t PyInt_AsLong +#endif +#ifndef Py_IS_FINITE +#define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X)) +#endif + +#ifdef __GNUC__ +#define UNUSED __attribute__((__unused__)) +#else +#define UNUSED +#endif + +#define DEFAULT_ENCODING "utf-8" + +#define PyScanner_Check(op) PyObject_TypeCheck(op, &PyScannerType) +#define PyScanner_CheckExact(op) (Py_TYPE(op) == &PyScannerType) +#define PyEncoder_Check(op) PyObject_TypeCheck(op, &PyEncoderType) +#define PyEncoder_CheckExact(op) (Py_TYPE(op) == &PyEncoderType) + +static PyTypeObject PyScannerType; +static PyTypeObject PyEncoderType; + +typedef struct _PyScannerObject { + PyObject_HEAD + PyObject *encoding; + PyObject *strict; + PyObject *object_hook; + PyObject *parse_float; + PyObject *parse_int; + PyObject *parse_constant; +} PyScannerObject; + +static PyMemberDef scanner_members[] = { + {"encoding", T_OBJECT, offsetof(PyScannerObject, encoding), READONLY, "encoding"}, + {"strict", T_OBJECT, offsetof(PyScannerObject, strict), READONLY, "strict"}, + {"object_hook", T_OBJECT, offsetof(PyScannerObject, object_hook), READONLY, "object_hook"}, + {"parse_float", T_OBJECT, offsetof(PyScannerObject, parse_float), READONLY, "parse_float"}, + {"parse_int", T_OBJECT, offsetof(PyScannerObject, parse_int), READONLY, "parse_int"}, + {"parse_constant", T_OBJECT, offsetof(PyScannerObject, parse_constant), READONLY, "parse_constant"}, + {NULL} +}; + +typedef struct _PyEncoderObject { + PyObject_HEAD + PyObject *markers; + PyObject *defaultfn; + PyObject *encoder; + PyObject *indent; + PyObject *key_separator; + PyObject *item_separator; + PyObject *sort_keys; + PyObject *skipkeys; + int fast_encode; + int allow_nan; +} PyEncoderObject; + +static PyMemberDef encoder_members[] = { + {"markers", T_OBJECT, offsetof(PyEncoderObject, markers), READONLY, "markers"}, + {"default", T_OBJECT, offsetof(PyEncoderObject, defaultfn), READONLY, "default"}, + {"encoder", T_OBJECT, offsetof(PyEncoderObject, encoder), READONLY, "encoder"}, + {"indent", T_OBJECT, offsetof(PyEncoderObject, indent), READONLY, "indent"}, + {"key_separator", T_OBJECT, offsetof(PyEncoderObject, key_separator), READONLY, "key_separator"}, + {"item_separator", T_OBJECT, offsetof(PyEncoderObject, item_separator), READONLY, "item_separator"}, + {"sort_keys", T_OBJECT, offsetof(PyEncoderObject, sort_keys), READONLY, "sort_keys"}, + {"skipkeys", T_OBJECT, offsetof(PyEncoderObject, skipkeys), READONLY, "skipkeys"}, + {NULL} +}; + +static Py_ssize_t +ascii_escape_char(Py_UNICODE c, char *output, Py_ssize_t chars); +static PyObject * +ascii_escape_unicode(PyObject *pystr); +static PyObject * +ascii_escape_str(PyObject *pystr); +static PyObject * +py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr); +void init_speedups(void); +static PyObject * +scan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr); +static PyObject * +scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr); +static PyObject * +_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx); +static PyObject * +scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +static int +scanner_init(PyObject *self, PyObject *args, PyObject *kwds); +static void +scanner_dealloc(PyObject *self); +static int +scanner_clear(PyObject *self); +static PyObject * +encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +static int +encoder_init(PyObject *self, PyObject *args, PyObject *kwds); +static void +encoder_dealloc(PyObject *self); +static int +encoder_clear(PyObject *self); +static int +encoder_listencode_list(PyEncoderObject *s, PyObject *rval, PyObject *seq, Py_ssize_t indent_level); +static int +encoder_listencode_obj(PyEncoderObject *s, PyObject *rval, PyObject *obj, Py_ssize_t indent_level); +static int +encoder_listencode_dict(PyEncoderObject *s, PyObject *rval, PyObject *dct, Py_ssize_t indent_level); +static PyObject * +_encoded_const(PyObject *const); +static void +raise_errmsg(char *msg, PyObject *s, Py_ssize_t end); +static PyObject * +encoder_encode_string(PyEncoderObject *s, PyObject *obj); +static int +_convertPyInt_AsSsize_t(PyObject *o, Py_ssize_t *size_ptr); +static PyObject * +_convertPyInt_FromSsize_t(Py_ssize_t *size_ptr); +static PyObject * +encoder_encode_float(PyEncoderObject *s, PyObject *obj); + +#define S_CHAR(c) (c >= ' ' && c <= '~' && c != '\\' && c != '"') +#define IS_WHITESPACE(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r')) + +#define MIN_EXPANSION 6 +#ifdef Py_UNICODE_WIDE +#define MAX_EXPANSION (2 * MIN_EXPANSION) +#else +#define MAX_EXPANSION MIN_EXPANSION +#endif + +static int +_convertPyInt_AsSsize_t(PyObject *o, Py_ssize_t *size_ptr) +{ + /* PyObject to Py_ssize_t converter */ + *size_ptr = PyInt_AsSsize_t(o); + if (*size_ptr == -1 && PyErr_Occurred()); + return 1; + return 0; +} + +static PyObject * +_convertPyInt_FromSsize_t(Py_ssize_t *size_ptr) +{ + /* Py_ssize_t to PyObject converter */ + return PyInt_FromSsize_t(*size_ptr); +} + +static Py_ssize_t +ascii_escape_char(Py_UNICODE c, char *output, Py_ssize_t chars) +{ + /* Escape unicode code point c to ASCII escape sequences + in char *output. output must have at least 12 bytes unused to + accommodate an escaped surrogate pair "\uXXXX\uXXXX" */ + output[chars++] = '\\'; + switch (c) { + case '\\': output[chars++] = (char)c; break; + case '"': output[chars++] = (char)c; break; + case '\b': output[chars++] = 'b'; break; + case '\f': output[chars++] = 'f'; break; + case '\n': output[chars++] = 'n'; break; + case '\r': output[chars++] = 'r'; break; + case '\t': output[chars++] = 't'; break; + default: +#ifdef Py_UNICODE_WIDE + if (c >= 0x10000) { + /* UTF-16 surrogate pair */ + Py_UNICODE v = c - 0x10000; + c = 0xd800 | ((v >> 10) & 0x3ff); + output[chars++] = 'u'; + output[chars++] = "0123456789abcdef"[(c >> 12) & 0xf]; + output[chars++] = "0123456789abcdef"[(c >> 8) & 0xf]; + output[chars++] = "0123456789abcdef"[(c >> 4) & 0xf]; + output[chars++] = "0123456789abcdef"[(c ) & 0xf]; + c = 0xdc00 | (v & 0x3ff); + output[chars++] = '\\'; + } +#endif + output[chars++] = 'u'; + output[chars++] = "0123456789abcdef"[(c >> 12) & 0xf]; + output[chars++] = "0123456789abcdef"[(c >> 8) & 0xf]; + output[chars++] = "0123456789abcdef"[(c >> 4) & 0xf]; + output[chars++] = "0123456789abcdef"[(c ) & 0xf]; + } + return chars; +} + +static PyObject * +ascii_escape_unicode(PyObject *pystr) +{ + /* Take a PyUnicode pystr and return a new ASCII-only escaped PyString */ + Py_ssize_t i; + Py_ssize_t input_chars; + Py_ssize_t output_size; + Py_ssize_t max_output_size; + Py_ssize_t chars; + PyObject *rval; + char *output; + Py_UNICODE *input_unicode; + + input_chars = PyUnicode_GET_SIZE(pystr); + input_unicode = PyUnicode_AS_UNICODE(pystr); + + /* One char input can be up to 6 chars output, estimate 4 of these */ + output_size = 2 + (MIN_EXPANSION * 4) + input_chars; + max_output_size = 2 + (input_chars * MAX_EXPANSION); + rval = PyString_FromStringAndSize(NULL, output_size); + if (rval == NULL) { + return NULL; + } + output = PyString_AS_STRING(rval); + chars = 0; + output[chars++] = '"'; + for (i = 0; i < input_chars; i++) { + Py_UNICODE c = input_unicode[i]; + if (S_CHAR(c)) { + output[chars++] = (char)c; + } + else { + chars = ascii_escape_char(c, output, chars); + } + if (output_size - chars < (1 + MAX_EXPANSION)) { + /* There's more than four, so let's resize by a lot */ + Py_ssize_t new_output_size = output_size * 2; + /* This is an upper bound */ + if (new_output_size > max_output_size) { + new_output_size = max_output_size; + } + /* Make sure that the output size changed before resizing */ + if (new_output_size != output_size) { + output_size = new_output_size; + if (_PyString_Resize(&rval, output_size) == -1) { + return NULL; + } + output = PyString_AS_STRING(rval); + } + } + } + output[chars++] = '"'; + if (_PyString_Resize(&rval, chars) == -1) { + return NULL; + } + return rval; +} + +static PyObject * +ascii_escape_str(PyObject *pystr) +{ + /* Take a PyString pystr and return a new ASCII-only escaped PyString */ + Py_ssize_t i; + Py_ssize_t input_chars; + Py_ssize_t output_size; + Py_ssize_t chars; + PyObject *rval; + char *output; + char *input_str; + + input_chars = PyString_GET_SIZE(pystr); + input_str = PyString_AS_STRING(pystr); + + /* Fast path for a string that's already ASCII */ + for (i = 0; i < input_chars; i++) { + Py_UNICODE c = (Py_UNICODE)(unsigned char)input_str[i]; + if (!S_CHAR(c)) { + /* If we have to escape something, scan the string for unicode */ + Py_ssize_t j; + for (j = i; j < input_chars; j++) { + c = (Py_UNICODE)(unsigned char)input_str[j]; + if (c > 0x7f) { + /* We hit a non-ASCII character, bail to unicode mode */ + PyObject *uni; + uni = PyUnicode_DecodeUTF8(input_str, input_chars, "strict"); + if (uni == NULL) { + return NULL; + } + rval = ascii_escape_unicode(uni); + Py_DECREF(uni); + return rval; + } + } + break; + } + } + + if (i == input_chars) { + /* Input is already ASCII */ + output_size = 2 + input_chars; + } + else { + /* One char input can be up to 6 chars output, estimate 4 of these */ + output_size = 2 + (MIN_EXPANSION * 4) + input_chars; + } + rval = PyString_FromStringAndSize(NULL, output_size); + if (rval == NULL) { + return NULL; + } + output = PyString_AS_STRING(rval); + output[0] = '"'; + + /* We know that everything up to i is ASCII already */ + chars = i + 1; + memcpy(&output[1], input_str, i); + + for (; i < input_chars; i++) { + Py_UNICODE c = (Py_UNICODE)(unsigned char)input_str[i]; + if (S_CHAR(c)) { + output[chars++] = (char)c; + } + else { + chars = ascii_escape_char(c, output, chars); + } + /* An ASCII char can't possibly expand to a surrogate! */ + if (output_size - chars < (1 + MIN_EXPANSION)) { + /* There's more than four, so let's resize by a lot */ + output_size *= 2; + if (output_size > 2 + (input_chars * MIN_EXPANSION)) { + output_size = 2 + (input_chars * MIN_EXPANSION); + } + if (_PyString_Resize(&rval, output_size) == -1) { + return NULL; + } + output = PyString_AS_STRING(rval); + } + } + output[chars++] = '"'; + if (_PyString_Resize(&rval, chars) == -1) { + return NULL; + } + return rval; +} + +static void +raise_errmsg(char *msg, PyObject *s, Py_ssize_t end) +{ + /* Use the Python function simplejson.decoder.errmsg to raise a nice + looking ValueError exception */ + static PyObject *errmsg_fn = NULL; + PyObject *pymsg; + if (errmsg_fn == NULL) { + PyObject *decoder = PyImport_ImportModule("simplejson.decoder"); + if (decoder == NULL) + return; + errmsg_fn = PyObject_GetAttrString(decoder, "errmsg"); + Py_DECREF(decoder); + if (errmsg_fn == NULL) + return; + } + pymsg = PyObject_CallFunction(errmsg_fn, "(zOO&)", msg, s, _convertPyInt_FromSsize_t, &end); + if (pymsg) { + PyErr_SetObject(PyExc_ValueError, pymsg); + Py_DECREF(pymsg); + } +} + +static PyObject * +join_list_unicode(PyObject *lst) +{ + /* return u''.join(lst) */ + static PyObject *joinfn = NULL; + if (joinfn == NULL) { + PyObject *ustr = PyUnicode_FromUnicode(NULL, 0); + if (ustr == NULL) + return NULL; + + joinfn = PyObject_GetAttrString(ustr, "join"); + Py_DECREF(ustr); + if (joinfn == NULL) + return NULL; + } + return PyObject_CallFunctionObjArgs(joinfn, lst, NULL); +} + +static PyObject * +join_list_string(PyObject *lst) +{ + /* return ''.join(lst) */ + static PyObject *joinfn = NULL; + if (joinfn == NULL) { + PyObject *ustr = PyString_FromStringAndSize(NULL, 0); + if (ustr == NULL) + return NULL; + + joinfn = PyObject_GetAttrString(ustr, "join"); + Py_DECREF(ustr); + if (joinfn == NULL) + return NULL; + } + return PyObject_CallFunctionObjArgs(joinfn, lst, NULL); +} + +static PyObject * +_build_rval_index_tuple(PyObject *rval, Py_ssize_t idx) { + /* return (rval, idx) tuple, stealing reference to rval */ + PyObject *tpl; + PyObject *pyidx; + /* + steal a reference to rval, returns (rval, idx) + */ + if (rval == NULL) { + return NULL; + } + pyidx = PyInt_FromSsize_t(idx); + if (pyidx == NULL) { + Py_DECREF(rval); + return NULL; + } + tpl = PyTuple_New(2); + if (tpl == NULL) { + Py_DECREF(pyidx); + Py_DECREF(rval); + return NULL; + } + PyTuple_SET_ITEM(tpl, 0, rval); + PyTuple_SET_ITEM(tpl, 1, pyidx); + return tpl; +} + +static PyObject * +scanstring_str(PyObject *pystr, Py_ssize_t end, char *encoding, int strict, Py_ssize_t *next_end_ptr) +{ + /* Read the JSON string from PyString pystr. + end is the index of the first character after the quote. + encoding is the encoding of pystr (must be an ASCII superset) + if strict is zero then literal control characters are allowed + *next_end_ptr is a return-by-reference index of the character + after the end quote + + Return value is a new PyString (if ASCII-only) or PyUnicode + */ + PyObject *rval; + Py_ssize_t len = PyString_GET_SIZE(pystr); + Py_ssize_t begin = end - 1; + Py_ssize_t next = begin; + int has_unicode = 0; + char *buf = PyString_AS_STRING(pystr); + PyObject *chunks = PyList_New(0); + if (chunks == NULL) { + goto bail; + } + if (end < 0 || len <= end) { + PyErr_SetString(PyExc_ValueError, "end is out of bounds"); + goto bail; + } + while (1) { + /* Find the end of the string or the next escape */ + Py_UNICODE c = 0; + PyObject *chunk = NULL; + for (next = end; next < len; next++) { + c = (unsigned char)buf[next]; + if (c == '"' || c == '\\') { + break; + } + else if (strict && c <= 0x1f) { + raise_errmsg("Invalid control character at", pystr, next); + goto bail; + } + else if (c > 0x7f) { + has_unicode = 1; + } + } + if (!(c == '"' || c == '\\')) { + raise_errmsg("Unterminated string starting at", pystr, begin); + goto bail; + } + /* Pick up this chunk if it's not zero length */ + if (next != end) { + PyObject *strchunk = PyString_FromStringAndSize(&buf[end], next - end); + if (strchunk == NULL) { + goto bail; + } + if (has_unicode) { + chunk = PyUnicode_FromEncodedObject(strchunk, encoding, NULL); + Py_DECREF(strchunk); + if (chunk == NULL) { + goto bail; + } + } + else { + chunk = strchunk; + } + if (PyList_Append(chunks, chunk)) { + Py_DECREF(chunk); + goto bail; + } + Py_DECREF(chunk); + } + next++; + if (c == '"') { + end = next; + break; + } + if (next == len) { + raise_errmsg("Unterminated string starting at", pystr, begin); + goto bail; + } + c = buf[next]; + if (c != 'u') { + /* Non-unicode backslash escapes */ + end = next + 1; + switch (c) { + case '"': break; + case '\\': break; + case '/': break; + case 'b': c = '\b'; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + default: c = 0; + } + if (c == 0) { + raise_errmsg("Invalid \\escape", pystr, end - 2); + goto bail; + } + } + else { + c = 0; + next++; + end = next + 4; + if (end >= len) { + raise_errmsg("Invalid \\uXXXX escape", pystr, next - 1); + goto bail; + } + /* Decode 4 hex digits */ + for (; next < end; next++) { + Py_UNICODE digit = buf[next]; + c <<= 4; + switch (digit) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + c |= (digit - '0'); break; + case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': + c |= (digit - 'a' + 10); break; + case 'A': case 'B': case 'C': case 'D': case 'E': + case 'F': + c |= (digit - 'A' + 10); break; + default: + raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5); + goto bail; + } + } +#ifdef Py_UNICODE_WIDE + /* Surrogate pair */ + if ((c & 0xfc00) == 0xd800) { + Py_UNICODE c2 = 0; + if (end + 6 >= len) { + raise_errmsg("Unpaired high surrogate", pystr, end - 5); + goto bail; + } + if (buf[next++] != '\\' || buf[next++] != 'u') { + raise_errmsg("Unpaired high surrogate", pystr, end - 5); + goto bail; + } + end += 6; + /* Decode 4 hex digits */ + for (; next < end; next++) { + c2 <<= 4; + Py_UNICODE digit = buf[next]; + switch (digit) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + c2 |= (digit - '0'); break; + case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': + c2 |= (digit - 'a' + 10); break; + case 'A': case 'B': case 'C': case 'D': case 'E': + case 'F': + c2 |= (digit - 'A' + 10); break; + default: + raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5); + goto bail; + } + } + if ((c2 & 0xfc00) != 0xdc00) { + raise_errmsg("Unpaired high surrogate", pystr, end - 5); + goto bail; + } + c = 0x10000 + (((c - 0xd800) << 10) | (c2 - 0xdc00)); + } + else if ((c & 0xfc00) == 0xdc00) { + raise_errmsg("Unpaired low surrogate", pystr, end - 5); + goto bail; + } +#endif + } + if (c > 0x7f) { + has_unicode = 1; + } + if (has_unicode) { + chunk = PyUnicode_FromUnicode(&c, 1); + if (chunk == NULL) { + goto bail; + } + } + else { + char c_char = Py_CHARMASK(c); + chunk = PyString_FromStringAndSize(&c_char, 1); + if (chunk == NULL) { + goto bail; + } + } + if (PyList_Append(chunks, chunk)) { + Py_DECREF(chunk); + goto bail; + } + Py_DECREF(chunk); + } + + rval = join_list_string(chunks); + if (rval == NULL) { + goto bail; + } + Py_CLEAR(chunks); + *next_end_ptr = end; + return rval; +bail: + *next_end_ptr = -1; + Py_XDECREF(chunks); + return NULL; +} + + +static PyObject * +scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next_end_ptr) +{ + /* Read the JSON string from PyUnicode pystr. + end is the index of the first character after the quote. + if strict is zero then literal control characters are allowed + *next_end_ptr is a return-by-reference index of the character + after the end quote + + Return value is a new PyUnicode + */ + PyObject *rval; + Py_ssize_t len = PyUnicode_GET_SIZE(pystr); + Py_ssize_t begin = end - 1; + Py_ssize_t next = begin; + const Py_UNICODE *buf = PyUnicode_AS_UNICODE(pystr); + PyObject *chunks = PyList_New(0); + if (chunks == NULL) { + goto bail; + } + if (end < 0 || len <= end) { + PyErr_SetString(PyExc_ValueError, "end is out of bounds"); + goto bail; + } + while (1) { + /* Find the end of the string or the next escape */ + Py_UNICODE c = 0; + PyObject *chunk = NULL; + for (next = end; next < len; next++) { + c = buf[next]; + if (c == '"' || c == '\\') { + break; + } + else if (strict && c <= 0x1f) { + raise_errmsg("Invalid control character at", pystr, next); + goto bail; + } + } + if (!(c == '"' || c == '\\')) { + raise_errmsg("Unterminated string starting at", pystr, begin); + goto bail; + } + /* Pick up this chunk if it's not zero length */ + if (next != end) { + chunk = PyUnicode_FromUnicode(&buf[end], next - end); + if (chunk == NULL) { + goto bail; + } + if (PyList_Append(chunks, chunk)) { + Py_DECREF(chunk); + goto bail; + } + Py_DECREF(chunk); + } + next++; + if (c == '"') { + end = next; + break; + } + if (next == len) { + raise_errmsg("Unterminated string starting at", pystr, begin); + goto bail; + } + c = buf[next]; + if (c != 'u') { + /* Non-unicode backslash escapes */ + end = next + 1; + switch (c) { + case '"': break; + case '\\': break; + case '/': break; + case 'b': c = '\b'; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + default: c = 0; + } + if (c == 0) { + raise_errmsg("Invalid \\escape", pystr, end - 2); + goto bail; + } + } + else { + c = 0; + next++; + end = next + 4; + if (end >= len) { + raise_errmsg("Invalid \\uXXXX escape", pystr, next - 1); + goto bail; + } + /* Decode 4 hex digits */ + for (; next < end; next++) { + Py_UNICODE digit = buf[next]; + c <<= 4; + switch (digit) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + c |= (digit - '0'); break; + case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': + c |= (digit - 'a' + 10); break; + case 'A': case 'B': case 'C': case 'D': case 'E': + case 'F': + c |= (digit - 'A' + 10); break; + default: + raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5); + goto bail; + } + } +#ifdef Py_UNICODE_WIDE + /* Surrogate pair */ + if ((c & 0xfc00) == 0xd800) { + Py_UNICODE c2 = 0; + if (end + 6 >= len) { + raise_errmsg("Unpaired high surrogate", pystr, end - 5); + goto bail; + } + if (buf[next++] != '\\' || buf[next++] != 'u') { + raise_errmsg("Unpaired high surrogate", pystr, end - 5); + goto bail; + } + end += 6; + /* Decode 4 hex digits */ + for (; next < end; next++) { + c2 <<= 4; + Py_UNICODE digit = buf[next]; + switch (digit) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + c2 |= (digit - '0'); break; + case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': + c2 |= (digit - 'a' + 10); break; + case 'A': case 'B': case 'C': case 'D': case 'E': + case 'F': + c2 |= (digit - 'A' + 10); break; + default: + raise_errmsg("Invalid \\uXXXX escape", pystr, end - 5); + goto bail; + } + } + if ((c2 & 0xfc00) != 0xdc00) { + raise_errmsg("Unpaired high surrogate", pystr, end - 5); + goto bail; + } + c = 0x10000 + (((c - 0xd800) << 10) | (c2 - 0xdc00)); + } + else if ((c & 0xfc00) == 0xdc00) { + raise_errmsg("Unpaired low surrogate", pystr, end - 5); + goto bail; + } +#endif + } + chunk = PyUnicode_FromUnicode(&c, 1); + if (chunk == NULL) { + goto bail; + } + if (PyList_Append(chunks, chunk)) { + Py_DECREF(chunk); + goto bail; + } + Py_DECREF(chunk); + } + + rval = join_list_unicode(chunks); + if (rval == NULL) { + goto bail; + } + Py_DECREF(chunks); + *next_end_ptr = end; + return rval; +bail: + *next_end_ptr = -1; + Py_XDECREF(chunks); + return NULL; +} + +PyDoc_STRVAR(pydoc_scanstring, + "scanstring(basestring, end, encoding, strict=True) -> (str, end)\n" + "\n" + "Scan the string s for a JSON string. End is the index of the\n" + "character in s after the quote that started the JSON string.\n" + "Unescapes all valid JSON string escape sequences and raises ValueError\n" + "on attempt to decode an invalid string. If strict is False then literal\n" + "control characters are allowed in the string.\n" + "\n" + "Returns a tuple of the decoded string and the index of the character in s\n" + "after the end quote." +); + +static PyObject * +py_scanstring(PyObject* self UNUSED, PyObject *args) +{ + PyObject *pystr; + PyObject *rval; + Py_ssize_t end; + Py_ssize_t next_end = -1; + char *encoding = NULL; + int strict = 1; + if (!PyArg_ParseTuple(args, "OO&|zi:scanstring", &pystr, _convertPyInt_AsSsize_t, &end, &encoding, &strict)) { + return NULL; + } + if (encoding == NULL) { + encoding = DEFAULT_ENCODING; + } + if (PyString_Check(pystr)) { + rval = scanstring_str(pystr, end, encoding, strict, &next_end); + } + else if (PyUnicode_Check(pystr)) { + rval = scanstring_unicode(pystr, end, strict, &next_end); + } + else { + PyErr_Format(PyExc_TypeError, + "first argument must be a string, not %.80s", + Py_TYPE(pystr)->tp_name); + return NULL; + } + return _build_rval_index_tuple(rval, next_end); +} + +PyDoc_STRVAR(pydoc_encode_basestring_ascii, + "encode_basestring_ascii(basestring) -> str\n" + "\n" + "Return an ASCII-only JSON representation of a Python string" +); + +static PyObject * +py_encode_basestring_ascii(PyObject* self UNUSED, PyObject *pystr) +{ + /* Return an ASCII-only JSON representation of a Python string */ + /* METH_O */ + if (PyString_Check(pystr)) { + return ascii_escape_str(pystr); + } + else if (PyUnicode_Check(pystr)) { + return ascii_escape_unicode(pystr); + } + else { + PyErr_Format(PyExc_TypeError, + "first argument must be a string, not %.80s", + Py_TYPE(pystr)->tp_name); + return NULL; + } +} + +static void +scanner_dealloc(PyObject *self) +{ + /* Deallocate scanner object */ + scanner_clear(self); + Py_TYPE(self)->tp_free(self); +} + +static int +scanner_traverse(PyObject *self, visitproc visit, void *arg) +{ + PyScannerObject *s; + assert(PyScanner_Check(self)); + s = (PyScannerObject *)self; + Py_VISIT(s->encoding); + Py_VISIT(s->strict); + Py_VISIT(s->object_hook); + Py_VISIT(s->parse_float); + Py_VISIT(s->parse_int); + Py_VISIT(s->parse_constant); + return 0; +} + +static int +scanner_clear(PyObject *self) +{ + PyScannerObject *s; + assert(PyScanner_Check(self)); + s = (PyScannerObject *)self; + Py_CLEAR(s->encoding); + Py_CLEAR(s->strict); + Py_CLEAR(s->object_hook); + Py_CLEAR(s->parse_float); + Py_CLEAR(s->parse_int); + Py_CLEAR(s->parse_constant); + return 0; +} + +static PyObject * +_parse_object_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { + /* Read a JSON object from PyString pystr. + idx is the index of the first character after the opening curly brace. + *next_idx_ptr is a return-by-reference index to the first character after + the closing curly brace. + + Returns a new PyObject (usually a dict, but object_hook can change that) + */ + char *str = PyString_AS_STRING(pystr); + Py_ssize_t end_idx = PyString_GET_SIZE(pystr) - 1; + PyObject *rval = PyDict_New(); + PyObject *key = NULL; + PyObject *val = NULL; + char *encoding = PyString_AS_STRING(s->encoding); + int strict = PyObject_IsTrue(s->strict); + Py_ssize_t next_idx; + if (rval == NULL) + return NULL; + + /* skip whitespace after { */ + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + + /* only loop if the object is non-empty */ + if (idx <= end_idx && str[idx] != '}') { + while (idx <= end_idx) { + /* read key */ + if (str[idx] != '"') { + raise_errmsg("Expecting property name", pystr, idx); + goto bail; + } + key = scanstring_str(pystr, idx + 1, encoding, strict, &next_idx); + if (key == NULL) + goto bail; + idx = next_idx; + + /* skip whitespace between key and : delimiter, read :, skip whitespace */ + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + if (idx > end_idx || str[idx] != ':') { + raise_errmsg("Expecting : delimiter", pystr, idx); + goto bail; + } + idx++; + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + + /* read any JSON data type */ + val = scan_once_str(s, pystr, idx, &next_idx); + if (val == NULL) + goto bail; + + if (PyDict_SetItem(rval, key, val) == -1) + goto bail; + + Py_CLEAR(key); + Py_CLEAR(val); + idx = next_idx; + + /* skip whitespace before } or , */ + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + + /* bail if the object is closed or we didn't get the , delimiter */ + if (idx > end_idx) break; + if (str[idx] == '}') { + break; + } + else if (str[idx] != ',') { + raise_errmsg("Expecting , delimiter", pystr, idx); + goto bail; + } + idx++; + + /* skip whitespace after , delimiter */ + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + } + } + /* verify that idx < end_idx, str[idx] should be '}' */ + if (idx > end_idx || str[idx] != '}') { + raise_errmsg("Expecting object", pystr, end_idx); + goto bail; + } + /* if object_hook is not None: rval = object_hook(rval) */ + if (s->object_hook != Py_None) { + val = PyObject_CallFunctionObjArgs(s->object_hook, rval, NULL); + if (val == NULL) + goto bail; + Py_DECREF(rval); + rval = val; + val = NULL; + } + *next_idx_ptr = idx + 1; + return rval; +bail: + Py_XDECREF(key); + Py_XDECREF(val); + Py_DECREF(rval); + return NULL; +} + +static PyObject * +_parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { + /* Read a JSON object from PyUnicode pystr. + idx is the index of the first character after the opening curly brace. + *next_idx_ptr is a return-by-reference index to the first character after + the closing curly brace. + + Returns a new PyObject (usually a dict, but object_hook can change that) + */ + Py_UNICODE *str = PyUnicode_AS_UNICODE(pystr); + Py_ssize_t end_idx = PyUnicode_GET_SIZE(pystr) - 1; + PyObject *val = NULL; + PyObject *rval = PyDict_New(); + PyObject *key = NULL; + int strict = PyObject_IsTrue(s->strict); + Py_ssize_t next_idx; + if (rval == NULL) + return NULL; + + /* skip whitespace after { */ + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + + /* only loop if the object is non-empty */ + if (idx <= end_idx && str[idx] != '}') { + while (idx <= end_idx) { + /* read key */ + if (str[idx] != '"') { + raise_errmsg("Expecting property name", pystr, idx); + goto bail; + } + key = scanstring_unicode(pystr, idx + 1, strict, &next_idx); + if (key == NULL) + goto bail; + idx = next_idx; + + /* skip whitespace between key and : delimiter, read :, skip whitespace */ + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + if (idx > end_idx || str[idx] != ':') { + raise_errmsg("Expecting : delimiter", pystr, idx); + goto bail; + } + idx++; + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + + /* read any JSON term */ + val = scan_once_unicode(s, pystr, idx, &next_idx); + if (val == NULL) + goto bail; + + if (PyDict_SetItem(rval, key, val) == -1) + goto bail; + + Py_CLEAR(key); + Py_CLEAR(val); + idx = next_idx; + + /* skip whitespace before } or , */ + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + + /* bail if the object is closed or we didn't get the , delimiter */ + if (idx > end_idx) break; + if (str[idx] == '}') { + break; + } + else if (str[idx] != ',') { + raise_errmsg("Expecting , delimiter", pystr, idx); + goto bail; + } + idx++; + + /* skip whitespace after , delimiter */ + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + } + } + + /* verify that idx < end_idx, str[idx] should be '}' */ + if (idx > end_idx || str[idx] != '}') { + raise_errmsg("Expecting object", pystr, end_idx); + goto bail; + } + + /* if object_hook is not None: rval = object_hook(rval) */ + if (s->object_hook != Py_None) { + val = PyObject_CallFunctionObjArgs(s->object_hook, rval, NULL); + if (val == NULL) + goto bail; + Py_DECREF(rval); + rval = val; + val = NULL; + } + *next_idx_ptr = idx + 1; + return rval; +bail: + Py_XDECREF(key); + Py_XDECREF(val); + Py_DECREF(rval); + return NULL; +} + +static PyObject * +_parse_array_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { + /* Read a JSON array from PyString pystr. + idx is the index of the first character after the opening brace. + *next_idx_ptr is a return-by-reference index to the first character after + the closing brace. + + Returns a new PyList + */ + char *str = PyString_AS_STRING(pystr); + Py_ssize_t end_idx = PyString_GET_SIZE(pystr) - 1; + PyObject *val = NULL; + PyObject *rval = PyList_New(0); + Py_ssize_t next_idx; + if (rval == NULL) + return NULL; + + /* skip whitespace after [ */ + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + + /* only loop if the array is non-empty */ + if (idx <= end_idx && str[idx] != ']') { + while (idx <= end_idx) { + + /* read any JSON term and de-tuplefy the (rval, idx) */ + val = scan_once_str(s, pystr, idx, &next_idx); + if (val == NULL) + goto bail; + + if (PyList_Append(rval, val) == -1) + goto bail; + + Py_CLEAR(val); + idx = next_idx; + + /* skip whitespace between term and , */ + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + + /* bail if the array is closed or we didn't get the , delimiter */ + if (idx > end_idx) break; + if (str[idx] == ']') { + break; + } + else if (str[idx] != ',') { + raise_errmsg("Expecting , delimiter", pystr, idx); + goto bail; + } + idx++; + + /* skip whitespace after , */ + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + } + } + + /* verify that idx < end_idx, str[idx] should be ']' */ + if (idx > end_idx || str[idx] != ']') { + raise_errmsg("Expecting object", pystr, end_idx); + goto bail; + } + *next_idx_ptr = idx + 1; + return rval; +bail: + Py_XDECREF(val); + Py_DECREF(rval); + return NULL; +} + +static PyObject * +_parse_array_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { + /* Read a JSON array from PyString pystr. + idx is the index of the first character after the opening brace. + *next_idx_ptr is a return-by-reference index to the first character after + the closing brace. + + Returns a new PyList + */ + Py_UNICODE *str = PyUnicode_AS_UNICODE(pystr); + Py_ssize_t end_idx = PyUnicode_GET_SIZE(pystr) - 1; + PyObject *val = NULL; + PyObject *rval = PyList_New(0); + Py_ssize_t next_idx; + if (rval == NULL) + return NULL; + + /* skip whitespace after [ */ + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + + /* only loop if the array is non-empty */ + if (idx <= end_idx && str[idx] != ']') { + while (idx <= end_idx) { + + /* read any JSON term */ + val = scan_once_unicode(s, pystr, idx, &next_idx); + if (val == NULL) + goto bail; + + if (PyList_Append(rval, val) == -1) + goto bail; + + Py_CLEAR(val); + idx = next_idx; + + /* skip whitespace between term and , */ + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + + /* bail if the array is closed or we didn't get the , delimiter */ + if (idx > end_idx) break; + if (str[idx] == ']') { + break; + } + else if (str[idx] != ',') { + raise_errmsg("Expecting , delimiter", pystr, idx); + goto bail; + } + idx++; + + /* skip whitespace after , */ + while (idx <= end_idx && IS_WHITESPACE(str[idx])) idx++; + } + } + + /* verify that idx < end_idx, str[idx] should be ']' */ + if (idx > end_idx || str[idx] != ']') { + raise_errmsg("Expecting object", pystr, end_idx); + goto bail; + } + *next_idx_ptr = idx + 1; + return rval; +bail: + Py_XDECREF(val); + Py_DECREF(rval); + return NULL; +} + +static PyObject * +_parse_constant(PyScannerObject *s, char *constant, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) { + /* Read a JSON constant from PyString pystr. + constant is the constant string that was found + ("NaN", "Infinity", "-Infinity"). + idx is the index of the first character of the constant + *next_idx_ptr is a return-by-reference index to the first character after + the constant. + + Returns the result of parse_constant + */ + PyObject *cstr; + PyObject *rval; + /* constant is "NaN", "Infinity", or "-Infinity" */ + cstr = PyString_InternFromString(constant); + if (cstr == NULL) + return NULL; + + /* rval = parse_constant(constant) */ + rval = PyObject_CallFunctionObjArgs(s->parse_constant, cstr, NULL); + idx += PyString_GET_SIZE(cstr); + Py_DECREF(cstr); + *next_idx_ptr = idx; + return rval; +} + +static PyObject * +_match_number_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ssize_t *next_idx_ptr) { + /* Read a JSON number from PyString pystr. + idx is the index of the first character of the number + *next_idx_ptr is a return-by-reference index to the first character after + the number. + + Returns a new PyObject representation of that number: + PyInt, PyLong, or PyFloat. + May return other types if parse_int or parse_float are set + */ + char *str = PyString_AS_STRING(pystr); + Py_ssize_t end_idx = PyString_GET_SIZE(pystr) - 1; + Py_ssize_t idx = start; + int is_float = 0; + PyObject *rval; + PyObject *numstr; + + /* read a sign if it's there, make sure it's not the end of the string */ + if (str[idx] == '-') { + idx++; + if (idx > end_idx) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + } + + /* read as many integer digits as we find as long as it doesn't start with 0 */ + if (str[idx] >= '1' && str[idx] <= '9') { + idx++; + while (idx <= end_idx && str[idx] >= '0' && str[idx] <= '9') idx++; + } + /* if it starts with 0 we only expect one integer digit */ + else if (str[idx] == '0') { + idx++; + } + /* no integer digits, error */ + else { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + + /* if the next char is '.' followed by a digit then read all float digits */ + if (idx < end_idx && str[idx] == '.' && str[idx + 1] >= '0' && str[idx + 1] <= '9') { + is_float = 1; + idx += 2; + while (idx <= end_idx && str[idx] >= '0' && str[idx] <= '9') idx++; + } + + /* if the next char is 'e' or 'E' then maybe read the exponent (or backtrack) */ + if (idx < end_idx && (str[idx] == 'e' || str[idx] == 'E')) { + + /* save the index of the 'e' or 'E' just in case we need to backtrack */ + Py_ssize_t e_start = idx; + idx++; + + /* read an exponent sign if present */ + if (idx < end_idx && (str[idx] == '-' || str[idx] == '+')) idx++; + + /* read all digits */ + while (idx <= end_idx && str[idx] >= '0' && str[idx] <= '9') idx++; + + /* if we got a digit, then parse as float. if not, backtrack */ + if (str[idx - 1] >= '0' && str[idx - 1] <= '9') { + is_float = 1; + } + else { + idx = e_start; + } + } + + /* copy the section we determined to be a number */ + numstr = PyString_FromStringAndSize(&str[start], idx - start); + if (numstr == NULL) + return NULL; + if (is_float) { + /* parse as a float using a fast path if available, otherwise call user defined method */ + if (s->parse_float != (PyObject *)&PyFloat_Type) { + rval = PyObject_CallFunctionObjArgs(s->parse_float, numstr, NULL); + } + else { + rval = PyFloat_FromDouble(PyOS_ascii_atof(PyString_AS_STRING(numstr))); + } + } + else { + /* parse as an int using a fast path if available, otherwise call user defined method */ + if (s->parse_int != (PyObject *)&PyInt_Type) { + rval = PyObject_CallFunctionObjArgs(s->parse_int, numstr, NULL); + } + else { + rval = PyInt_FromString(PyString_AS_STRING(numstr), NULL, 10); + } + } + Py_DECREF(numstr); + *next_idx_ptr = idx; + return rval; +} + +static PyObject * +_match_number_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t start, Py_ssize_t *next_idx_ptr) { + /* Read a JSON number from PyUnicode pystr. + idx is the index of the first character of the number + *next_idx_ptr is a return-by-reference index to the first character after + the number. + + Returns a new PyObject representation of that number: + PyInt, PyLong, or PyFloat. + May return other types if parse_int or parse_float are set + */ + Py_UNICODE *str = PyUnicode_AS_UNICODE(pystr); + Py_ssize_t end_idx = PyUnicode_GET_SIZE(pystr) - 1; + Py_ssize_t idx = start; + int is_float = 0; + PyObject *rval; + PyObject *numstr; + + /* read a sign if it's there, make sure it's not the end of the string */ + if (str[idx] == '-') { + idx++; + if (idx > end_idx) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + } + + /* read as many integer digits as we find as long as it doesn't start with 0 */ + if (str[idx] >= '1' && str[idx] <= '9') { + idx++; + while (idx <= end_idx && str[idx] >= '0' && str[idx] <= '9') idx++; + } + /* if it starts with 0 we only expect one integer digit */ + else if (str[idx] == '0') { + idx++; + } + /* no integer digits, error */ + else { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + + /* if the next char is '.' followed by a digit then read all float digits */ + if (idx < end_idx && str[idx] == '.' && str[idx + 1] >= '0' && str[idx + 1] <= '9') { + is_float = 1; + idx += 2; + while (idx < end_idx && str[idx] >= '0' && str[idx] <= '9') idx++; + } + + /* if the next char is 'e' or 'E' then maybe read the exponent (or backtrack) */ + if (idx < end_idx && (str[idx] == 'e' || str[idx] == 'E')) { + Py_ssize_t e_start = idx; + idx++; + + /* read an exponent sign if present */ + if (idx < end_idx && (str[idx] == '-' || str[idx] == '+')) idx++; + + /* read all digits */ + while (idx <= end_idx && str[idx] >= '0' && str[idx] <= '9') idx++; + + /* if we got a digit, then parse as float. if not, backtrack */ + if (str[idx - 1] >= '0' && str[idx - 1] <= '9') { + is_float = 1; + } + else { + idx = e_start; + } + } + + /* copy the section we determined to be a number */ + numstr = PyUnicode_FromUnicode(&str[start], idx - start); + if (numstr == NULL) + return NULL; + if (is_float) { + /* parse as a float using a fast path if available, otherwise call user defined method */ + if (s->parse_float != (PyObject *)&PyFloat_Type) { + rval = PyObject_CallFunctionObjArgs(s->parse_float, numstr, NULL); + } + else { + rval = PyFloat_FromString(numstr, NULL); + } + } + else { + /* no fast path for unicode -> int, just call */ + rval = PyObject_CallFunctionObjArgs(s->parse_int, numstr, NULL); + } + Py_DECREF(numstr); + *next_idx_ptr = idx; + return rval; +} + +static PyObject * +scan_once_str(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) +{ + /* Read one JSON term (of any kind) from PyString pystr. + idx is the index of the first character of the term + *next_idx_ptr is a return-by-reference index to the first character after + the number. + + Returns a new PyObject representation of the term. + */ + char *str = PyString_AS_STRING(pystr); + Py_ssize_t length = PyString_GET_SIZE(pystr); + if (idx >= length) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + switch (str[idx]) { + case '"': + /* string */ + return scanstring_str(pystr, idx + 1, + PyString_AS_STRING(s->encoding), + PyObject_IsTrue(s->strict), + next_idx_ptr); + case '{': + /* object */ + return _parse_object_str(s, pystr, idx + 1, next_idx_ptr); + case '[': + /* array */ + return _parse_array_str(s, pystr, idx + 1, next_idx_ptr); + case 'n': + /* null */ + if ((idx + 3 < length) && str[idx + 1] == 'u' && str[idx + 2] == 'l' && str[idx + 3] == 'l') { + Py_INCREF(Py_None); + *next_idx_ptr = idx + 4; + return Py_None; + } + break; + case 't': + /* true */ + if ((idx + 3 < length) && str[idx + 1] == 'r' && str[idx + 2] == 'u' && str[idx + 3] == 'e') { + Py_INCREF(Py_True); + *next_idx_ptr = idx + 4; + return Py_True; + } + break; + case 'f': + /* false */ + if ((idx + 4 < length) && str[idx + 1] == 'a' && str[idx + 2] == 'l' && str[idx + 3] == 's' && str[idx + 4] == 'e') { + Py_INCREF(Py_False); + *next_idx_ptr = idx + 5; + return Py_False; + } + break; + case 'N': + /* NaN */ + if ((idx + 2 < length) && str[idx + 1] == 'a' && str[idx + 2] == 'N') { + return _parse_constant(s, "NaN", idx, next_idx_ptr); + } + break; + case 'I': + /* Infinity */ + if ((idx + 7 < length) && str[idx + 1] == 'n' && str[idx + 2] == 'f' && str[idx + 3] == 'i' && str[idx + 4] == 'n' && str[idx + 5] == 'i' && str[idx + 6] == 't' && str[idx + 7] == 'y') { + return _parse_constant(s, "Infinity", idx, next_idx_ptr); + } + break; + case '-': + /* -Infinity */ + if ((idx + 8 < length) && str[idx + 1] == 'I' && str[idx + 2] == 'n' && str[idx + 3] == 'f' && str[idx + 4] == 'i' && str[idx + 5] == 'n' && str[idx + 6] == 'i' && str[idx + 7] == 't' && str[idx + 8] == 'y') { + return _parse_constant(s, "-Infinity", idx, next_idx_ptr); + } + break; + } + /* Didn't find a string, object, array, or named constant. Look for a number. */ + return _match_number_str(s, pystr, idx, next_idx_ptr); +} + +static PyObject * +scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_t *next_idx_ptr) +{ + /* Read one JSON term (of any kind) from PyUnicode pystr. + idx is the index of the first character of the term + *next_idx_ptr is a return-by-reference index to the first character after + the number. + + Returns a new PyObject representation of the term. + */ + Py_UNICODE *str = PyUnicode_AS_UNICODE(pystr); + Py_ssize_t length = PyUnicode_GET_SIZE(pystr); + if (idx >= length) { + PyErr_SetNone(PyExc_StopIteration); + return NULL; + } + switch (str[idx]) { + case '"': + /* string */ + return scanstring_unicode(pystr, idx + 1, + PyObject_IsTrue(s->strict), + next_idx_ptr); + case '{': + /* object */ + return _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr); + case '[': + /* array */ + return _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr); + case 'n': + /* null */ + if ((idx + 3 < length) && str[idx + 1] == 'u' && str[idx + 2] == 'l' && str[idx + 3] == 'l') { + Py_INCREF(Py_None); + *next_idx_ptr = idx + 4; + return Py_None; + } + break; + case 't': + /* true */ + if ((idx + 3 < length) && str[idx + 1] == 'r' && str[idx + 2] == 'u' && str[idx + 3] == 'e') { + Py_INCREF(Py_True); + *next_idx_ptr = idx + 4; + return Py_True; + } + break; + case 'f': + /* false */ + if ((idx + 4 < length) && str[idx + 1] == 'a' && str[idx + 2] == 'l' && str[idx + 3] == 's' && str[idx + 4] == 'e') { + Py_INCREF(Py_False); + *next_idx_ptr = idx + 5; + return Py_False; + } + break; + case 'N': + /* NaN */ + if ((idx + 2 < length) && str[idx + 1] == 'a' && str[idx + 2] == 'N') { + return _parse_constant(s, "NaN", idx, next_idx_ptr); + } + break; + case 'I': + /* Infinity */ + if ((idx + 7 < length) && str[idx + 1] == 'n' && str[idx + 2] == 'f' && str[idx + 3] == 'i' && str[idx + 4] == 'n' && str[idx + 5] == 'i' && str[idx + 6] == 't' && str[idx + 7] == 'y') { + return _parse_constant(s, "Infinity", idx, next_idx_ptr); + } + break; + case '-': + /* -Infinity */ + if ((idx + 8 < length) && str[idx + 1] == 'I' && str[idx + 2] == 'n' && str[idx + 3] == 'f' && str[idx + 4] == 'i' && str[idx + 5] == 'n' && str[idx + 6] == 'i' && str[idx + 7] == 't' && str[idx + 8] == 'y') { + return _parse_constant(s, "-Infinity", idx, next_idx_ptr); + } + break; + } + /* Didn't find a string, object, array, or named constant. Look for a number. */ + return _match_number_unicode(s, pystr, idx, next_idx_ptr); +} + +static PyObject * +scanner_call(PyObject *self, PyObject *args, PyObject *kwds) +{ + /* Python callable interface to scan_once_{str,unicode} */ + PyObject *pystr; + PyObject *rval; + Py_ssize_t idx; + Py_ssize_t next_idx = -1; + static char *kwlist[] = {"string", "idx", NULL}; + PyScannerObject *s; + assert(PyScanner_Check(self)); + s = (PyScannerObject *)self; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&:scan_once", kwlist, &pystr, _convertPyInt_AsSsize_t, &idx)) + return NULL; + + if (PyString_Check(pystr)) { + rval = scan_once_str(s, pystr, idx, &next_idx); + } + else if (PyUnicode_Check(pystr)) { + rval = scan_once_unicode(s, pystr, idx, &next_idx); + } + else { + PyErr_Format(PyExc_TypeError, + "first argument must be a string, not %.80s", + Py_TYPE(pystr)->tp_name); + return NULL; + } + return _build_rval_index_tuple(rval, next_idx); +} + +static PyObject * +scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyScannerObject *s; + s = (PyScannerObject *)type->tp_alloc(type, 0); + if (s != NULL) { + s->encoding = NULL; + s->strict = NULL; + s->object_hook = NULL; + s->parse_float = NULL; + s->parse_int = NULL; + s->parse_constant = NULL; + } + return (PyObject *)s; +} + +static int +scanner_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + /* Initialize Scanner object */ + PyObject *ctx; + static char *kwlist[] = {"context", NULL}; + PyScannerObject *s; + + assert(PyScanner_Check(self)); + s = (PyScannerObject *)self; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx)) + return -1; + + /* PyString_AS_STRING is used on encoding */ + s->encoding = PyObject_GetAttrString(ctx, "encoding"); + if (s->encoding == Py_None) { + Py_DECREF(Py_None); + s->encoding = PyString_InternFromString(DEFAULT_ENCODING); + } + else if (PyUnicode_Check(s->encoding)) { + PyObject *tmp = PyUnicode_AsEncodedString(s->encoding, NULL, NULL); + Py_DECREF(s->encoding); + s->encoding = tmp; + } + if (s->encoding == NULL || !PyString_Check(s->encoding)) + goto bail; + + /* All of these will fail "gracefully" so we don't need to verify them */ + s->strict = PyObject_GetAttrString(ctx, "strict"); + if (s->strict == NULL) + goto bail; + s->object_hook = PyObject_GetAttrString(ctx, "object_hook"); + if (s->object_hook == NULL) + goto bail; + s->parse_float = PyObject_GetAttrString(ctx, "parse_float"); + if (s->parse_float == NULL) + goto bail; + s->parse_int = PyObject_GetAttrString(ctx, "parse_int"); + if (s->parse_int == NULL) + goto bail; + s->parse_constant = PyObject_GetAttrString(ctx, "parse_constant"); + if (s->parse_constant == NULL) + goto bail; + + return 0; + +bail: + Py_CLEAR(s->encoding); + Py_CLEAR(s->strict); + Py_CLEAR(s->object_hook); + Py_CLEAR(s->parse_float); + Py_CLEAR(s->parse_int); + Py_CLEAR(s->parse_constant); + return -1; +} + +PyDoc_STRVAR(scanner_doc, "JSON scanner object"); + +static +PyTypeObject PyScannerType = { + PyObject_HEAD_INIT(NULL) + 0, /* tp_internal */ + "simplejson._speedups.Scanner", /* tp_name */ + sizeof(PyScannerObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + scanner_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + scanner_call, /* tp_call */ + 0, /* tp_str */ + 0,/* PyObject_GenericGetAttr, */ /* tp_getattro */ + 0,/* PyObject_GenericSetAttr, */ /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + scanner_doc, /* tp_doc */ + scanner_traverse, /* tp_traverse */ + scanner_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + scanner_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + scanner_init, /* tp_init */ + 0,/* PyType_GenericAlloc, */ /* tp_alloc */ + scanner_new, /* tp_new */ + 0,/* PyObject_GC_Del, */ /* tp_free */ +}; + +static PyObject * +encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyEncoderObject *s; + s = (PyEncoderObject *)type->tp_alloc(type, 0); + if (s != NULL) { + s->markers = NULL; + s->defaultfn = NULL; + s->encoder = NULL; + s->indent = NULL; + s->key_separator = NULL; + s->item_separator = NULL; + s->sort_keys = NULL; + s->skipkeys = NULL; + } + return (PyObject *)s; +} + +static int +encoder_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + /* initialize Encoder object */ + static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL}; + + PyEncoderObject *s; + PyObject *allow_nan; + + assert(PyEncoder_Check(self)); + s = (PyEncoderObject *)self; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOOOOOO:make_encoder", kwlist, + &s->markers, &s->defaultfn, &s->encoder, &s->indent, &s->key_separator, &s->item_separator, &s->sort_keys, &s->skipkeys, &allow_nan)) + return -1; + + Py_INCREF(s->markers); + Py_INCREF(s->defaultfn); + Py_INCREF(s->encoder); + Py_INCREF(s->indent); + Py_INCREF(s->key_separator); + Py_INCREF(s->item_separator); + Py_INCREF(s->sort_keys); + Py_INCREF(s->skipkeys); + s->fast_encode = (PyCFunction_Check(s->encoder) && PyCFunction_GetFunction(s->encoder) == (PyCFunction)py_encode_basestring_ascii); + s->allow_nan = PyObject_IsTrue(allow_nan); + return 0; +} + +static PyObject * +encoder_call(PyObject *self, PyObject *args, PyObject *kwds) +{ + /* Python callable interface to encode_listencode_obj */ + static char *kwlist[] = {"obj", "_current_indent_level", NULL}; + PyObject *obj; + PyObject *rval; + Py_ssize_t indent_level; + PyEncoderObject *s; + assert(PyEncoder_Check(self)); + s = (PyEncoderObject *)self; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&:_iterencode", kwlist, + &obj, _convertPyInt_AsSsize_t, &indent_level)) + return NULL; + rval = PyList_New(0); + if (rval == NULL) + return NULL; + if (encoder_listencode_obj(s, rval, obj, indent_level)) { + Py_DECREF(rval); + return NULL; + } + return rval; +} + +static PyObject * +_encoded_const(PyObject *obj) +{ + /* Return the JSON string representation of None, True, False */ + if (obj == Py_None) { + static PyObject *s_null = NULL; + if (s_null == NULL) { + s_null = PyString_InternFromString("null"); + } + Py_INCREF(s_null); + return s_null; + } + else if (obj == Py_True) { + static PyObject *s_true = NULL; + if (s_true == NULL) { + s_true = PyString_InternFromString("true"); + } + Py_INCREF(s_true); + return s_true; + } + else if (obj == Py_False) { + static PyObject *s_false = NULL; + if (s_false == NULL) { + s_false = PyString_InternFromString("false"); + } + Py_INCREF(s_false); + return s_false; + } + else { + PyErr_SetString(PyExc_ValueError, "not a const"); + return NULL; + } +} + +static PyObject * +encoder_encode_float(PyEncoderObject *s, PyObject *obj) +{ + /* Return the JSON representation of a PyFloat */ + double i = PyFloat_AS_DOUBLE(obj); + if (!Py_IS_FINITE(i)) { + if (!s->allow_nan) { + PyErr_SetString(PyExc_ValueError, "Out of range float values are not JSON compliant"); + return NULL; + } + if (i > 0) { + return PyString_FromString("Infinity"); + } + else if (i < 0) { + return PyString_FromString("-Infinity"); + } + else { + return PyString_FromString("NaN"); + } + } + /* Use a better float format here? */ + return PyObject_Repr(obj); +} + +static PyObject * +encoder_encode_string(PyEncoderObject *s, PyObject *obj) +{ + /* Return the JSON representation of a string */ + if (s->fast_encode) + return py_encode_basestring_ascii(NULL, obj); + else + return PyObject_CallFunctionObjArgs(s->encoder, obj, NULL); +} + +static int +_steal_list_append(PyObject *lst, PyObject *stolen) +{ + /* Append stolen and then decrement its reference count */ + int rval = PyList_Append(lst, stolen); + Py_DECREF(stolen); + return rval; +} + +static int +encoder_listencode_obj(PyEncoderObject *s, PyObject *rval, PyObject *obj, Py_ssize_t indent_level) +{ + /* Encode Python object obj to a JSON term, rval is a PyList */ + PyObject *newobj; + int rv; + + if (obj == Py_None || obj == Py_True || obj == Py_False) { + PyObject *cstr = _encoded_const(obj); + if (cstr == NULL) + return -1; + return _steal_list_append(rval, cstr); + } + else if (PyString_Check(obj) || PyUnicode_Check(obj)) + { + PyObject *encoded = encoder_encode_string(s, obj); + if (encoded == NULL) + return -1; + return _steal_list_append(rval, encoded); + } + else if (PyInt_Check(obj) || PyLong_Check(obj)) { + PyObject *encoded = PyObject_Str(obj); + if (encoded == NULL) + return -1; + return _steal_list_append(rval, encoded); + } + else if (PyFloat_Check(obj)) { + PyObject *encoded = encoder_encode_float(s, obj); + if (encoded == NULL) + return -1; + return _steal_list_append(rval, encoded); + } + else if (PyList_Check(obj) || PyTuple_Check(obj)) { + return encoder_listencode_list(s, rval, obj, indent_level); + } + else if (PyDict_Check(obj)) { + return encoder_listencode_dict(s, rval, obj, indent_level); + } + else { + PyObject *ident = NULL; + if (s->markers != Py_None) { + int has_key; + ident = PyLong_FromVoidPtr(obj); + if (ident == NULL) + return -1; + has_key = PyDict_Contains(s->markers, ident); + if (has_key) { + if (has_key != -1) + PyErr_SetString(PyExc_ValueError, "Circular reference detected"); + Py_DECREF(ident); + return -1; + } + if (PyDict_SetItem(s->markers, ident, obj)) { + Py_DECREF(ident); + return -1; + } + } + newobj = PyObject_CallFunctionObjArgs(s->defaultfn, obj, NULL); + if (newobj == NULL) { + Py_XDECREF(ident); + return -1; + } + rv = encoder_listencode_obj(s, rval, newobj, indent_level); + Py_DECREF(newobj); + if (rv) { + Py_XDECREF(ident); + return -1; + } + if (ident != NULL) { + if (PyDict_DelItem(s->markers, ident)) { + Py_XDECREF(ident); + return -1; + } + Py_XDECREF(ident); + } + return rv; + } +} + +static int +encoder_listencode_dict(PyEncoderObject *s, PyObject *rval, PyObject *dct, Py_ssize_t indent_level) +{ + /* Encode Python dict dct a JSON term, rval is a PyList */ + static PyObject *open_dict = NULL; + static PyObject *close_dict = NULL; + static PyObject *empty_dict = NULL; + PyObject *kstr = NULL; + PyObject *ident = NULL; + PyObject *key, *value; + Py_ssize_t pos; + int skipkeys; + Py_ssize_t idx; + + if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) { + open_dict = PyString_InternFromString("{"); + close_dict = PyString_InternFromString("}"); + empty_dict = PyString_InternFromString("{}"); + if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) + return -1; + } + if (PyDict_Size(dct) == 0) + return PyList_Append(rval, empty_dict); + + if (s->markers != Py_None) { + int has_key; + ident = PyLong_FromVoidPtr(dct); + if (ident == NULL) + goto bail; + has_key = PyDict_Contains(s->markers, ident); + if (has_key) { + if (has_key != -1) + PyErr_SetString(PyExc_ValueError, "Circular reference detected"); + goto bail; + } + if (PyDict_SetItem(s->markers, ident, dct)) { + goto bail; + } + } + + if (PyList_Append(rval, open_dict)) + goto bail; + + if (s->indent != Py_None) { + /* TODO: DOES NOT RUN */ + indent_level += 1; + /* + newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) + separator = _item_separator + newline_indent + buf += newline_indent + */ + } + + /* TODO: C speedup not implemented for sort_keys */ + + pos = 0; + skipkeys = PyObject_IsTrue(s->skipkeys); + idx = 0; + while (PyDict_Next(dct, &pos, &key, &value)) { + PyObject *encoded; + + if (PyString_Check(key) || PyUnicode_Check(key)) { + Py_INCREF(key); + kstr = key; + } + else if (PyFloat_Check(key)) { + kstr = encoder_encode_float(s, key); + if (kstr == NULL) + goto bail; + } + else if (PyInt_Check(key) || PyLong_Check(key)) { + kstr = PyObject_Str(key); + if (kstr == NULL) + goto bail; + } + else if (key == Py_True || key == Py_False || key == Py_None) { + kstr = _encoded_const(key); + if (kstr == NULL) + goto bail; + } + else if (skipkeys) { + continue; + } + else { + /* TODO: include repr of key */ + PyErr_SetString(PyExc_ValueError, "keys must be a string"); + goto bail; + } + + if (idx) { + if (PyList_Append(rval, s->item_separator)) + goto bail; + } + + encoded = encoder_encode_string(s, kstr); + Py_CLEAR(kstr); + if (encoded == NULL) + goto bail; + if (PyList_Append(rval, encoded)) { + Py_DECREF(encoded); + goto bail; + } + Py_DECREF(encoded); + if (PyList_Append(rval, s->key_separator)) + goto bail; + if (encoder_listencode_obj(s, rval, value, indent_level)) + goto bail; + idx += 1; + } + if (ident != NULL) { + if (PyDict_DelItem(s->markers, ident)) + goto bail; + Py_CLEAR(ident); + } + if (s->indent != Py_None) { + /* TODO: DOES NOT RUN */ + indent_level -= 1; + /* + yield '\n' + (' ' * (_indent * _current_indent_level)) + */ + } + if (PyList_Append(rval, close_dict)) + goto bail; + return 0; + +bail: + Py_XDECREF(kstr); + Py_XDECREF(ident); + return -1; +} + + +static int +encoder_listencode_list(PyEncoderObject *s, PyObject *rval, PyObject *seq, Py_ssize_t indent_level) +{ + /* Encode Python list seq to a JSON term, rval is a PyList */ + static PyObject *open_array = NULL; + static PyObject *close_array = NULL; + static PyObject *empty_array = NULL; + PyObject *ident = NULL; + PyObject *s_fast = NULL; + Py_ssize_t num_items; + PyObject **seq_items; + Py_ssize_t i; + + if (open_array == NULL || close_array == NULL || empty_array == NULL) { + open_array = PyString_InternFromString("["); + close_array = PyString_InternFromString("]"); + empty_array = PyString_InternFromString("[]"); + if (open_array == NULL || close_array == NULL || empty_array == NULL) + return -1; + } + ident = NULL; + s_fast = PySequence_Fast(seq, "_iterencode_list needs a sequence"); + if (s_fast == NULL) + return -1; + num_items = PySequence_Fast_GET_SIZE(s_fast); + if (num_items == 0) { + Py_DECREF(s_fast); + return PyList_Append(rval, empty_array); + } + + if (s->markers != Py_None) { + int has_key; + ident = PyLong_FromVoidPtr(seq); + if (ident == NULL) + goto bail; + has_key = PyDict_Contains(s->markers, ident); + if (has_key) { + if (has_key != -1) + PyErr_SetString(PyExc_ValueError, "Circular reference detected"); + goto bail; + } + if (PyDict_SetItem(s->markers, ident, seq)) { + goto bail; + } + } + + seq_items = PySequence_Fast_ITEMS(s_fast); + if (PyList_Append(rval, open_array)) + goto bail; + if (s->indent != Py_None) { + /* TODO: DOES NOT RUN */ + indent_level += 1; + /* + newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) + separator = _item_separator + newline_indent + buf += newline_indent + */ + } + for (i = 0; i < num_items; i++) { + PyObject *obj = seq_items[i]; + if (i) { + if (PyList_Append(rval, s->item_separator)) + goto bail; + } + if (encoder_listencode_obj(s, rval, obj, indent_level)) + goto bail; + } + if (ident != NULL) { + if (PyDict_DelItem(s->markers, ident)) + goto bail; + Py_CLEAR(ident); + } + if (s->indent != Py_None) { + /* TODO: DOES NOT RUN */ + indent_level -= 1; + /* + yield '\n' + (' ' * (_indent * _current_indent_level)) + */ + } + if (PyList_Append(rval, close_array)) + goto bail; + Py_DECREF(s_fast); + return 0; + +bail: + Py_XDECREF(ident); + Py_DECREF(s_fast); + return -1; +} + +static void +encoder_dealloc(PyObject *self) +{ + /* Deallocate Encoder */ + encoder_clear(self); + Py_TYPE(self)->tp_free(self); +} + +static int +encoder_traverse(PyObject *self, visitproc visit, void *arg) +{ + PyEncoderObject *s; + assert(PyEncoder_Check(self)); + s = (PyEncoderObject *)self; + Py_VISIT(s->markers); + Py_VISIT(s->defaultfn); + Py_VISIT(s->encoder); + Py_VISIT(s->indent); + Py_VISIT(s->key_separator); + Py_VISIT(s->item_separator); + Py_VISIT(s->sort_keys); + Py_VISIT(s->skipkeys); + return 0; +} + +static int +encoder_clear(PyObject *self) +{ + /* Deallocate Encoder */ + PyEncoderObject *s; + assert(PyEncoder_Check(self)); + s = (PyEncoderObject *)self; + Py_CLEAR(s->markers); + Py_CLEAR(s->defaultfn); + Py_CLEAR(s->encoder); + Py_CLEAR(s->indent); + Py_CLEAR(s->key_separator); + Py_CLEAR(s->item_separator); + Py_CLEAR(s->sort_keys); + Py_CLEAR(s->skipkeys); + return 0; +} + +PyDoc_STRVAR(encoder_doc, "_iterencode(obj, _current_indent_level) -> iterable"); + +static +PyTypeObject PyEncoderType = { + PyObject_HEAD_INIT(NULL) + 0, /* tp_internal */ + "simplejson._speedups.Encoder", /* tp_name */ + sizeof(PyEncoderObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + encoder_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + encoder_call, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ + encoder_doc, /* tp_doc */ + encoder_traverse, /* tp_traverse */ + encoder_clear, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + encoder_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + encoder_init, /* tp_init */ + 0, /* tp_alloc */ + encoder_new, /* tp_new */ + 0, /* tp_free */ +}; + +static PyMethodDef speedups_methods[] = { + {"encode_basestring_ascii", + (PyCFunction)py_encode_basestring_ascii, + METH_O, + pydoc_encode_basestring_ascii}, + {"scanstring", + (PyCFunction)py_scanstring, + METH_VARARGS, + pydoc_scanstring}, + {NULL, NULL, 0, NULL} +}; + +PyDoc_STRVAR(module_doc, +"simplejson speedups\n"); + +void +init_speedups(void) +{ + PyObject *m; + PyScannerType.tp_new = PyType_GenericNew; + if (PyType_Ready(&PyScannerType) < 0) + return; + PyEncoderType.tp_new = PyType_GenericNew; + if (PyType_Ready(&PyEncoderType) < 0) + return; + m = Py_InitModule3("_speedups", speedups_methods, module_doc); + Py_INCREF((PyObject*)&PyScannerType); + PyModule_AddObject(m, "make_scanner", (PyObject*)&PyScannerType); + Py_INCREF((PyObject*)&PyEncoderType); + PyModule_AddObject(m, "make_encoder", (PyObject*)&PyEncoderType); +} diff --git a/resources/lib/simplejson/decoder.py b/resources/lib/simplejson/decoder.py new file mode 100644 index 0000000..b769ea4 --- /dev/null +++ b/resources/lib/simplejson/decoder.py @@ -0,0 +1,354 @@ +"""Implementation of JSONDecoder +""" +import re +import sys +import struct + +from simplejson.scanner import make_scanner +try: + from simplejson._speedups import scanstring as c_scanstring +except ImportError: + c_scanstring = None + +__all__ = ['JSONDecoder'] + +FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL + +def _floatconstants(): + _BYTES = '7FF80000000000007FF0000000000000'.decode('hex') + if sys.byteorder != 'big': + _BYTES = _BYTES[:8][::-1] + _BYTES[8:][::-1] + nan, inf = struct.unpack('dd', _BYTES) + return nan, inf, -inf + +NaN, PosInf, NegInf = _floatconstants() + + +def linecol(doc, pos): + lineno = doc.count('\n', 0, pos) + 1 + if lineno == 1: + colno = pos + else: + colno = pos - doc.rindex('\n', 0, pos) + return lineno, colno + + +def errmsg(msg, doc, pos, end=None): + # Note that this function is called from _speedups + lineno, colno = linecol(doc, pos) + if end is None: + #fmt = '{0}: line {1} column {2} (char {3})' + #return fmt.format(msg, lineno, colno, pos) + fmt = '%s: line %d column %d (char %d)' + return fmt % (msg, lineno, colno, pos) + endlineno, endcolno = linecol(doc, end) + #fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})' + #return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end) + fmt = '%s: line %d column %d - line %d column %d (char %d - %d)' + return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end) + + +_CONSTANTS = { + '-Infinity': NegInf, + 'Infinity': PosInf, + 'NaN': NaN, +} + +STRINGCHUNK = re.compile(r'(.*?)(["\\\x00-\x1f])', FLAGS) +BACKSLASH = { + '"': u'"', '\\': u'\\', '/': u'/', + 'b': u'\b', 'f': u'\f', 'n': u'\n', 'r': u'\r', 't': u'\t', +} + +DEFAULT_ENCODING = "utf-8" + +def py_scanstring(s, end, encoding=None, strict=True, _b=BACKSLASH, _m=STRINGCHUNK.match): + """Scan the string s for a JSON string. End is the index of the + character in s after the quote that started the JSON string. + Unescapes all valid JSON string escape sequences and raises ValueError + on attempt to decode an invalid string. If strict is False then literal + control characters are allowed in the string. + + Returns a tuple of the decoded string and the index of the character in s + after the end quote.""" + if encoding is None: + encoding = DEFAULT_ENCODING + chunks = [] + _append = chunks.append + begin = end - 1 + while 1: + chunk = _m(s, end) + if chunk is None: + raise ValueError( + errmsg("Unterminated string starting at", s, begin)) + end = chunk.end() + content, terminator = chunk.groups() + # Content is contains zero or more unescaped string characters + if content: + if not isinstance(content, unicode): + content = unicode(content, encoding) + _append(content) + # Terminator is the end of string, a literal control character, + # or a backslash denoting that an escape sequence follows + if terminator == '"': + break + elif terminator != '\\': + if strict: + msg = "Invalid control character %r at" % (terminator,) + #msg = "Invalid control character {0!r} at".format(terminator) + raise ValueError(errmsg(msg, s, end)) + else: + _append(terminator) + continue + try: + esc = s[end] + except IndexError: + raise ValueError( + errmsg("Unterminated string starting at", s, begin)) + # If not a unicode escape sequence, must be in the lookup table + if esc != 'u': + try: + char = _b[esc] + except KeyError: + msg = "Invalid \\escape: " + repr(esc) + raise ValueError(errmsg(msg, s, end)) + end += 1 + else: + # Unicode escape sequence + esc = s[end + 1:end + 5] + next_end = end + 5 + if len(esc) != 4: + msg = "Invalid \\uXXXX escape" + raise ValueError(errmsg(msg, s, end)) + uni = int(esc, 16) + # Check for surrogate pair on UCS-4 systems + if 0xd800 <= uni <= 0xdbff and sys.maxunicode > 65535: + msg = "Invalid \\uXXXX\\uXXXX surrogate pair" + if not s[end + 5:end + 7] == '\\u': + raise ValueError(errmsg(msg, s, end)) + esc2 = s[end + 7:end + 11] + if len(esc2) != 4: + raise ValueError(errmsg(msg, s, end)) + uni2 = int(esc2, 16) + uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00)) + next_end += 6 + char = unichr(uni) + end = next_end + # Append the unescaped character + _append(char) + return u''.join(chunks), end + + +# Use speedup if available +scanstring = c_scanstring or py_scanstring + +WHITESPACE = re.compile(r'[ \t\n\r]*', FLAGS) +WHITESPACE_STR = ' \t\n\r' + +def JSONObject((s, end), encoding, strict, scan_once, object_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR): + pairs = {} + # Use a slice to prevent IndexError from being raised, the following + # check will raise a more specific ValueError if the string is empty + nextchar = s[end:end + 1] + # Normally we expect nextchar == '"' + if nextchar != '"': + if nextchar in _ws: + end = _w(s, end).end() + nextchar = s[end:end + 1] + # Trivial empty object + if nextchar == '}': + return pairs, end + 1 + elif nextchar != '"': + raise ValueError(errmsg("Expecting property name", s, end)) + end += 1 + while True: + key, end = scanstring(s, end, encoding, strict) + + # To skip some function call overhead we optimize the fast paths where + # the JSON key separator is ": " or just ":". + if s[end:end + 1] != ':': + end = _w(s, end).end() + if s[end:end + 1] != ':': + raise ValueError(errmsg("Expecting : delimiter", s, end)) + + end += 1 + + try: + if s[end] in _ws: + end += 1 + if s[end] in _ws: + end = _w(s, end + 1).end() + except IndexError: + pass + + try: + value, end = scan_once(s, end) + except StopIteration: + raise ValueError(errmsg("Expecting object", s, end)) + pairs[key] = value + + try: + nextchar = s[end] + if nextchar in _ws: + end = _w(s, end + 1).end() + nextchar = s[end] + except IndexError: + nextchar = '' + end += 1 + + if nextchar == '}': + break + elif nextchar != ',': + raise ValueError(errmsg("Expecting , delimiter", s, end - 1)) + + try: + nextchar = s[end] + if nextchar in _ws: + end += 1 + nextchar = s[end] + if nextchar in _ws: + end = _w(s, end + 1).end() + nextchar = s[end] + except IndexError: + nextchar = '' + + end += 1 + if nextchar != '"': + raise ValueError(errmsg("Expecting property name", s, end - 1)) + + if object_hook is not None: + pairs = object_hook(pairs) + return pairs, end + +def JSONArray((s, end), scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR): + values = [] + nextchar = s[end:end + 1] + if nextchar in _ws: + end = _w(s, end + 1).end() + nextchar = s[end:end + 1] + # Look-ahead for trivial empty array + if nextchar == ']': + return values, end + 1 + _append = values.append + while True: + try: + value, end = scan_once(s, end) + except StopIteration: + raise ValueError(errmsg("Expecting object", s, end)) + _append(value) + nextchar = s[end:end + 1] + if nextchar in _ws: + end = _w(s, end + 1).end() + nextchar = s[end:end + 1] + end += 1 + if nextchar == ']': + break + elif nextchar != ',': + raise ValueError(errmsg("Expecting , delimiter", s, end)) + + try: + if s[end] in _ws: + end += 1 + if s[end] in _ws: + end = _w(s, end + 1).end() + except IndexError: + pass + + return values, end + +class JSONDecoder(object): + """Simple JSON decoder + + Performs the following translations in decoding by default: + + +---------------+-------------------+ + | JSON | Python | + +===============+===================+ + | object | dict | + +---------------+-------------------+ + | array | list | + +---------------+-------------------+ + | string | unicode | + +---------------+-------------------+ + | number (int) | int, long | + +---------------+-------------------+ + | number (real) | float | + +---------------+-------------------+ + | true | True | + +---------------+-------------------+ + | false | False | + +---------------+-------------------+ + | null | None | + +---------------+-------------------+ + + It also understands ``NaN``, ``Infinity``, and ``-Infinity`` as + their corresponding ``float`` values, which is outside the JSON spec. + + """ + + def __init__(self, encoding=None, object_hook=None, parse_float=None, + parse_int=None, parse_constant=None, strict=True): + """``encoding`` determines the encoding used to interpret any ``str`` + objects decoded by this instance (utf-8 by default). It has no + effect when decoding ``unicode`` objects. + + Note that currently only encodings that are a superset of ASCII work, + strings of other encodings should be passed in as ``unicode``. + + ``object_hook``, if specified, will be called with the result + of every JSON object decoded and its return value will be used in + place of the given ``dict``. This can be used to provide custom + deserializations (e.g. to support JSON-RPC class hinting). + + ``parse_float``, if specified, will be called with the string + of every JSON float to be decoded. By default this is equivalent to + float(num_str). This can be used to use another datatype or parser + for JSON floats (e.g. decimal.Decimal). + + ``parse_int``, if specified, will be called with the string + of every JSON int to be decoded. By default this is equivalent to + int(num_str). This can be used to use another datatype or parser + for JSON integers (e.g. float). + + ``parse_constant``, if specified, will be called with one of the + following strings: -Infinity, Infinity, NaN. + This can be used to raise an exception if invalid JSON numbers + are encountered. + + """ + self.encoding = encoding + self.object_hook = object_hook + self.parse_float = parse_float or float + self.parse_int = parse_int or int + self.parse_constant = parse_constant or _CONSTANTS.__getitem__ + self.strict = strict + self.parse_object = JSONObject + self.parse_array = JSONArray + self.parse_string = scanstring + self.scan_once = make_scanner(self) + + def decode(self, s, _w=WHITESPACE.match): + """Return the Python representation of ``s`` (a ``str`` or ``unicode`` + instance containing a JSON document) + + """ + obj, end = self.raw_decode(s, idx=_w(s, 0).end()) + end = _w(s, end).end() + if end != len(s): + raise ValueError(errmsg("Extra data", s, end, len(s))) + return obj + + def raw_decode(self, s, idx=0): + """Decode a JSON document from ``s`` (a ``str`` or ``unicode`` beginning + with a JSON document) and return a 2-tuple of the Python + representation and the index in ``s`` where the document ended. + + This can be used to decode a JSON document from a string that may + have extraneous data at the end. + + """ + try: + obj, end = self.scan_once(s, idx) + except StopIteration: + raise ValueError("No JSON object could be decoded") + return obj, end diff --git a/resources/lib/simplejson/encoder.py b/resources/lib/simplejson/encoder.py new file mode 100644 index 0000000..cf58290 --- /dev/null +++ b/resources/lib/simplejson/encoder.py @@ -0,0 +1,440 @@ +"""Implementation of JSONEncoder +""" +import re + +try: + from simplejson._speedups import encode_basestring_ascii as c_encode_basestring_ascii +except ImportError: + c_encode_basestring_ascii = None +try: + from simplejson._speedups import make_encoder as c_make_encoder +except ImportError: + c_make_encoder = None + +ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]') +ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])') +HAS_UTF8 = re.compile(r'[\x80-\xff]') +ESCAPE_DCT = { + '\\': '\\\\', + '"': '\\"', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t', +} +for i in range(0x20): + #ESCAPE_DCT.setdefault(chr(i), '\\u{0:04x}'.format(i)) + ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,)) + +# Assume this produces an infinity on all machines (probably not guaranteed) +INFINITY = float('1e66666') +FLOAT_REPR = repr + +def encode_basestring(s): + """Return a JSON representation of a Python string + + """ + def replace(match): + return ESCAPE_DCT[match.group(0)] + return '"' + ESCAPE.sub(replace, s) + '"' + + +def py_encode_basestring_ascii(s): + """Return an ASCII-only JSON representation of a Python string + + """ + if isinstance(s, str) and HAS_UTF8.search(s) is not None: + s = s.decode('utf-8') + def replace(match): + s = match.group(0) + try: + return ESCAPE_DCT[s] + except KeyError: + n = ord(s) + if n < 0x10000: + #return '\\u{0:04x}'.format(n) + return '\\u%04x' % (n,) + else: + # surrogate pair + n -= 0x10000 + s1 = 0xd800 | ((n >> 10) & 0x3ff) + s2 = 0xdc00 | (n & 0x3ff) + #return '\\u{0:04x}\\u{1:04x}'.format(s1, s2) + return '\\u%04x\\u%04x' % (s1, s2) + return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"' + + +encode_basestring_ascii = c_encode_basestring_ascii or py_encode_basestring_ascii + +class JSONEncoder(object): + """Extensible JSON encoder for Python data structures. + + Supports the following objects and types by default: + + +-------------------+---------------+ + | Python | JSON | + +===================+===============+ + | dict | object | + +-------------------+---------------+ + | list, tuple | array | + +-------------------+---------------+ + | str, unicode | string | + +-------------------+---------------+ + | int, long, float | number | + +-------------------+---------------+ + | True | true | + +-------------------+---------------+ + | False | false | + +-------------------+---------------+ + | None | null | + +-------------------+---------------+ + + To extend this to recognize other objects, subclass and implement a + ``.default()`` method with another method that returns a serializable + object for ``o`` if possible, otherwise it should call the superclass + implementation (to raise ``TypeError``). + + """ + item_separator = ', ' + key_separator = ': ' + def __init__(self, skipkeys=False, ensure_ascii=True, + check_circular=True, allow_nan=True, sort_keys=False, + indent=None, separators=None, encoding='utf-8', default=None): + """Constructor for JSONEncoder, with sensible defaults. + + If skipkeys is false, then it is a TypeError to attempt + encoding of keys that are not str, int, long, float or None. If + skipkeys is True, such items are simply skipped. + + If ensure_ascii is true, the output is guaranteed to be str + objects with all incoming unicode characters escaped. If + ensure_ascii is false, the output will be unicode object. + + If check_circular is true, then lists, dicts, and custom encoded + objects will be checked for circular references during encoding to + prevent an infinite recursion (which would cause an OverflowError). + Otherwise, no such check takes place. + + If allow_nan is true, then NaN, Infinity, and -Infinity will be + encoded as such. This behavior is not JSON specification compliant, + but is consistent with most JavaScript based encoders and decoders. + Otherwise, it will be a ValueError to encode such floats. + + If sort_keys is true, then the output of dictionaries will be + sorted by key; this is useful for regression tests to ensure + that JSON serializations can be compared on a day-to-day basis. + + If indent is a non-negative integer, then JSON array + elements and object members will be pretty-printed with that + indent level. An indent level of 0 will only insert newlines. + None is the most compact representation. + + If specified, separators should be a (item_separator, key_separator) + tuple. The default is (', ', ': '). To get the most compact JSON + representation you should specify (',', ':') to eliminate whitespace. + + If specified, default is a function that gets called for objects + that can't otherwise be serialized. It should return a JSON encodable + version of the object or raise a ``TypeError``. + + If encoding is not None, then all input strings will be + transformed into unicode using that encoding prior to JSON-encoding. + The default is UTF-8. + + """ + + self.skipkeys = skipkeys + self.ensure_ascii = ensure_ascii + self.check_circular = check_circular + self.allow_nan = allow_nan + self.sort_keys = sort_keys + self.indent = indent + if separators is not None: + self.item_separator, self.key_separator = separators + if default is not None: + self.default = default + self.encoding = encoding + + def default(self, o): + """Implement this method in a subclass such that it returns + a serializable object for ``o``, or calls the base implementation + (to raise a ``TypeError``). + + For example, to support arbitrary iterators, you could + implement default like this:: + + def default(self, o): + try: + iterable = iter(o) + except TypeError: + pass + else: + return list(iterable) + return JSONEncoder.default(self, o) + + """ + raise TypeError(repr(o) + " is not JSON serializable") + + def encode(self, o): + """Return a JSON string representation of a Python data structure. + + >>> JSONEncoder().encode({"foo": ["bar", "baz"]}) + '{"foo": ["bar", "baz"]}' + + """ + # This is for extremely simple cases and benchmarks. + if isinstance(o, basestring): + if isinstance(o, str): + _encoding = self.encoding + if (_encoding is not None + and not (_encoding == 'utf-8')): + o = o.decode(_encoding) + if self.ensure_ascii: + return encode_basestring_ascii(o) + else: + return encode_basestring(o) + # This doesn't pass the iterator directly to ''.join() because the + # exceptions aren't as detailed. The list call should be roughly + # equivalent to the PySequence_Fast that ''.join() would do. + chunks = self.iterencode(o, _one_shot=True) + if not isinstance(chunks, (list, tuple)): + chunks = list(chunks) + return ''.join(chunks) + + def iterencode(self, o, _one_shot=False): + """Encode the given object and yield each string + representation as available. + + For example:: + + for chunk in JSONEncoder().iterencode(bigobject): + mysocket.write(chunk) + + """ + if self.check_circular: + markers = {} + else: + markers = None + if self.ensure_ascii: + _encoder = encode_basestring_ascii + else: + _encoder = encode_basestring + if self.encoding != 'utf-8': + def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding): + if isinstance(o, str): + o = o.decode(_encoding) + return _orig_encoder(o) + + def floatstr(o, allow_nan=self.allow_nan, _repr=FLOAT_REPR, _inf=INFINITY, _neginf=-INFINITY): + # Check for specials. Note that this type of test is processor- and/or + # platform-specific, so do tests which don't depend on the internals. + + if o != o: + text = 'NaN' + elif o == _inf: + text = 'Infinity' + elif o == _neginf: + text = '-Infinity' + else: + return _repr(o) + + if not allow_nan: + raise ValueError( + "Out of range float values are not JSON compliant: " + + repr(o)) + + return text + + + if _one_shot and c_make_encoder is not None and not self.indent and not self.sort_keys: + _iterencode = c_make_encoder( + markers, self.default, _encoder, self.indent, + self.key_separator, self.item_separator, self.sort_keys, + self.skipkeys, self.allow_nan) + else: + _iterencode = _make_iterencode( + markers, self.default, _encoder, self.indent, floatstr, + self.key_separator, self.item_separator, self.sort_keys, + self.skipkeys, _one_shot) + return _iterencode(o, 0) + +def _make_iterencode(markers, _default, _encoder, _indent, _floatstr, _key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot, + ## HACK: hand-optimized bytecode; turn globals into locals + False=False, + True=True, + ValueError=ValueError, + basestring=basestring, + dict=dict, + float=float, + id=id, + int=int, + isinstance=isinstance, + list=list, + long=long, + str=str, + tuple=tuple, + ): + + def _iterencode_list(lst, _current_indent_level): + if not lst: + yield '[]' + return + if markers is not None: + markerid = id(lst) + if markerid in markers: + raise ValueError("Circular reference detected") + markers[markerid] = lst + buf = '[' + if _indent is not None: + _current_indent_level += 1 + newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) + separator = _item_separator + newline_indent + buf += newline_indent + else: + newline_indent = None + separator = _item_separator + first = True + for value in lst: + if first: + first = False + else: + buf = separator + if isinstance(value, basestring): + yield buf + _encoder(value) + elif value is None: + yield buf + 'null' + elif value is True: + yield buf + 'true' + elif value is False: + yield buf + 'false' + elif isinstance(value, (int, long)): + yield buf + str(value) + elif isinstance(value, float): + yield buf + _floatstr(value) + else: + yield buf + if isinstance(value, (list, tuple)): + chunks = _iterencode_list(value, _current_indent_level) + elif isinstance(value, dict): + chunks = _iterencode_dict(value, _current_indent_level) + else: + chunks = _iterencode(value, _current_indent_level) + for chunk in chunks: + yield chunk + if newline_indent is not None: + _current_indent_level -= 1 + yield '\n' + (' ' * (_indent * _current_indent_level)) + yield ']' + if markers is not None: + del markers[markerid] + + def _iterencode_dict(dct, _current_indent_level): + if not dct: + yield '{}' + return + if markers is not None: + markerid = id(dct) + if markerid in markers: + raise ValueError("Circular reference detected") + markers[markerid] = dct + yield '{' + if _indent is not None: + _current_indent_level += 1 + newline_indent = '\n' + (' ' * (_indent * _current_indent_level)) + item_separator = _item_separator + newline_indent + yield newline_indent + else: + newline_indent = None + item_separator = _item_separator + first = True + if _sort_keys: + items = dct.items() + items.sort(key=lambda kv: kv[0]) + else: + items = dct.iteritems() + for key, value in items: + if isinstance(key, basestring): + pass + # JavaScript is weakly typed for these, so it makes sense to + # also allow them. Many encoders seem to do something like this. + elif isinstance(key, float): + key = _floatstr(key) + elif key is True: + key = 'true' + elif key is False: + key = 'false' + elif key is None: + key = 'null' + elif isinstance(key, (int, long)): + key = str(key) + elif _skipkeys: + continue + else: + raise TypeError("key " + repr(key) + " is not a string") + if first: + first = False + else: + yield item_separator + yield _encoder(key) + yield _key_separator + if isinstance(value, basestring): + yield _encoder(value) + elif value is None: + yield 'null' + elif value is True: + yield 'true' + elif value is False: + yield 'false' + elif isinstance(value, (int, long)): + yield str(value) + elif isinstance(value, float): + yield _floatstr(value) + else: + if isinstance(value, (list, tuple)): + chunks = _iterencode_list(value, _current_indent_level) + elif isinstance(value, dict): + chunks = _iterencode_dict(value, _current_indent_level) + else: + chunks = _iterencode(value, _current_indent_level) + for chunk in chunks: + yield chunk + if newline_indent is not None: + _current_indent_level -= 1 + yield '\n' + (' ' * (_indent * _current_indent_level)) + yield '}' + if markers is not None: + del markers[markerid] + + def _iterencode(o, _current_indent_level): + if isinstance(o, basestring): + yield _encoder(o) + elif o is None: + yield 'null' + elif o is True: + yield 'true' + elif o is False: + yield 'false' + elif isinstance(o, (int, long)): + yield str(o) + elif isinstance(o, float): + yield _floatstr(o) + elif isinstance(o, (list, tuple)): + for chunk in _iterencode_list(o, _current_indent_level): + yield chunk + elif isinstance(o, dict): + for chunk in _iterencode_dict(o, _current_indent_level): + yield chunk + else: + if markers is not None: + markerid = id(o) + if markerid in markers: + raise ValueError("Circular reference detected") + markers[markerid] = o + o = _default(o) + for chunk in _iterencode(o, _current_indent_level): + yield chunk + if markers is not None: + del markers[markerid] + + return _iterencode diff --git a/resources/lib/simplejson/scanner.py b/resources/lib/simplejson/scanner.py new file mode 100644 index 0000000..adbc6ec --- /dev/null +++ b/resources/lib/simplejson/scanner.py @@ -0,0 +1,65 @@ +"""JSON token scanner +""" +import re +try: + from simplejson._speedups import make_scanner as c_make_scanner +except ImportError: + c_make_scanner = None + +__all__ = ['make_scanner'] + +NUMBER_RE = re.compile( + r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?', + (re.VERBOSE | re.MULTILINE | re.DOTALL)) + +def py_make_scanner(context): + parse_object = context.parse_object + parse_array = context.parse_array + parse_string = context.parse_string + match_number = NUMBER_RE.match + encoding = context.encoding + strict = context.strict + parse_float = context.parse_float + parse_int = context.parse_int + parse_constant = context.parse_constant + object_hook = context.object_hook + + def _scan_once(string, idx): + try: + nextchar = string[idx] + except IndexError: + raise StopIteration + + if nextchar == '"': + return parse_string(string, idx + 1, encoding, strict) + elif nextchar == '{': + return parse_object((string, idx + 1), encoding, strict, _scan_once, object_hook) + elif nextchar == '[': + return parse_array((string, idx + 1), _scan_once) + elif nextchar == 'n' and string[idx:idx + 4] == 'null': + return None, idx + 4 + elif nextchar == 't' and string[idx:idx + 4] == 'true': + return True, idx + 4 + elif nextchar == 'f' and string[idx:idx + 5] == 'false': + return False, idx + 5 + + m = match_number(string, idx) + if m is not None: + integer, frac, exp = m.groups() + if frac or exp: + res = parse_float(integer + (frac or '') + (exp or '')) + else: + res = parse_int(integer) + return res, m.end() + elif nextchar == 'N' and string[idx:idx + 3] == 'NaN': + return parse_constant('NaN'), idx + 3 + elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity': + return parse_constant('Infinity'), idx + 8 + elif nextchar == '-' and string[idx:idx + 9] == '-Infinity': + return parse_constant('-Infinity'), idx + 9 + else: + raise StopIteration + + return _scan_once + +make_scanner = c_make_scanner or py_make_scanner diff --git a/resources/lib/simplejson/tool.py b/resources/lib/simplejson/tool.py new file mode 100644 index 0000000..9044331 --- /dev/null +++ b/resources/lib/simplejson/tool.py @@ -0,0 +1,37 @@ +r"""Command-line tool to validate and pretty-print JSON + +Usage:: + + $ echo '{"json":"obj"}' | python -m simplejson.tool + { + "json": "obj" + } + $ echo '{ 1.2:3.4}' | python -m simplejson.tool + Expecting property name: line 1 column 2 (char 2) + +""" +import sys +import simplejson + +def main(): + if len(sys.argv) == 1: + infile = sys.stdin + outfile = sys.stdout + elif len(sys.argv) == 2: + infile = open(sys.argv[1], 'rb') + outfile = sys.stdout + elif len(sys.argv) == 3: + infile = open(sys.argv[1], 'rb') + outfile = open(sys.argv[2], 'wb') + else: + raise SystemExit(sys.argv[0] + " [infile [outfile]]") + try: + obj = simplejson.load(infile) + except ValueError, e: + raise SystemExit(e) + simplejson.dump(obj, outfile, sort_keys=True, indent=4) + outfile.write('\n') + + +if __name__ == '__main__': + main() diff --git a/resources/lib/transmissionrpc-0.3-python2.4.patch b/resources/lib/transmissionrpc-0.3-python2.4.patch new file mode 100644 index 0000000..d9b84d4 --- /dev/null +++ b/resources/lib/transmissionrpc-0.3-python2.4.patch @@ -0,0 +1,80 @@ +diff -rupN transmissionrpc-0.3/transmission.py transmissionrpc/transmission.py +--- transmissionrpc-0.3/transmission.py 2009-12-10 16:39:33.134130829 -0500 ++++ transmissionrpc/transmission.py 2009-12-10 16:45:37.385258836 -0500 +@@ -69,7 +69,7 @@ class Torrent(object): + wanted = self.fields['wanted'] + index = 1 + for item in zip(indicies, files, priorities, wanted): +- selected = True if item[3] else False ++ selected = bool(item[3]) + priority = PRIORITY[item[2]] + result[item[0]] = { + 'selected': selected, +@@ -252,29 +252,30 @@ class Client(object): + while True: + error_data = "" + try: +- self._debug_request(request) +- socket.setdefaulttimeout(10) +- if (sys.version_info[0] == 2 and sys.version_info[1] > 5) or sys.version_info[0] > 2: +- response = urllib2.urlopen(request, timeout=60) +- else: +- response = urllib2.urlopen(request) +- break +- except urllib2.HTTPError, error: +- error_data = error.read() +- if error.code == 409: +- logger.info('Server responded with 409, trying to set session-id.') +- if request_count > 1: +- raise TransmissionError('Session ID negotiation failed.', error) +- if 'X-Transmission-Session-Id' in error.headers: +- self.sessionid = error.headers['X-Transmission-Session-Id'] +- request.add_header('X-Transmission-Session-Id', self.sessionid) ++ try: ++ self._debug_request(request) ++ socket.setdefaulttimeout(10) ++ if (sys.version_info[0] == 2 and sys.version_info[1] > 5) or sys.version_info[0] > 2: ++ response = urllib2.urlopen(request, timeout=60) + else: +- raise TransmissionError('Unknown conflict.', error) +- except urllib2.URLError, error: +- raise TransmissionError('Failed to connect to daemon.', error) +- except httplib.BadStatusLine, error: +- if (request_count > 1): +- raise TransmissionError('Failed to request %s "%s".' % (self.url, query), error) ++ response = urllib2.urlopen(request) ++ break ++ except urllib2.HTTPError, error: ++ error_data = error.read() ++ if error.code == 409: ++ logger.info('Server responded with 409, trying to set session-id.') ++ if request_count > 1: ++ raise TransmissionError('Session ID negotiation failed.', error) ++ if 'X-Transmission-Session-Id' in error.headers: ++ self.sessionid = error.headers['X-Transmission-Session-Id'] ++ request.add_header('X-Transmission-Session-Id', self.sessionid) ++ else: ++ raise TransmissionError('Unknown conflict.', error) ++ except urllib2.URLError, error: ++ raise TransmissionError('Failed to connect to daemon.', error) ++ except httplib.BadStatusLine, error: ++ if (request_count > 1): ++ raise TransmissionError('Failed to request %s "%s".' % (self.url, query), error) + finally: + if error_data: + self._debug_response(error, error_data) +diff -rupN transmissionrpc-0.3/utils.py transmissionrpc/utils.py +--- transmissionrpc-0.3/utils.py 2009-12-10 16:39:33.134130829 -0500 ++++ transmissionrpc/utils.py 2009-12-10 16:45:37.386133947 -0500 +@@ -64,7 +64,10 @@ def rpc_bool(arg): + arg = bool(int(arg)) + except: + arg = arg.lower() in [u'true', u'yes'] +- return 1 if bool(arg) else 0 ++ if bool(arg): ++ return 1 ++ else: ++ return 0 + + TR_TYPE_MAP = { + 'number' : int, diff --git a/resources/lib/transmissionrpc-0.3-python2.4/__init__.py b/resources/lib/transmissionrpc-0.3-python2.4/__init__.py new file mode 100644 index 0000000..f4afa02 --- /dev/null +++ b/resources/lib/transmissionrpc-0.3-python2.4/__init__.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# 2008-08, Erik Svensson + +from constants import * +from transmission import TransmissionError, Torrent, Session, Client + +__author__ = u'Erik Svensson ' +__version__ = u'0.3' +__copyright__ = u'Copyright (c) 2008 Erik Svensson' +__license__ = u'MIT' diff --git a/resources/lib/transmissionrpc-0.3-python2.4/constants.py b/resources/lib/transmissionrpc-0.3-python2.4/constants.py new file mode 100755 index 0000000..96ccc01 --- /dev/null +++ b/resources/lib/transmissionrpc-0.3-python2.4/constants.py @@ -0,0 +1,230 @@ +# -*- coding: utf-8 -*- +# 2008-07, Erik Svensson + +import logging + +logger = logging.getLogger('transmissionrpc') +logger.setLevel(logging.ERROR) + +def mirror_dict(d): + d.update(dict((v, k) for k, v in d.iteritems())) + return d + +DEFAULT_PORT = 9091 + +TR_STATUS_CHECK_WAIT = (1<<0) +TR_STATUS_CHECK = (1<<1) +TR_STATUS_DOWNLOAD = (1<<2) +TR_STATUS_SEED = (1<<3) +TR_STATUS_STOPPED = (1<<4) + +STATUS = mirror_dict({ + 'check pending' : TR_STATUS_CHECK_WAIT, + 'checking' : TR_STATUS_CHECK, + 'downloading' : TR_STATUS_DOWNLOAD, + 'seeding' : TR_STATUS_SEED, + 'stopped' : TR_STATUS_STOPPED, +}) + +TR_PRI_LOW = -1 +TR_PRI_NORMAL = 0 +TR_PRI_HIGH = 1 + +PRIORITY = mirror_dict({ + 'low' : TR_PRI_LOW, + 'normal' : TR_PRI_NORMAL, + 'high' : TR_PRI_HIGH +}) + +TR_RATIOLIMIT_GLOBAL = 0 # follow the global settings +TR_RATIOLIMIT_SINGLE = 1 # override the global settings, seeding until a certain ratio +TR_RATIOLIMIT_UNLIMITED = 2 # override the global settings, seeding regardless of ratio + +RATIO_LIMIT = mirror_dict({ + 'global' : TR_RATIOLIMIT_GLOBAL, + 'single' : TR_RATIOLIMIT_SINGLE, + 'unlimeted' : TR_RATIOLIMIT_UNLIMITED +}) + +# A note on argument maps +# These maps are used to verify *-set methods. The information is structured in +# a tree. +# set +- - [, , , , ] +# | +- - [, , , , ] +# | +# get +- - [, , , , ] +# +- - [, , , , ] + +# Arguments for torrent methods +TORRENT_ARGS = { + 'get' : { + 'activityDate': ('number', 1, None, None, None), + 'addedDate': ('number', 1, None, None, None), + 'announceResponse': ('string', 1, None, None, None), + 'announceURL': ('string', 1, None, None, None), + 'bandwidthPriority': ('number', 5, None, None, None), + 'comment': ('string', 1, None, None, None), + 'corruptEver': ('number', 1, None, None, None), + 'creator': ('string', 1, None, None, None), + 'dateCreated': ('number', 1, None, None, None), + 'desiredAvailable': ('number', 1, None, None, None), + 'doneDate': ('number', 1, None, None, None), + 'downloadDir': ('string', 4, None, None, None), + 'downloadedEver': ('number', 1, None, None, None), + 'downloaders': ('number', 4, None, None, None), + 'downloadLimit': ('number', 1, None, None, None), + 'downloadLimited': ('boolean', 5, None, None, None), + 'downloadLimitMode': ('number', 1, 5, None, None), + 'error': ('number', 1, None, None, None), + 'errorString': ('number', 1, None, None, None), + 'eta': ('number', 1, None, None, None), + 'files': ('array', 1, None, None, None), + 'fileStats': ('array', 5, None, None, None), + 'hashString': ('string', 1, None, None, None), + 'haveUnchecked': ('number', 1, None, None, None), + 'haveValid': ('number', 1, None, None, None), + 'honorsSessionLimits': ('boolean', 5, None, None, None), + 'id': ('number', 1, None, None, None), + 'isPrivate': ('boolean', 1, None, None, None), + 'lastAnnounceTime': ('number', 1, None, None, None), + 'lastScrapeTime': ('number', 1, None, None, None), + 'leechers': ('number', 1, None, None, None), + 'leftUntilDone': ('number', 1, None, None, None), + 'manualAnnounceTime': ('number', 1, None, None, None), + 'maxConnectedPeers': ('number', 1, None, None, None), + 'name': ('string', 1, None, None, None), + 'nextAnnounceTime': ('number', 1, None, None, None), + 'nextScrapeTime': ('number', 1, None, None, None), + 'peer-limit': ('number', 5, None, None, None), + 'peers': ('array', 2, None, None, None), + 'peersConnected': ('number', 1, None, None, None), + 'peersFrom': ('object', 1, None, None, None), + 'peersGettingFromUs': ('number', 1, None, None, None), + 'peersKnown': ('number', 1, None, None, None), + 'peersSendingToUs': ('number', 1, None, None, None), + 'percentDone': ('double', 5, None, None, None), + 'pieces': ('string', 5, None, None, None), + 'pieceCount': ('number', 1, None, None, None), + 'pieceSize': ('number', 1, None, None, None), + 'priorities': ('array', 1, None, None, None), + 'rateDownload': ('number', 1, None, None, None), + 'rateUpload': ('number', 1, None, None, None), + 'recheckProgress': ('double', 1, None, None, None), + 'scrapeResponse': ('string', 1, None, None, None), + 'scrapeURL': ('string', 1, None, None, None), + 'seeders': ('number', 1, None, None, None), + 'seedRatioLimit': ('double', 5, None, None, None), + 'seedRatioMode': ('number', 5, None, None, None), + 'sizeWhenDone': ('number', 1, None, None, None), + 'startDate': ('number', 1, None, None, None), + 'status': ('number', 1, None, None, None), + 'swarmSpeed': ('number', 1, None, None, None), + 'timesCompleted': ('number', 1, None, None, None), + 'trackers': ('array', 1, None, None, None), + 'totalSize': ('number', 1, None, None, None), + 'torrentFile': ('string', 5, None, None, None), + 'uploadedEver': ('number', 1, None, None, None), + 'uploadLimit': ('number', 1, None, None, None), + 'uploadLimitMode': ('number', 1, 5, None, None), + 'uploadLimited': ('boolean', 5, None, None, None), + 'uploadRatio': ('double', 1, None, None, None), + 'wanted': ('array', 1, None, None, None), + 'webseeds': ('array', 1, None, None, None), + 'webseedsSendingToUs': ('number', 1, None, None, None), + }, + 'set': { + 'bandwidthPriority': ('number', 5, None, None, None), + 'downloadLimit': ('number', 5, None, 'speed-limit-down', None), + 'downloadLimited': ('boolean', 5, None, 'speed-limit-down-enabled', None), + 'files-wanted': ('array', 1, None, None, None), + 'files-unwanted': ('array', 1, None, None, None), + 'honorsSessionLimits': ('boolean', 5, None, None, None), + 'ids': ('array', 1, None, None, None), + 'peer-limit': ('number', 1, None, None, None), + 'priority-high': ('array', 1, None, None, None), + 'priority-low': ('array', 1, None, None, None), + 'priority-normal': ('array', 1, None, None, None), + 'seedRatioLimit': ('double', 5, None, None, None), + 'seedRatioMode': ('number', 5, None, None, None), + 'speed-limit-down': ('number', 1, 5, None, 'downloadLimit'), + 'speed-limit-down-enabled': ('boolean', 1, 5, None, 'downloadLimited'), + 'speed-limit-up': ('number', 1, 5, None, 'uploadLimit'), + 'speed-limit-up-enabled': ('boolean', 1, 5, None, 'uploadLimited'), + 'uploadLimit': ('number', 5, None, 'speed-limit-up', None), + 'uploadLimited': ('boolean', 5, None, 'speed-limit-up-enabled', None), + }, + 'add': { + 'download-dir': ('string', 1, None, None, None), + 'filename': ('string', 1, None, None, None), + 'files-wanted': ('array', 1, None, None, None), + 'files-unwanted': ('array', 1, None, None, None), + 'metainfo': ('string', 1, None, None, None), + 'paused': ('boolean', 1, None, None, None), + 'peer-limit': ('number', 1, None, None, None), + 'priority-high': ('array', 1, None, None, None), + 'priority-low': ('array', 1, None, None, None), + 'priority-normal': ('array', 1, None, None, None), + } +} + +# Arguments for session methods +SESSION_ARGS = { + 'get': { + "alt-speed-down": ('number', 5, None, None, None), + "alt-speed-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-begin": ('number', 5, None, None, None), + "alt-speed-time-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-end": ('number', 5, None, None, None), + "alt-speed-time-day": ('number', 5, None, None, None), + "alt-speed-up": ('number', 5, None, None, None), + "blocklist-enabled": ('boolean', 5, None, None, None), + "blocklist-size": ('number', 5, None, None, None), + "encryption": ('string', 1, None, None, None), + "download-dir": ('string', 1, None, None, None), + "peer-limit": ('number', 1, 5, None, None), + "peer-limit-global": ('number', 5, None, None, None), + "peer-limit-per-torrent": ('number', 5, None, None, None), + "pex-allowed": ('boolean', 1, 5, None, None), + "pex-enabled": ('boolean', 5, None, None, None), + "port": ('number', 1, 5, None, None), + "peer-port": ('number', 5, None, None, None), + "peer-port-random-on-start": ('boolean', 5, None, None, None), + "port-forwarding-enabled": ('boolean', 1, None, None, None), + "rpc-version": ('number', 4, None, None, None), + "rpc-version-minimum": ('number', 4, None, None, None), + "seedRatioLimit": ('double', 5, None, None, None), + "seedRatioLimited": ('boolean', 5, None, None, None), + "speed-limit-down": ('number', 1, None, None, None), + "speed-limit-down-enabled": ('boolean', 1, None, None, None), + "speed-limit-up": ('number', 1, None, None, None), + "speed-limit-up-enabled": ('boolean', 1, None, None, None), + "version": ('string', 3, None, None, None), + }, + 'set': { + "alt-speed-down": ('number', 5, None, None, None), + "alt-speed-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-begin": ('number', 5, None, None, None), + "alt-speed-time-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-end": ('number', 5, None, None, None), + "alt-speed-time-day": ('number', 5, None, None, None), + "alt-speed-up": ('number', 5, None, None, None), + "blocklist-enabled": ('boolean', 5, None, None, None), + "encryption": ('string', 1, None, None, None), + "download-dir": ('string', 1, None, None, None), + "peer-limit": ('number', 1, 5, None, 'peer-limit-global'), + "peer-limit-global": ('number', 5, None, 'peer-limit', None), + "peer-limit-per-torrent": ('number', 5, None, None, None), + "pex-allowed": ('boolean', 1, 5, None, 'pex-enabled'), + "pex-enabled": ('boolean', 5, None, 'pex-allowed', None), + "port": ('number', 1, 5, None, 'peer-port'), + "peer-port": ('number', 5, None, 'port', None), + "peer-port-random-on-start": ('boolean', 5, None, None, None), + "port-forwarding-enabled": ('boolean', 1, None, None, None), + "seedRatioLimit": ('double', 5, None, None, None), + "seedRatioLimited": ('boolean', 5, None, None, None), + "speed-limit-down": ('number', 1, None, None, None), + "speed-limit-down-enabled": ('boolean', 1, None, None, None), + "speed-limit-up": ('number', 1, None, None, None), + "speed-limit-up-enabled": ('boolean', 1, None, None, None), + }, +} diff --git a/resources/lib/transmissionrpc-0.3-python2.4/transmission.py b/resources/lib/transmissionrpc-0.3-python2.4/transmission.py new file mode 100755 index 0000000..fb3867d --- /dev/null +++ b/resources/lib/transmissionrpc-0.3-python2.4/transmission.py @@ -0,0 +1,606 @@ +# -*- coding: utf-8 -*- +# 2008-07, Erik Svensson + +import sys, os, time, datetime +import re +import httplib, urllib2, base64, socket + +try: + import json +except ImportError: + import simplejson as json + +from constants import * +from utils import * + +class TransmissionError(Exception): + def __init__(self, message='', original=None): + Exception.__init__(self, message) + self.message = message + self.original = original + + def __str__(self): + if self.original: + original_name = type(self.original).__name__ + return '%s Original exception: %s, "%s"' % (self.message, original_name, self.original.args) + else: + return self.args + +class Torrent(object): + """ + Torrent is a class holding the data raceived from Transmission regarding a bittorrent transfer. + All fetched torrent fields are accessable through this class using attributes. + This class has a few convenience properties using the torrent data. + """ + + def __init__(self, fields): + if 'id' not in fields: + raise ValueError('Torrent requires an id') + self.fields = {} + self.update(fields) + + def __repr__(self): + return '' % (self.fields['id'], self.fields['name']) + + def __str__(self): + return 'torrent %s' % self.fields['name'] + + def update(self, other): + """Update the torrent data from a Transmission arguments dictinary""" + fields = None + if isinstance(other, dict): + fields = other + elif isinstance(other, Torrent): + fields = other.fields + else: + raise ValueError('Cannot update with supplied data') + for k, v in fields.iteritems(): + self.fields[k.replace('-', '_')] = v + + def files(self): + """ + Get list of files for this torrent. This function returns a dictionary with file information for each file. + """ + result = {} + if 'files' in self.fields: + indicies = xrange(len(self.fields['files'])) + files = self.fields['files'] + priorities = self.fields['priorities'] + wanted = self.fields['wanted'] + index = 1 + for item in zip(indicies, files, priorities, wanted): + selected = bool(item[3]) + priority = PRIORITY[item[2]] + result[item[0]] = { + 'selected': selected, + 'priority': priority, + 'size': item[1]['length'], + 'name': item[1]['name'], + 'completed': item[1]['bytesCompleted']} + return result + + def __getattr__(self, name): + try: + return self.fields[name] + except KeyError, e: + raise AttributeError('No attribute %s' % name) + + @property + def status(self): + """Get the status as string.""" + return STATUS[self.fields['status']] + + @property + def progress(self): + """Get the download progress in percent as float.""" + try: + return 100.0 * (self.fields['sizeWhenDone'] - self.fields['leftUntilDone']) / float(self.fields['sizeWhenDone']) + except ZeroDivisionError: + return 0.0 + + @property + def ratio(self): + """Get the upload/download ratio.""" + try: + return self.fields['uploadedEver'] / float(self.fields['downloadedEver']) + except ZeroDivisionError: + return 0.0 + + @property + def eta(self): + """Get the "eta" as datetime.timedelta.""" + eta = self.fields['eta'] + if eta >= 0: + return datetime.timedelta(seconds=eta) + else: + ValueError('eta not valid') + + @property + def date_active(self): + """Get the attribute "activityDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['activityDate']) + + @property + def date_added(self): + """Get the attribute "addedDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['addedDate']) + + @property + def date_started(self): + """Get the attribute "startDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['startDate']) + + @property + def date_done(self): + """Get the attribute "doneDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['doneDate']) + + def format_eta(self): + """Returns the attribute "eta" formatted as a string.""" + eta = self.fields['eta'] + if eta == -1: + return 'not available' + elif eta == -2: + return 'unknown' + else: + return format_timedelta(self.eta) + +class Session(object): + """ + Session is a class holding the session data for a Transmission daemon. + + Access the session field can be done through attributes. + The attributes available are the same as the session arguments in the + Transmission RPC specification, but with underscore instead of hypen. + ``download-dir`` -> ``download_dir``. + """ + + def __init__(self, fields={}): + self.fields = {} + self.update(fields) + + def update(self, other): + """Update the session data from a session arguments dictinary""" + + fields = None + if isinstance(other, dict): + fields = other + elif isinstance(other, Session): + fields = other.fields + else: + raise ValueError('Cannot update with supplied data') + + for k, v in fields.iteritems(): + self.fields[k.replace('-', '_')] = v + + def __getattr__(self, name): + try: + return self.fields[name] + except KeyError, e: + raise AttributeError('No attribute %s' % name) + + def __str__(self): + text = '' + for k, v in self.fields.iteritems(): + text += "% 32s: %s\n" % (k[-32:], v) + return text + +class Client(object): + """ + This is it. This class implements the json-RPC protocol to communicate with Transmission. + """ + + def __init__(self, address='localhost', port=DEFAULT_PORT, user=None, password=None): + base_url = 'http://' + address + ':' + str(port) + self.url = base_url + '/transmission/rpc' + if user and password: + password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() + password_manager.add_password(realm=None, uri=self.url, user=user, passwd=password) + opener = urllib2.build_opener( + urllib2.HTTPBasicAuthHandler(password_manager) + , urllib2.HTTPDigestAuthHandler(password_manager) + ) + urllib2.install_opener(opener) + elif user or password: + logger.warning('Either user or password missing, not using authentication.') + self._sequence = 0 + self.session = Session() + self.sessionid = 0 + self.protocol_version = None + self.get_session() + self.torrent_get_arguments = get_arguments('torrent-get' + , self.rpc_version) + + def _debug_request(self, request): + logger.debug( + json.dumps( + { + 'request': { + 'url': request.get_full_url(), + 'request-headers': dict(request.header_items()), + 'request-data': json.loads(request.data), + } + }, + indent=2 + ) + ) + + def _debug_response(self, response, response_data): + try: + response_data = json.loads(response_data) + except: + pass + logger.debug( + json.dumps( + { + 'response': { + 'url': response.url, + 'code': response.code, + 'msg': response.msg, + 'headers': dict(response.headers), + 'data': response_data, + } + }, + indent=2 + ) + ) + + def _http_query(self, query): + headers = {'X-Transmission-Session-Id': self.sessionid} + request = urllib2.Request(self.url, query, headers) + request_count = 0 + while True: + error_data = "" + try: + try: + self._debug_request(request) + socket.setdefaulttimeout(10) + if (sys.version_info[0] == 2 and sys.version_info[1] > 5) or sys.version_info[0] > 2: + response = urllib2.urlopen(request, timeout=60) + else: + response = urllib2.urlopen(request) + break + except urllib2.HTTPError, error: + error_data = error.read() + if error.code == 409: + logger.info('Server responded with 409, trying to set session-id.') + if request_count > 1: + raise TransmissionError('Session ID negotiation failed.', error) + if 'X-Transmission-Session-Id' in error.headers: + self.sessionid = error.headers['X-Transmission-Session-Id'] + request.add_header('X-Transmission-Session-Id', self.sessionid) + else: + raise TransmissionError('Unknown conflict.', error) + except urllib2.URLError, error: + raise TransmissionError('Failed to connect to daemon.', error) + except httplib.BadStatusLine, error: + if (request_count > 1): + raise TransmissionError('Failed to request %s "%s".' % (self.url, query), error) + finally: + if error_data: + self._debug_response(error, error_data) + request_count = request_count + 1 + result = response.read() + self._debug_response(response, result) + return result + + def _request(self, method, arguments={}, ids=[], require_ids = False): + """Send json-rpc request to Transmission using http POST""" + + if not isinstance(method, (str, unicode)): + raise ValueError('request takes method as string') + if not isinstance(arguments, dict): + raise ValueError('request takes arguments as dict') + ids = self._format_ids(ids) + if len(ids) > 0: + arguments['ids'] = ids + elif require_ids: + raise ValueError('request require ids') + + query = json.dumps({'tag': self._sequence, 'method': method + , 'arguments': arguments}) + logger.info(query) + self._sequence += 1 + start = time.time() + http_data = self._http_query(query) + elapsed = time.time() - start + logger.info('http request took %.3f s' % (elapsed)) + + try: + data = json.loads(http_data) + except ValueError, e: + logger.error('Error: ' + str(e)) + logger.error('Request: \"%s\"' % (query)) + logger.error('HTTP data: \"%s\"' % (http_data)) + raise + + logger.info(json.dumps(data, indent=2)) + + if data['result'] != 'success': + raise TransmissionError('Query failed with result \"%s\"' + % data['result']) + + results = {} + if method == 'torrent-get': + for item in data['arguments']['torrents']: + results[item['id']] = Torrent(item) + if self.protocol_version == 2 and 'peers' not in item: + self.protocol_version = 1 + elif method == 'torrent-add': + item = data['arguments']['torrent-added'] + results[item['id']] = Torrent(item) + elif method == 'session-get': + self._update_session(data['arguments']) + elif method == 'session-stats': + # older versions of T has the return data in "session-stats" + if 'session-stats' in data['arguments']: + self._update_session(data['arguments']['session-stats']) + else: + self._update_session(data['arguments']) + elif method in ('port-test', 'blocklist-update'): + results = data['arguments'] + else: + return None + + return results + + def _format_ids(self, args): + """Take things and make them valid torrent identifiers""" + ids = [] + + if isinstance(args, (int, long)): + ids.append(args) + elif isinstance(args, (str, unicode)): + for item in re.split(u'[ ,]+', args): + if len(item) == 0: + continue + addition = None + try: + # handle index + addition = [int(item)] + except ValueError: + pass + if not addition: + # handle hashes + try: + int(item, 16) + addition = [item] + except: + pass + if not addition: + # handle index ranges i.e. 5:10 + match = re.match(u'^(\d+):(\d+)$', item) + if match: + try: + idx_from = int(match.group(1)) + idx_to = int(match.group(2)) + addition = range(idx_from, idx_to + 1) + except: + pass + if not addition: + raise ValueError(u'Invalid torrent id, \"%s\"' % item) + ids.extend(addition) + elif isinstance(args, (list)): + for item in args: + ids.extend(self._format_ids(item)) + else: + raise ValueError(u'Invalid torrent id') + return ids + + def _update_session(self, data): + self.session.update(data) + + @property + def rpc_version(self): + if self.protocol_version == None: + if hasattr(self.session, 'rpc_version'): + self.protocol_version = self.session.rpc_version + elif hasattr(self.session, 'version'): + self.protocol_version = 3 + else: + self.protocol_version = 2 + return self.protocol_version + + def _rpc_version_warning(self, version): + if self.rpc_version < version: + logger.warning('Using feature not supported by server. RPC version for server %d, feature introduced in %d.' % (self.rpc_version, version)) + + def add(self, data, **kwargs): + """ + Add torrent to transfers list. Takes a base64 encoded .torrent file in data. + Additional arguments are: + + * `paused`, boolean, Whether to pause the transfer on add. + * `download_dir`, path, The directory where the downloaded + contents will be saved in. + * `peer_limit`, number, Limits the number of peers for this + transfer. + * `files_unwanted`, + * `files_wanted`, + * `priority_high`, + * `priority_low`, + * `priority_normal`, + """ + args = {'metainfo': data} + for key, value in kwargs.iteritems(): + argument = make_rpc_name(key) + (arg, val) = argument_value_convert('torrent-add', + argument, value, self.rpc_version) + args[arg] = val + return self._request('torrent-add', args) + + def add_url(self, torrent_url, **kwargs): + """ + Add torrent to transfers list. Takes a url to a .torrent file. + Additional arguments are: + + * `paused`, boolean, Whether to pause the transfer on add. + * `download_dir`, path, The directory where the downloaded + contents will be saved in. + * `peer_limit`, number, Limits the number of peers for this + transfer. + * `files_unwanted`, + * `files_wanted`, + * `priority_high`, + * `priority_low`, + * `priority_normal`, + """ + torrent_file = None + if os.path.exists(torrent_url): + torrent_file = open(torrent_url, 'r') + else: + try: + torrent_file = urllib2.urlopen(torrent_url) + except: + torrent_file = None + + if not torrent_file: + raise TransmissionError('File does not exist.') + + torrent_data = base64.b64encode(torrent_file.read()) + return self.add(torrent_data, **kwargs) + + def remove(self, ids, delete_data=False): + """ + remove torrent(s) with provided id(s). Local data is removed if + delete_data is True, otherwise not. + """ + self._rpc_version_warning(3) + self._request('torrent-remove', + {'delete-local-data':rpc_bool(delete_data)}, ids, True) + + def start(self, ids): + """start torrent(s) with provided id(s)""" + self._request('torrent-start', {}, ids, True) + + def stop(self, ids): + """stop torrent(s) with provided id(s)""" + self._request('torrent-stop', {}, ids, True) + + def verify(self, ids): + """verify torrent(s) with provided id(s)""" + self._request('torrent-verify', {}, ids, True) + + def reannounce(self, ids): + """reannounce torrent(s) with provided id(s)""" + self._rpc_version_warning(5) + self._request('torrent-reannounce', {}, ids, True) + + def info(self, ids=[], arguments={}): + """Get detailed information for torrent(s) with provided id(s).""" + if not arguments: + arguments = self.torrent_get_arguments + return self._request('torrent-get', {'fields': arguments}, ids) + + def get_files(self, ids=[]): + """ + Get list of files for provided torrent id(s). + This function returns a dictonary for each requested torrent id holding + the information about the files. + """ + fields = ['id', 'name', 'hashString', 'files', 'priorities', 'wanted'] + request_result = self._request('torrent-get', {'fields': fields}, ids) + result = {} + for id, torrent in request_result.iteritems(): + result[id] = torrent.files() + return result + + def set_files(self, items): + """ + Set file properties. Takes a dictonary with similar contents as the + result of get_files. + """ + if not isinstance(items, dict): + raise ValueError('Invalid file description') + for tid, files in items.iteritems(): + if not isinstance(files, dict): + continue + wanted = [] + unwanted = [] + priority_high = [] + priority_normal = [] + priority_low = [] + for fid, file in files.iteritems(): + if not isinstance(file, dict): + continue + if 'selected' in file and file['selected']: + wanted.append(fid) + else: + unwanted.append(fid) + if 'priority' in file: + if file['priority'] == 'high': + priority_high.append(fid) + elif file['priority'] == 'normal': + priority_normal.append(fid) + elif file['priority'] == 'low': + priority_low.append(fid) + self.change([tid], files_wanted = wanted + , files_unwanted = unwanted + , priority_high = priority_high + , priority_normal = priority_normal + , priority_low = priority_low) + + def list(self): + """list all torrents""" + fields = ['id', 'hashString', 'name', 'sizeWhenDone', 'leftUntilDone' + , 'eta', 'status', 'rateUpload', 'rateDownload', 'uploadedEver' + , 'downloadedEver'] + return self._request('torrent-get', {'fields': fields}) + + def change(self, ids, **kwargs): + """ + Change torrent parameters. This is the list of parameters that. + """ + args = {} + for key, value in kwargs.iteritems(): + argument = make_rpc_name(key) + (arg, val) = argument_value_convert('torrent-set' + , argument, value, self.rpc_version) + args[arg] = val + + if len(args) > 0: + self._request('torrent-set', args, ids, True) + else: + ValueError("No arguments to set") + + def get_session(self): + """Get session parameters""" + self._request('session-get') + return self.session + + def set_session(self, **kwargs): + """Set session parameters""" + args = {} + for key, value in kwargs.iteritems(): + if key == 'encryption' and value not in ['required', 'preferred', 'tolerated']: + raise ValueError('Invalid encryption value') + argument = make_rpc_name(key) + (arg, val) = argument_value_convert('session-set' + , argument, value, self.rpc_version) + args[arg] = val + if len(args) > 0: + self._request('session-set', args) + + def blocklist_update(self): + """Update block list. Returns the size of the block list.""" + self._rpc_version_warning(5) + result = self._request('blocklist-update') + if 'blocklist-size' in result: + return result['blocklist-size'] + return None + + def port_test(self): + """ + Tests to see if your incoming peer port is accessible from the + outside world. + """ + self._rpc_version_warning(5) + result = self._request('port-test') + if 'port-is-open' in result: + return result['port-is-open'] + return None + + def session_stats(self): + """Get session statistics""" + self._request('session-stats') + return self.session diff --git a/resources/lib/transmissionrpc-0.3-python2.4/utils.py b/resources/lib/transmissionrpc-0.3-python2.4/utils.py new file mode 100644 index 0000000..3e4099e --- /dev/null +++ b/resources/lib/transmissionrpc-0.3-python2.4/utils.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +# 2008-07, Erik Svensson + +import socket, datetime +import constants +from constants import logger + +UNITS = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB'] + +def format_size(size): + s = float(size) + i = 0 + while size >= 1024.0 and i < len(UNITS): + i += 1 + size /= 1024.0 + return (size, UNITS[i]) + +def format_speed(size): + (size, unit) = format_size(size) + return (size, unit + '/s') + +def format_timedelta(delta): + minutes, seconds = divmod(delta.seconds, 60) + hours, minutes = divmod(minutes, 60) + return '%d %02d:%02d:%02d' % (delta.days, hours, minutes, seconds) + +def format_timestamp(timestamp): + if timestamp > 0: + dt = datetime.datetime.fromtimestamp(timestamp) + return dt.isoformat(' ') + else: + return '-' + +class INetAddressError(Exception): + pass + +def inet_address(address, default_port, default_address='localhost'): + addr = address.split(':') + if len(addr) == 1: + try: + port = int(addr[0]) + addr = default_address + except: + addr = addr[0] + port = default_port + elif len(addr) == 2: + port = int(addr[1]) + if len(addr[0]) == 0: + addr = default_address + else: + addr = addr[0] + else: + addr = default_address + port = default_port + try: + socket.getaddrinfo(addr, port, socket.AF_INET, socket.SOCK_STREAM) + except socket.gaierror, e: + raise INetAddressError('Cannot look up address "%s".' % address) + return (addr, port) + +def rpc_bool(arg): + if isinstance(arg, (str, unicode)): + try: + arg = bool(int(arg)) + except: + arg = arg.lower() in [u'true', u'yes'] + if bool(arg): + return 1 + else: + return 0 + +TR_TYPE_MAP = { + 'number' : int, + 'string' : str, + 'double': float, + 'boolean' : rpc_bool, + 'array': list, + 'object': dict +} + +def make_python_name(name): + return name.replace('-', '_') + +def make_rpc_name(name): + return name.replace('_', '-') + +def argument_value_convert(method, argument, value, rpc_version): + if method in ('torrent-add', 'torrent-get', 'torrent-set'): + args = constants.TORRENT_ARGS[method[-3:]] + elif method in ('session-get', 'session-set'): + args = constants.SESSION_ARGS[method[-3:]] + else: + return ValueError('Method "%s" not supported' % (method)) + if argument in args: + info = args[argument] + invalid_version = True + while invalid_version: + invalid_version = False + replacement = None + if rpc_version < info[1]: + invalid_version = True + replacement = info[3] + if info[2] and info[2] <= rpc_version: + invalid_version = True + replacement = info[4] + if invalid_version: + if replacement: + logger.warning( + 'Replacing requested argument "%s" with "%s".' + % (argument, replacement)) + argument = replacement + info = args[argument] + else: + raise ValueError( + 'Method "%s" Argument "%s" does not exist in version %d.' + % (method, argument, rpc_version)) + return (argument, TR_TYPE_MAP[info[0]](value)) + else: + raise ValueError('Argument "%s" does not exists for method "%s".', + (argument, method)) + +def get_arguments(method, rpc_version): + if method in ('torrent-add', 'torrent-get', 'torrent-set'): + args = constants.TORRENT_ARGS[method[-3:]] + elif method in ('session-get', 'session-set'): + args = constants.SESSION_ARGS[method[-3:]] + else: + return ValueError('Method "%s" not supported' % (method)) + accessible = [] + for argument, info in args.iteritems(): + valid_version = True + if rpc_version < info[1]: + valid_version = False + if info[2] and info[2] <= rpc_version: + valid_version = False + if valid_version: + accessible.append(argument) + return accessible diff --git a/resources/lib/transmissionrpc-0.3/__init__.py b/resources/lib/transmissionrpc-0.3/__init__.py new file mode 100644 index 0000000..f4afa02 --- /dev/null +++ b/resources/lib/transmissionrpc-0.3/__init__.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# 2008-08, Erik Svensson + +from constants import * +from transmission import TransmissionError, Torrent, Session, Client + +__author__ = u'Erik Svensson ' +__version__ = u'0.3' +__copyright__ = u'Copyright (c) 2008 Erik Svensson' +__license__ = u'MIT' diff --git a/resources/lib/transmissionrpc-0.3/constants.py b/resources/lib/transmissionrpc-0.3/constants.py new file mode 100755 index 0000000..96ccc01 --- /dev/null +++ b/resources/lib/transmissionrpc-0.3/constants.py @@ -0,0 +1,230 @@ +# -*- coding: utf-8 -*- +# 2008-07, Erik Svensson + +import logging + +logger = logging.getLogger('transmissionrpc') +logger.setLevel(logging.ERROR) + +def mirror_dict(d): + d.update(dict((v, k) for k, v in d.iteritems())) + return d + +DEFAULT_PORT = 9091 + +TR_STATUS_CHECK_WAIT = (1<<0) +TR_STATUS_CHECK = (1<<1) +TR_STATUS_DOWNLOAD = (1<<2) +TR_STATUS_SEED = (1<<3) +TR_STATUS_STOPPED = (1<<4) + +STATUS = mirror_dict({ + 'check pending' : TR_STATUS_CHECK_WAIT, + 'checking' : TR_STATUS_CHECK, + 'downloading' : TR_STATUS_DOWNLOAD, + 'seeding' : TR_STATUS_SEED, + 'stopped' : TR_STATUS_STOPPED, +}) + +TR_PRI_LOW = -1 +TR_PRI_NORMAL = 0 +TR_PRI_HIGH = 1 + +PRIORITY = mirror_dict({ + 'low' : TR_PRI_LOW, + 'normal' : TR_PRI_NORMAL, + 'high' : TR_PRI_HIGH +}) + +TR_RATIOLIMIT_GLOBAL = 0 # follow the global settings +TR_RATIOLIMIT_SINGLE = 1 # override the global settings, seeding until a certain ratio +TR_RATIOLIMIT_UNLIMITED = 2 # override the global settings, seeding regardless of ratio + +RATIO_LIMIT = mirror_dict({ + 'global' : TR_RATIOLIMIT_GLOBAL, + 'single' : TR_RATIOLIMIT_SINGLE, + 'unlimeted' : TR_RATIOLIMIT_UNLIMITED +}) + +# A note on argument maps +# These maps are used to verify *-set methods. The information is structured in +# a tree. +# set +- - [, , , , ] +# | +- - [, , , , ] +# | +# get +- - [, , , , ] +# +- - [, , , , ] + +# Arguments for torrent methods +TORRENT_ARGS = { + 'get' : { + 'activityDate': ('number', 1, None, None, None), + 'addedDate': ('number', 1, None, None, None), + 'announceResponse': ('string', 1, None, None, None), + 'announceURL': ('string', 1, None, None, None), + 'bandwidthPriority': ('number', 5, None, None, None), + 'comment': ('string', 1, None, None, None), + 'corruptEver': ('number', 1, None, None, None), + 'creator': ('string', 1, None, None, None), + 'dateCreated': ('number', 1, None, None, None), + 'desiredAvailable': ('number', 1, None, None, None), + 'doneDate': ('number', 1, None, None, None), + 'downloadDir': ('string', 4, None, None, None), + 'downloadedEver': ('number', 1, None, None, None), + 'downloaders': ('number', 4, None, None, None), + 'downloadLimit': ('number', 1, None, None, None), + 'downloadLimited': ('boolean', 5, None, None, None), + 'downloadLimitMode': ('number', 1, 5, None, None), + 'error': ('number', 1, None, None, None), + 'errorString': ('number', 1, None, None, None), + 'eta': ('number', 1, None, None, None), + 'files': ('array', 1, None, None, None), + 'fileStats': ('array', 5, None, None, None), + 'hashString': ('string', 1, None, None, None), + 'haveUnchecked': ('number', 1, None, None, None), + 'haveValid': ('number', 1, None, None, None), + 'honorsSessionLimits': ('boolean', 5, None, None, None), + 'id': ('number', 1, None, None, None), + 'isPrivate': ('boolean', 1, None, None, None), + 'lastAnnounceTime': ('number', 1, None, None, None), + 'lastScrapeTime': ('number', 1, None, None, None), + 'leechers': ('number', 1, None, None, None), + 'leftUntilDone': ('number', 1, None, None, None), + 'manualAnnounceTime': ('number', 1, None, None, None), + 'maxConnectedPeers': ('number', 1, None, None, None), + 'name': ('string', 1, None, None, None), + 'nextAnnounceTime': ('number', 1, None, None, None), + 'nextScrapeTime': ('number', 1, None, None, None), + 'peer-limit': ('number', 5, None, None, None), + 'peers': ('array', 2, None, None, None), + 'peersConnected': ('number', 1, None, None, None), + 'peersFrom': ('object', 1, None, None, None), + 'peersGettingFromUs': ('number', 1, None, None, None), + 'peersKnown': ('number', 1, None, None, None), + 'peersSendingToUs': ('number', 1, None, None, None), + 'percentDone': ('double', 5, None, None, None), + 'pieces': ('string', 5, None, None, None), + 'pieceCount': ('number', 1, None, None, None), + 'pieceSize': ('number', 1, None, None, None), + 'priorities': ('array', 1, None, None, None), + 'rateDownload': ('number', 1, None, None, None), + 'rateUpload': ('number', 1, None, None, None), + 'recheckProgress': ('double', 1, None, None, None), + 'scrapeResponse': ('string', 1, None, None, None), + 'scrapeURL': ('string', 1, None, None, None), + 'seeders': ('number', 1, None, None, None), + 'seedRatioLimit': ('double', 5, None, None, None), + 'seedRatioMode': ('number', 5, None, None, None), + 'sizeWhenDone': ('number', 1, None, None, None), + 'startDate': ('number', 1, None, None, None), + 'status': ('number', 1, None, None, None), + 'swarmSpeed': ('number', 1, None, None, None), + 'timesCompleted': ('number', 1, None, None, None), + 'trackers': ('array', 1, None, None, None), + 'totalSize': ('number', 1, None, None, None), + 'torrentFile': ('string', 5, None, None, None), + 'uploadedEver': ('number', 1, None, None, None), + 'uploadLimit': ('number', 1, None, None, None), + 'uploadLimitMode': ('number', 1, 5, None, None), + 'uploadLimited': ('boolean', 5, None, None, None), + 'uploadRatio': ('double', 1, None, None, None), + 'wanted': ('array', 1, None, None, None), + 'webseeds': ('array', 1, None, None, None), + 'webseedsSendingToUs': ('number', 1, None, None, None), + }, + 'set': { + 'bandwidthPriority': ('number', 5, None, None, None), + 'downloadLimit': ('number', 5, None, 'speed-limit-down', None), + 'downloadLimited': ('boolean', 5, None, 'speed-limit-down-enabled', None), + 'files-wanted': ('array', 1, None, None, None), + 'files-unwanted': ('array', 1, None, None, None), + 'honorsSessionLimits': ('boolean', 5, None, None, None), + 'ids': ('array', 1, None, None, None), + 'peer-limit': ('number', 1, None, None, None), + 'priority-high': ('array', 1, None, None, None), + 'priority-low': ('array', 1, None, None, None), + 'priority-normal': ('array', 1, None, None, None), + 'seedRatioLimit': ('double', 5, None, None, None), + 'seedRatioMode': ('number', 5, None, None, None), + 'speed-limit-down': ('number', 1, 5, None, 'downloadLimit'), + 'speed-limit-down-enabled': ('boolean', 1, 5, None, 'downloadLimited'), + 'speed-limit-up': ('number', 1, 5, None, 'uploadLimit'), + 'speed-limit-up-enabled': ('boolean', 1, 5, None, 'uploadLimited'), + 'uploadLimit': ('number', 5, None, 'speed-limit-up', None), + 'uploadLimited': ('boolean', 5, None, 'speed-limit-up-enabled', None), + }, + 'add': { + 'download-dir': ('string', 1, None, None, None), + 'filename': ('string', 1, None, None, None), + 'files-wanted': ('array', 1, None, None, None), + 'files-unwanted': ('array', 1, None, None, None), + 'metainfo': ('string', 1, None, None, None), + 'paused': ('boolean', 1, None, None, None), + 'peer-limit': ('number', 1, None, None, None), + 'priority-high': ('array', 1, None, None, None), + 'priority-low': ('array', 1, None, None, None), + 'priority-normal': ('array', 1, None, None, None), + } +} + +# Arguments for session methods +SESSION_ARGS = { + 'get': { + "alt-speed-down": ('number', 5, None, None, None), + "alt-speed-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-begin": ('number', 5, None, None, None), + "alt-speed-time-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-end": ('number', 5, None, None, None), + "alt-speed-time-day": ('number', 5, None, None, None), + "alt-speed-up": ('number', 5, None, None, None), + "blocklist-enabled": ('boolean', 5, None, None, None), + "blocklist-size": ('number', 5, None, None, None), + "encryption": ('string', 1, None, None, None), + "download-dir": ('string', 1, None, None, None), + "peer-limit": ('number', 1, 5, None, None), + "peer-limit-global": ('number', 5, None, None, None), + "peer-limit-per-torrent": ('number', 5, None, None, None), + "pex-allowed": ('boolean', 1, 5, None, None), + "pex-enabled": ('boolean', 5, None, None, None), + "port": ('number', 1, 5, None, None), + "peer-port": ('number', 5, None, None, None), + "peer-port-random-on-start": ('boolean', 5, None, None, None), + "port-forwarding-enabled": ('boolean', 1, None, None, None), + "rpc-version": ('number', 4, None, None, None), + "rpc-version-minimum": ('number', 4, None, None, None), + "seedRatioLimit": ('double', 5, None, None, None), + "seedRatioLimited": ('boolean', 5, None, None, None), + "speed-limit-down": ('number', 1, None, None, None), + "speed-limit-down-enabled": ('boolean', 1, None, None, None), + "speed-limit-up": ('number', 1, None, None, None), + "speed-limit-up-enabled": ('boolean', 1, None, None, None), + "version": ('string', 3, None, None, None), + }, + 'set': { + "alt-speed-down": ('number', 5, None, None, None), + "alt-speed-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-begin": ('number', 5, None, None, None), + "alt-speed-time-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-end": ('number', 5, None, None, None), + "alt-speed-time-day": ('number', 5, None, None, None), + "alt-speed-up": ('number', 5, None, None, None), + "blocklist-enabled": ('boolean', 5, None, None, None), + "encryption": ('string', 1, None, None, None), + "download-dir": ('string', 1, None, None, None), + "peer-limit": ('number', 1, 5, None, 'peer-limit-global'), + "peer-limit-global": ('number', 5, None, 'peer-limit', None), + "peer-limit-per-torrent": ('number', 5, None, None, None), + "pex-allowed": ('boolean', 1, 5, None, 'pex-enabled'), + "pex-enabled": ('boolean', 5, None, 'pex-allowed', None), + "port": ('number', 1, 5, None, 'peer-port'), + "peer-port": ('number', 5, None, 'port', None), + "peer-port-random-on-start": ('boolean', 5, None, None, None), + "port-forwarding-enabled": ('boolean', 1, None, None, None), + "seedRatioLimit": ('double', 5, None, None, None), + "seedRatioLimited": ('boolean', 5, None, None, None), + "speed-limit-down": ('number', 1, None, None, None), + "speed-limit-down-enabled": ('boolean', 1, None, None, None), + "speed-limit-up": ('number', 1, None, None, None), + "speed-limit-up-enabled": ('boolean', 1, None, None, None), + }, +} diff --git a/resources/lib/transmissionrpc-0.3/transmission.py b/resources/lib/transmissionrpc-0.3/transmission.py new file mode 100755 index 0000000..7a62c19 --- /dev/null +++ b/resources/lib/transmissionrpc-0.3/transmission.py @@ -0,0 +1,605 @@ +# -*- coding: utf-8 -*- +# 2008-07, Erik Svensson + +import sys, os, time, datetime +import re +import httplib, urllib2, base64, socket + +try: + import json +except ImportError: + import simplejson as json + +from constants import * +from utils import * + +class TransmissionError(Exception): + def __init__(self, message='', original=None): + Exception.__init__(self, message) + self.message = message + self.original = original + + def __str__(self): + if self.original: + original_name = type(self.original).__name__ + return '%s Original exception: %s, "%s"' % (self.message, original_name, self.original.args) + else: + return self.args + +class Torrent(object): + """ + Torrent is a class holding the data raceived from Transmission regarding a bittorrent transfer. + All fetched torrent fields are accessable through this class using attributes. + This class has a few convenience properties using the torrent data. + """ + + def __init__(self, fields): + if 'id' not in fields: + raise ValueError('Torrent requires an id') + self.fields = {} + self.update(fields) + + def __repr__(self): + return '' % (self.fields['id'], self.fields['name']) + + def __str__(self): + return 'torrent %s' % self.fields['name'] + + def update(self, other): + """Update the torrent data from a Transmission arguments dictinary""" + fields = None + if isinstance(other, dict): + fields = other + elif isinstance(other, Torrent): + fields = other.fields + else: + raise ValueError('Cannot update with supplied data') + for k, v in fields.iteritems(): + self.fields[k.replace('-', '_')] = v + + def files(self): + """ + Get list of files for this torrent. This function returns a dictionary with file information for each file. + """ + result = {} + if 'files' in self.fields: + indicies = xrange(len(self.fields['files'])) + files = self.fields['files'] + priorities = self.fields['priorities'] + wanted = self.fields['wanted'] + index = 1 + for item in zip(indicies, files, priorities, wanted): + selected = True if item[3] else False + priority = PRIORITY[item[2]] + result[item[0]] = { + 'selected': selected, + 'priority': priority, + 'size': item[1]['length'], + 'name': item[1]['name'], + 'completed': item[1]['bytesCompleted']} + return result + + def __getattr__(self, name): + try: + return self.fields[name] + except KeyError, e: + raise AttributeError('No attribute %s' % name) + + @property + def status(self): + """Get the status as string.""" + return STATUS[self.fields['status']] + + @property + def progress(self): + """Get the download progress in percent as float.""" + try: + return 100.0 * (self.fields['sizeWhenDone'] - self.fields['leftUntilDone']) / float(self.fields['sizeWhenDone']) + except ZeroDivisionError: + return 0.0 + + @property + def ratio(self): + """Get the upload/download ratio.""" + try: + return self.fields['uploadedEver'] / float(self.fields['downloadedEver']) + except ZeroDivisionError: + return 0.0 + + @property + def eta(self): + """Get the "eta" as datetime.timedelta.""" + eta = self.fields['eta'] + if eta >= 0: + return datetime.timedelta(seconds=eta) + else: + ValueError('eta not valid') + + @property + def date_active(self): + """Get the attribute "activityDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['activityDate']) + + @property + def date_added(self): + """Get the attribute "addedDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['addedDate']) + + @property + def date_started(self): + """Get the attribute "startDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['startDate']) + + @property + def date_done(self): + """Get the attribute "doneDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['doneDate']) + + def format_eta(self): + """Returns the attribute "eta" formatted as a string.""" + eta = self.fields['eta'] + if eta == -1: + return 'not available' + elif eta == -2: + return 'unknown' + else: + return format_timedelta(self.eta) + +class Session(object): + """ + Session is a class holding the session data for a Transmission daemon. + + Access the session field can be done through attributes. + The attributes available are the same as the session arguments in the + Transmission RPC specification, but with underscore instead of hypen. + ``download-dir`` -> ``download_dir``. + """ + + def __init__(self, fields={}): + self.fields = {} + self.update(fields) + + def update(self, other): + """Update the session data from a session arguments dictinary""" + + fields = None + if isinstance(other, dict): + fields = other + elif isinstance(other, Session): + fields = other.fields + else: + raise ValueError('Cannot update with supplied data') + + for k, v in fields.iteritems(): + self.fields[k.replace('-', '_')] = v + + def __getattr__(self, name): + try: + return self.fields[name] + except KeyError, e: + raise AttributeError('No attribute %s' % name) + + def __str__(self): + text = '' + for k, v in self.fields.iteritems(): + text += "% 32s: %s\n" % (k[-32:], v) + return text + +class Client(object): + """ + This is it. This class implements the json-RPC protocol to communicate with Transmission. + """ + + def __init__(self, address='localhost', port=DEFAULT_PORT, user=None, password=None): + base_url = 'http://' + address + ':' + str(port) + self.url = base_url + '/transmission/rpc' + if user and password: + password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() + password_manager.add_password(realm=None, uri=self.url, user=user, passwd=password) + opener = urllib2.build_opener( + urllib2.HTTPBasicAuthHandler(password_manager) + , urllib2.HTTPDigestAuthHandler(password_manager) + ) + urllib2.install_opener(opener) + elif user or password: + logger.warning('Either user or password missing, not using authentication.') + self._sequence = 0 + self.session = Session() + self.sessionid = 0 + self.protocol_version = None + self.get_session() + self.torrent_get_arguments = get_arguments('torrent-get' + , self.rpc_version) + + def _debug_request(self, request): + logger.debug( + json.dumps( + { + 'request': { + 'url': request.get_full_url(), + 'request-headers': dict(request.header_items()), + 'request-data': json.loads(request.data), + } + }, + indent=2 + ) + ) + + def _debug_response(self, response, response_data): + try: + response_data = json.loads(response_data) + except: + pass + logger.debug( + json.dumps( + { + 'response': { + 'url': response.url, + 'code': response.code, + 'msg': response.msg, + 'headers': dict(response.headers), + 'data': response_data, + } + }, + indent=2 + ) + ) + + def _http_query(self, query): + headers = {'X-Transmission-Session-Id': self.sessionid} + request = urllib2.Request(self.url, query, headers) + request_count = 0 + while True: + error_data = "" + try: + self._debug_request(request) + socket.setdefaulttimeout(10) + if (sys.version_info[0] == 2 and sys.version_info[1] > 5) or sys.version_info[0] > 2: + response = urllib2.urlopen(request, timeout=60) + else: + response = urllib2.urlopen(request) + break + except urllib2.HTTPError, error: + error_data = error.read() + if error.code == 409: + logger.info('Server responded with 409, trying to set session-id.') + if request_count > 1: + raise TransmissionError('Session ID negotiation failed.', error) + if 'X-Transmission-Session-Id' in error.headers: + self.sessionid = error.headers['X-Transmission-Session-Id'] + request.add_header('X-Transmission-Session-Id', self.sessionid) + else: + raise TransmissionError('Unknown conflict.', error) + except urllib2.URLError, error: + raise TransmissionError('Failed to connect to daemon.', error) + except httplib.BadStatusLine, error: + if (request_count > 1): + raise TransmissionError('Failed to request %s "%s".' % (self.url, query), error) + finally: + if error_data: + self._debug_response(error, error_data) + request_count = request_count + 1 + result = response.read() + self._debug_response(response, result) + return result + + def _request(self, method, arguments={}, ids=[], require_ids = False): + """Send json-rpc request to Transmission using http POST""" + + if not isinstance(method, (str, unicode)): + raise ValueError('request takes method as string') + if not isinstance(arguments, dict): + raise ValueError('request takes arguments as dict') + ids = self._format_ids(ids) + if len(ids) > 0: + arguments['ids'] = ids + elif require_ids: + raise ValueError('request require ids') + + query = json.dumps({'tag': self._sequence, 'method': method + , 'arguments': arguments}) + logger.info(query) + self._sequence += 1 + start = time.time() + http_data = self._http_query(query) + elapsed = time.time() - start + logger.info('http request took %.3f s' % (elapsed)) + + try: + data = json.loads(http_data) + except ValueError, e: + logger.error('Error: ' + str(e)) + logger.error('Request: \"%s\"' % (query)) + logger.error('HTTP data: \"%s\"' % (http_data)) + raise + + logger.info(json.dumps(data, indent=2)) + + if data['result'] != 'success': + raise TransmissionError('Query failed with result \"%s\"' + % data['result']) + + results = {} + if method == 'torrent-get': + for item in data['arguments']['torrents']: + results[item['id']] = Torrent(item) + if self.protocol_version == 2 and 'peers' not in item: + self.protocol_version = 1 + elif method == 'torrent-add': + item = data['arguments']['torrent-added'] + results[item['id']] = Torrent(item) + elif method == 'session-get': + self._update_session(data['arguments']) + elif method == 'session-stats': + # older versions of T has the return data in "session-stats" + if 'session-stats' in data['arguments']: + self._update_session(data['arguments']['session-stats']) + else: + self._update_session(data['arguments']) + elif method in ('port-test', 'blocklist-update'): + results = data['arguments'] + else: + return None + + return results + + def _format_ids(self, args): + """Take things and make them valid torrent identifiers""" + ids = [] + + if isinstance(args, (int, long)): + ids.append(args) + elif isinstance(args, (str, unicode)): + for item in re.split(u'[ ,]+', args): + if len(item) == 0: + continue + addition = None + try: + # handle index + addition = [int(item)] + except ValueError: + pass + if not addition: + # handle hashes + try: + int(item, 16) + addition = [item] + except: + pass + if not addition: + # handle index ranges i.e. 5:10 + match = re.match(u'^(\d+):(\d+)$', item) + if match: + try: + idx_from = int(match.group(1)) + idx_to = int(match.group(2)) + addition = range(idx_from, idx_to + 1) + except: + pass + if not addition: + raise ValueError(u'Invalid torrent id, \"%s\"' % item) + ids.extend(addition) + elif isinstance(args, (list)): + for item in args: + ids.extend(self._format_ids(item)) + else: + raise ValueError(u'Invalid torrent id') + return ids + + def _update_session(self, data): + self.session.update(data) + + @property + def rpc_version(self): + if self.protocol_version == None: + if hasattr(self.session, 'rpc_version'): + self.protocol_version = self.session.rpc_version + elif hasattr(self.session, 'version'): + self.protocol_version = 3 + else: + self.protocol_version = 2 + return self.protocol_version + + def _rpc_version_warning(self, version): + if self.rpc_version < version: + logger.warning('Using feature not supported by server. RPC version for server %d, feature introduced in %d.' % (self.rpc_version, version)) + + def add(self, data, **kwargs): + """ + Add torrent to transfers list. Takes a base64 encoded .torrent file in data. + Additional arguments are: + + * `paused`, boolean, Whether to pause the transfer on add. + * `download_dir`, path, The directory where the downloaded + contents will be saved in. + * `peer_limit`, number, Limits the number of peers for this + transfer. + * `files_unwanted`, + * `files_wanted`, + * `priority_high`, + * `priority_low`, + * `priority_normal`, + """ + args = {'metainfo': data} + for key, value in kwargs.iteritems(): + argument = make_rpc_name(key) + (arg, val) = argument_value_convert('torrent-add', + argument, value, self.rpc_version) + args[arg] = val + return self._request('torrent-add', args) + + def add_url(self, torrent_url, **kwargs): + """ + Add torrent to transfers list. Takes a url to a .torrent file. + Additional arguments are: + + * `paused`, boolean, Whether to pause the transfer on add. + * `download_dir`, path, The directory where the downloaded + contents will be saved in. + * `peer_limit`, number, Limits the number of peers for this + transfer. + * `files_unwanted`, + * `files_wanted`, + * `priority_high`, + * `priority_low`, + * `priority_normal`, + """ + torrent_file = None + if os.path.exists(torrent_url): + torrent_file = open(torrent_url, 'r') + else: + try: + torrent_file = urllib2.urlopen(torrent_url) + except: + torrent_file = None + + if not torrent_file: + raise TransmissionError('File does not exist.') + + torrent_data = base64.b64encode(torrent_file.read()) + return self.add(torrent_data, **kwargs) + + def remove(self, ids, delete_data=False): + """ + remove torrent(s) with provided id(s). Local data is removed if + delete_data is True, otherwise not. + """ + self._rpc_version_warning(3) + self._request('torrent-remove', + {'delete-local-data':rpc_bool(delete_data)}, ids, True) + + def start(self, ids): + """start torrent(s) with provided id(s)""" + self._request('torrent-start', {}, ids, True) + + def stop(self, ids): + """stop torrent(s) with provided id(s)""" + self._request('torrent-stop', {}, ids, True) + + def verify(self, ids): + """verify torrent(s) with provided id(s)""" + self._request('torrent-verify', {}, ids, True) + + def reannounce(self, ids): + """reannounce torrent(s) with provided id(s)""" + self._rpc_version_warning(5) + self._request('torrent-reannounce', {}, ids, True) + + def info(self, ids=[], arguments={}): + """Get detailed information for torrent(s) with provided id(s).""" + if not arguments: + arguments = self.torrent_get_arguments + return self._request('torrent-get', {'fields': arguments}, ids) + + def get_files(self, ids=[]): + """ + Get list of files for provided torrent id(s). + This function returns a dictonary for each requested torrent id holding + the information about the files. + """ + fields = ['id', 'name', 'hashString', 'files', 'priorities', 'wanted'] + request_result = self._request('torrent-get', {'fields': fields}, ids) + result = {} + for id, torrent in request_result.iteritems(): + result[id] = torrent.files() + return result + + def set_files(self, items): + """ + Set file properties. Takes a dictonary with similar contents as the + result of get_files. + """ + if not isinstance(items, dict): + raise ValueError('Invalid file description') + for tid, files in items.iteritems(): + if not isinstance(files, dict): + continue + wanted = [] + unwanted = [] + priority_high = [] + priority_normal = [] + priority_low = [] + for fid, file in files.iteritems(): + if not isinstance(file, dict): + continue + if 'selected' in file and file['selected']: + wanted.append(fid) + else: + unwanted.append(fid) + if 'priority' in file: + if file['priority'] == 'high': + priority_high.append(fid) + elif file['priority'] == 'normal': + priority_normal.append(fid) + elif file['priority'] == 'low': + priority_low.append(fid) + self.change([tid], files_wanted = wanted + , files_unwanted = unwanted + , priority_high = priority_high + , priority_normal = priority_normal + , priority_low = priority_low) + + def list(self): + """list all torrents""" + fields = ['id', 'hashString', 'name', 'sizeWhenDone', 'leftUntilDone' + , 'eta', 'status', 'rateUpload', 'rateDownload', 'uploadedEver' + , 'downloadedEver'] + return self._request('torrent-get', {'fields': fields}) + + def change(self, ids, **kwargs): + """ + Change torrent parameters. This is the list of parameters that. + """ + args = {} + for key, value in kwargs.iteritems(): + argument = make_rpc_name(key) + (arg, val) = argument_value_convert('torrent-set' + , argument, value, self.rpc_version) + args[arg] = val + + if len(args) > 0: + self._request('torrent-set', args, ids, True) + else: + ValueError("No arguments to set") + + def get_session(self): + """Get session parameters""" + self._request('session-get') + return self.session + + def set_session(self, **kwargs): + """Set session parameters""" + args = {} + for key, value in kwargs.iteritems(): + if key == 'encryption' and value not in ['required', 'preferred', 'tolerated']: + raise ValueError('Invalid encryption value') + argument = make_rpc_name(key) + (arg, val) = argument_value_convert('session-set' + , argument, value, self.rpc_version) + args[arg] = val + if len(args) > 0: + self._request('session-set', args) + + def blocklist_update(self): + """Update block list. Returns the size of the block list.""" + self._rpc_version_warning(5) + result = self._request('blocklist-update') + if 'blocklist-size' in result: + return result['blocklist-size'] + return None + + def port_test(self): + """ + Tests to see if your incoming peer port is accessible from the + outside world. + """ + self._rpc_version_warning(5) + result = self._request('port-test') + if 'port-is-open' in result: + return result['port-is-open'] + return None + + def session_stats(self): + """Get session statistics""" + self._request('session-stats') + return self.session diff --git a/resources/lib/transmissionrpc-0.3/utils.py b/resources/lib/transmissionrpc-0.3/utils.py new file mode 100644 index 0000000..5b2b2a0 --- /dev/null +++ b/resources/lib/transmissionrpc-0.3/utils.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- +# 2008-07, Erik Svensson + +import socket, datetime +import constants +from constants import logger + +UNITS = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB'] + +def format_size(size): + s = float(size) + i = 0 + while size >= 1024.0 and i < len(UNITS): + i += 1 + size /= 1024.0 + return (size, UNITS[i]) + +def format_speed(size): + (size, unit) = format_size(size) + return (size, unit + '/s') + +def format_timedelta(delta): + minutes, seconds = divmod(delta.seconds, 60) + hours, minutes = divmod(minutes, 60) + return '%d %02d:%02d:%02d' % (delta.days, hours, minutes, seconds) + +def format_timestamp(timestamp): + if timestamp > 0: + dt = datetime.datetime.fromtimestamp(timestamp) + return dt.isoformat(' ') + else: + return '-' + +class INetAddressError(Exception): + pass + +def inet_address(address, default_port, default_address='localhost'): + addr = address.split(':') + if len(addr) == 1: + try: + port = int(addr[0]) + addr = default_address + except: + addr = addr[0] + port = default_port + elif len(addr) == 2: + port = int(addr[1]) + if len(addr[0]) == 0: + addr = default_address + else: + addr = addr[0] + else: + addr = default_address + port = default_port + try: + socket.getaddrinfo(addr, port, socket.AF_INET, socket.SOCK_STREAM) + except socket.gaierror, e: + raise INetAddressError('Cannot look up address "%s".' % address) + return (addr, port) + +def rpc_bool(arg): + if isinstance(arg, (str, unicode)): + try: + arg = bool(int(arg)) + except: + arg = arg.lower() in [u'true', u'yes'] + return 1 if bool(arg) else 0 + +TR_TYPE_MAP = { + 'number' : int, + 'string' : str, + 'double': float, + 'boolean' : rpc_bool, + 'array': list, + 'object': dict +} + +def make_python_name(name): + return name.replace('-', '_') + +def make_rpc_name(name): + return name.replace('_', '-') + +def argument_value_convert(method, argument, value, rpc_version): + if method in ('torrent-add', 'torrent-get', 'torrent-set'): + args = constants.TORRENT_ARGS[method[-3:]] + elif method in ('session-get', 'session-set'): + args = constants.SESSION_ARGS[method[-3:]] + else: + return ValueError('Method "%s" not supported' % (method)) + if argument in args: + info = args[argument] + invalid_version = True + while invalid_version: + invalid_version = False + replacement = None + if rpc_version < info[1]: + invalid_version = True + replacement = info[3] + if info[2] and info[2] <= rpc_version: + invalid_version = True + replacement = info[4] + if invalid_version: + if replacement: + logger.warning( + 'Replacing requested argument "%s" with "%s".' + % (argument, replacement)) + argument = replacement + info = args[argument] + else: + raise ValueError( + 'Method "%s" Argument "%s" does not exist in version %d.' + % (method, argument, rpc_version)) + return (argument, TR_TYPE_MAP[info[0]](value)) + else: + raise ValueError('Argument "%s" does not exists for method "%s".', + (argument, method)) + +def get_arguments(method, rpc_version): + if method in ('torrent-add', 'torrent-get', 'torrent-set'): + args = constants.TORRENT_ARGS[method[-3:]] + elif method in ('session-get', 'session-set'): + args = constants.SESSION_ARGS[method[-3:]] + else: + return ValueError('Method "%s" not supported' % (method)) + accessible = [] + for argument, info in args.iteritems(): + valid_version = True + if rpc_version < info[1]: + valid_version = False + if info[2] and info[2] <= rpc_version: + valid_version = False + if valid_version: + accessible.append(argument) + return accessible diff --git a/resources/lib/transmissionrpc-0.4/__init__.py b/resources/lib/transmissionrpc-0.4/__init__.py new file mode 100755 index 0000000..5e09d46 --- /dev/null +++ b/resources/lib/transmissionrpc-0.4/__init__.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# 2008-08, Erik Svensson + +from constants import * +from transmission import TransmissionError, Torrent, Session, Client + +__author__ = u'Erik Svensson ' +__version__ = u'0.4' +__copyright__ = u'Copyright (c) 2009 Erik Svensson' +__license__ = u'MIT' diff --git a/resources/lib/transmissionrpc-0.4/constants.py b/resources/lib/transmissionrpc-0.4/constants.py new file mode 100755 index 0000000..f40cdc6 --- /dev/null +++ b/resources/lib/transmissionrpc-0.4/constants.py @@ -0,0 +1,234 @@ +# -*- coding: utf-8 -*- +# 2008-07, Erik Svensson + +import logging + +logger = logging.getLogger('transmissionrpc') +logger.setLevel(logging.ERROR) + +def mirror_dict(d): + d.update(dict((v, k) for k, v in d.iteritems())) + return d + +DEFAULT_PORT = 9091 + +DEFAULT_TIMEOUT = 30 + +TR_STATUS_CHECK_WAIT = (1<<0) +TR_STATUS_CHECK = (1<<1) +TR_STATUS_DOWNLOAD = (1<<2) +TR_STATUS_SEED = (1<<3) +TR_STATUS_STOPPED = (1<<4) + +STATUS = mirror_dict({ + 'check pending' : TR_STATUS_CHECK_WAIT, + 'checking' : TR_STATUS_CHECK, + 'downloading' : TR_STATUS_DOWNLOAD, + 'seeding' : TR_STATUS_SEED, + 'stopped' : TR_STATUS_STOPPED, +}) + +TR_PRI_LOW = -1 +TR_PRI_NORMAL = 0 +TR_PRI_HIGH = 1 + +PRIORITY = mirror_dict({ + 'low' : TR_PRI_LOW, + 'normal' : TR_PRI_NORMAL, + 'high' : TR_PRI_HIGH +}) + +TR_RATIOLIMIT_GLOBAL = 0 # follow the global settings +TR_RATIOLIMIT_SINGLE = 1 # override the global settings, seeding until a certain ratio +TR_RATIOLIMIT_UNLIMITED = 2 # override the global settings, seeding regardless of ratio + +RATIO_LIMIT = mirror_dict({ + 'global' : TR_RATIOLIMIT_GLOBAL, + 'single' : TR_RATIOLIMIT_SINGLE, + 'unlimeted' : TR_RATIOLIMIT_UNLIMITED +}) + +# A note on argument maps +# These maps are used to verify *-set methods. The information is structured in +# a tree. +# set +- - [, , , , ] +# | +- - [, , , , ] +# | +# get +- - [, , , , ] +# +- - [, , , , ] + +# Arguments for torrent methods +TORRENT_ARGS = { + 'get' : { + 'activityDate': ('number', 1, None, None, None), + 'addedDate': ('number', 1, None, None, None), + 'announceResponse': ('string', 1, None, None, None), + 'announceURL': ('string', 1, None, None, None), + 'bandwidthPriority': ('number', 5, None, None, None), + 'comment': ('string', 1, None, None, None), + 'corruptEver': ('number', 1, None, None, None), + 'creator': ('string', 1, None, None, None), + 'dateCreated': ('number', 1, None, None, None), + 'desiredAvailable': ('number', 1, None, None, None), + 'doneDate': ('number', 1, None, None, None), + 'downloadDir': ('string', 4, None, None, None), + 'downloadedEver': ('number', 1, None, None, None), + 'downloaders': ('number', 4, None, None, None), + 'downloadLimit': ('number', 1, None, None, None), + 'downloadLimited': ('boolean', 5, None, None, None), + 'downloadLimitMode': ('number', 1, 5, None, None), + 'error': ('number', 1, None, None, None), + 'errorString': ('number', 1, None, None, None), + 'eta': ('number', 1, None, None, None), + 'files': ('array', 1, None, None, None), + 'fileStats': ('array', 5, None, None, None), + 'hashString': ('string', 1, None, None, None), + 'haveUnchecked': ('number', 1, None, None, None), + 'haveValid': ('number', 1, None, None, None), + 'honorsSessionLimits': ('boolean', 5, None, None, None), + 'id': ('number', 1, None, None, None), + 'isPrivate': ('boolean', 1, None, None, None), + 'lastAnnounceTime': ('number', 1, None, None, None), + 'lastScrapeTime': ('number', 1, None, None, None), + 'leechers': ('number', 1, None, None, None), + 'leftUntilDone': ('number', 1, None, None, None), + 'manualAnnounceTime': ('number', 1, None, None, None), + 'maxConnectedPeers': ('number', 1, None, None, None), + 'name': ('string', 1, None, None, None), + 'nextAnnounceTime': ('number', 1, None, None, None), + 'nextScrapeTime': ('number', 1, None, None, None), + 'peer-limit': ('number', 5, None, None, None), + 'peers': ('array', 2, None, None, None), + 'peersConnected': ('number', 1, None, None, None), + 'peersFrom': ('object', 1, None, None, None), + 'peersGettingFromUs': ('number', 1, None, None, None), + 'peersKnown': ('number', 1, None, None, None), + 'peersSendingToUs': ('number', 1, None, None, None), + 'percentDone': ('double', 5, None, None, None), + 'pieces': ('string', 5, None, None, None), + 'pieceCount': ('number', 1, None, None, None), + 'pieceSize': ('number', 1, None, None, None), + 'priorities': ('array', 1, None, None, None), + 'rateDownload': ('number', 1, None, None, None), + 'rateUpload': ('number', 1, None, None, None), + 'recheckProgress': ('double', 1, None, None, None), + 'scrapeResponse': ('string', 1, None, None, None), + 'scrapeURL': ('string', 1, None, None, None), + 'seeders': ('number', 1, None, None, None), + 'seedRatioLimit': ('double', 5, None, None, None), + 'seedRatioMode': ('number', 5, None, None, None), + 'sizeWhenDone': ('number', 1, None, None, None), + 'startDate': ('number', 1, None, None, None), + 'status': ('number', 1, None, None, None), + 'swarmSpeed': ('number', 1, None, None, None), + 'timesCompleted': ('number', 1, None, None, None), + 'trackers': ('array', 1, None, None, None), + 'totalSize': ('number', 1, None, None, None), + 'torrentFile': ('string', 5, None, None, None), + 'uploadedEver': ('number', 1, None, None, None), + 'uploadLimit': ('number', 1, None, None, None), + 'uploadLimitMode': ('number', 1, 5, None, None), + 'uploadLimited': ('boolean', 5, None, None, None), + 'uploadRatio': ('double', 1, None, None, None), + 'wanted': ('array', 1, None, None, None), + 'webseeds': ('array', 1, None, None, None), + 'webseedsSendingToUs': ('number', 1, None, None, None), + }, + 'set': { + 'bandwidthPriority': ('number', 5, None, None, None), + 'downloadLimit': ('number', 5, None, 'speed-limit-down', None), + 'downloadLimited': ('boolean', 5, None, 'speed-limit-down-enabled', None), + 'files-wanted': ('array', 1, None, None, None), + 'files-unwanted': ('array', 1, None, None, None), + 'honorsSessionLimits': ('boolean', 5, None, None, None), + 'ids': ('array', 1, None, None, None), + 'peer-limit': ('number', 1, None, None, None), + 'priority-high': ('array', 1, None, None, None), + 'priority-low': ('array', 1, None, None, None), + 'priority-normal': ('array', 1, None, None, None), + 'seedRatioLimit': ('double', 5, None, None, None), + 'seedRatioMode': ('number', 5, None, None, None), + 'speed-limit-down': ('number', 1, 5, None, 'downloadLimit'), + 'speed-limit-down-enabled': ('boolean', 1, 5, None, 'downloadLimited'), + 'speed-limit-up': ('number', 1, 5, None, 'uploadLimit'), + 'speed-limit-up-enabled': ('boolean', 1, 5, None, 'uploadLimited'), + 'uploadLimit': ('number', 5, None, 'speed-limit-up', None), + 'uploadLimited': ('boolean', 5, None, 'speed-limit-up-enabled', None), + }, + 'add': { + 'download-dir': ('string', 1, None, None, None), + 'filename': ('string', 1, None, None, None), + 'files-wanted': ('array', 1, None, None, None), + 'files-unwanted': ('array', 1, None, None, None), + 'metainfo': ('string', 1, None, None, None), + 'paused': ('boolean', 1, None, None, None), + 'peer-limit': ('number', 1, None, None, None), + 'priority-high': ('array', 1, None, None, None), + 'priority-low': ('array', 1, None, None, None), + 'priority-normal': ('array', 1, None, None, None), + } +} + +# Arguments for session methods +SESSION_ARGS = { + 'get': { + "alt-speed-down": ('number', 5, None, None, None), + "alt-speed-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-begin": ('number', 5, None, None, None), + "alt-speed-time-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-end": ('number', 5, None, None, None), + "alt-speed-time-day": ('number', 5, None, None, None), + "alt-speed-up": ('number', 5, None, None, None), + "blocklist-enabled": ('boolean', 5, None, None, None), + "blocklist-size": ('number', 5, None, None, None), + "dht-enabled": ('boolean', 6, None, None, None), + "download-dir": ('string', 1, None, None, None), + "encryption": ('string', 1, None, None, None), + "peer-limit": ('number', 1, 5, None, None), + "peer-limit-global": ('number', 5, None, None, None), + "peer-limit-per-torrent": ('number', 5, None, None, None), + "pex-allowed": ('boolean', 1, 5, None, None), + "pex-enabled": ('boolean', 5, None, None, None), + "port": ('number', 1, 5, None, None), + "peer-port": ('number', 5, None, None, None), + "peer-port-random-on-start": ('boolean', 5, None, None, None), + "port-forwarding-enabled": ('boolean', 1, None, None, None), + "rpc-version": ('number', 4, None, None, None), + "rpc-version-minimum": ('number', 4, None, None, None), + "seedRatioLimit": ('double', 5, None, None, None), + "seedRatioLimited": ('boolean', 5, None, None, None), + "speed-limit-down": ('number', 1, None, None, None), + "speed-limit-down-enabled": ('boolean', 1, None, None, None), + "speed-limit-up": ('number', 1, None, None, None), + "speed-limit-up-enabled": ('boolean', 1, None, None, None), + "version": ('string', 3, None, None, None), + }, + 'set': { + "alt-speed-down": ('number', 5, None, None, None), + "alt-speed-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-begin": ('number', 5, None, None, None), + "alt-speed-time-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-end": ('number', 5, None, None, None), + "alt-speed-time-day": ('number', 5, None, None, None), + "alt-speed-up": ('number', 5, None, None, None), + "blocklist-enabled": ('boolean', 5, None, None, None), + "dht-enabled": ('boolean', 6, None, None, None), + "download-dir": ('string', 1, None, None, None), + "encryption": ('string', 1, None, None, None), + "peer-limit": ('number', 1, 5, None, 'peer-limit-global'), + "peer-limit-global": ('number', 5, None, 'peer-limit', None), + "peer-limit-per-torrent": ('number', 5, None, None, None), + "pex-allowed": ('boolean', 1, 5, None, 'pex-enabled'), + "pex-enabled": ('boolean', 5, None, 'pex-allowed', None), + "port": ('number', 1, 5, None, 'peer-port'), + "peer-port": ('number', 5, None, 'port', None), + "peer-port-random-on-start": ('boolean', 5, None, None, None), + "port-forwarding-enabled": ('boolean', 1, None, None, None), + "seedRatioLimit": ('double', 5, None, None, None), + "seedRatioLimited": ('boolean', 5, None, None, None), + "speed-limit-down": ('number', 1, None, None, None), + "speed-limit-down-enabled": ('boolean', 1, None, None, None), + "speed-limit-up": ('number', 1, None, None, None), + "speed-limit-up-enabled": ('boolean', 1, None, None, None), + }, +} diff --git a/resources/lib/transmissionrpc-0.4/transmission.py b/resources/lib/transmissionrpc-0.4/transmission.py new file mode 100755 index 0000000..8723385 --- /dev/null +++ b/resources/lib/transmissionrpc-0.4/transmission.py @@ -0,0 +1,628 @@ +# -*- coding: utf-8 -*- +# 2008-07, Erik Svensson + +import sys, os, time, datetime +import re +import httplib, urllib2, base64, socket + +try: + import json +except ImportError: + import simplejson as json + +from constants import * +from utils import * + +class TransmissionError(Exception): + def __init__(self, message='', original=None): + Exception.__init__(self, message) + self.message = message + self.original = original + + def __str__(self): + if self.original: + original_name = type(self.original).__name__ + return '%s Original exception: %s, "%s"' % (self.message, original_name, self.original.args) + else: + return self.args + +class Torrent(object): + """ + Torrent is a class holding the data raceived from Transmission regarding a bittorrent transfer. + All fetched torrent fields are accessable through this class using attributes. + This class has a few convenience properties using the torrent data. + """ + + def __init__(self, fields): + if 'id' not in fields: + raise ValueError('Torrent requires an id') + self.fields = {} + self.update(fields) + + def __repr__(self): + return '' % (self.fields['id'], self.fields['name']) + + def __str__(self): + return 'torrent %s' % self.fields['name'] + + def update(self, other): + """Update the torrent data from a Transmission arguments dictinary""" + fields = None + if isinstance(other, dict): + fields = other + elif isinstance(other, Torrent): + fields = other.fields + else: + raise ValueError('Cannot update with supplied data') + for k, v in fields.iteritems(): + self.fields[k.replace('-', '_')] = v + + def files(self): + """ + Get list of files for this torrent. This function returns a dictionary with file information for each file. + """ + result = {} + if 'files' in self.fields: + indicies = xrange(len(self.fields['files'])) + files = self.fields['files'] + priorities = self.fields['priorities'] + wanted = self.fields['wanted'] + index = 1 + for item in zip(indicies, files, priorities, wanted): + selected = bool(item[3]) + priority = PRIORITY[item[2]] + result[item[0]] = { + 'selected': selected, + 'priority': priority, + 'size': item[1]['length'], + 'name': item[1]['name'], + 'completed': item[1]['bytesCompleted']} + return result + + def __getattr__(self, name): + try: + return self.fields[name] + except KeyError, e: + raise AttributeError('No attribute %s' % name) + + @property + def status(self): + """Get the status as string.""" + return STATUS[self.fields['status']] + + @property + def progress(self): + """Get the download progress in percent as float.""" + try: + return 100.0 * (self.fields['sizeWhenDone'] - self.fields['leftUntilDone']) / float(self.fields['sizeWhenDone']) + except ZeroDivisionError: + return 0.0 + + @property + def ratio(self): + """Get the upload/download ratio.""" + try: + return self.fields['uploadedEver'] / float(self.fields['downloadedEver']) + except ZeroDivisionError: + return 0.0 + + @property + def eta(self): + """Get the "eta" as datetime.timedelta.""" + eta = self.fields['eta'] + if eta >= 0: + return datetime.timedelta(seconds=eta) + else: + ValueError('eta not valid') + + @property + def date_active(self): + """Get the attribute "activityDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['activityDate']) + + @property + def date_added(self): + """Get the attribute "addedDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['addedDate']) + + @property + def date_started(self): + """Get the attribute "startDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['startDate']) + + @property + def date_done(self): + """Get the attribute "doneDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['doneDate']) + + def format_eta(self): + """Returns the attribute "eta" formatted as a string.""" + eta = self.fields['eta'] + if eta == -1: + return 'not available' + elif eta == -2: + return 'unknown' + else: + return format_timedelta(self.eta) + +class Session(object): + """ + Session is a class holding the session data for a Transmission daemon. + + Access the session field can be done through attributes. + The attributes available are the same as the session arguments in the + Transmission RPC specification, but with underscore instead of hypen. + ``download-dir`` -> ``download_dir``. + """ + + def __init__(self, fields={}): + self.fields = {} + self.update(fields) + + def update(self, other): + """Update the session data from a session arguments dictinary""" + + fields = None + if isinstance(other, dict): + fields = other + elif isinstance(other, Session): + fields = other.fields + else: + raise ValueError('Cannot update with supplied data') + + for k, v in fields.iteritems(): + self.fields[k.replace('-', '_')] = v + + def __getattr__(self, name): + try: + return self.fields[name] + except KeyError, e: + raise AttributeError('No attribute %s' % name) + + def __str__(self): + text = '' + for k, v in self.fields.iteritems(): + text += "% 32s: %s\n" % (k[-32:], v) + return text + +class Client(object): + """ + This is it. This class implements the json-RPC protocol to communicate with Transmission. + """ + + def __init__(self, address='localhost', port=DEFAULT_PORT, user=None, password=None): + base_url = 'http://' + address + ':' + str(port) + self.url = base_url + '/transmission/rpc' + if user and password: + password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() + password_manager.add_password(realm=None, uri=self.url, user=user, passwd=password) + opener = urllib2.build_opener( + urllib2.HTTPBasicAuthHandler(password_manager) + , urllib2.HTTPDigestAuthHandler(password_manager) + ) + urllib2.install_opener(opener) + elif user or password: + logger.warning('Either user or password missing, not using authentication.') + self._sequence = 0 + self.session = Session() + self.sessionid = 0 + self.protocol_version = None + self.get_session() + self.torrent_get_arguments = get_arguments('torrent-get' + , self.rpc_version) + + def _debug_request(self, request): + logger.debug( + json.dumps( + { + 'request': { + 'url': request.get_full_url(), + 'request-headers': dict(request.header_items()), + 'request-data': json.loads(request.data), + } + }, + indent=2 + ) + ) + + def _debug_response(self, response, response_data): + try: + response_data = json.loads(response_data) + except: + pass + logger.debug( + json.dumps( + { + 'response': { + 'url': response.url, + 'code': response.code, + 'msg': response.msg, + 'headers': dict(response.headers), + 'data': response_data, + } + }, + indent=2 + ) + ) + + def _http_query(self, query, timeout=DEFAULT_TIMEOUT): + headers = {'X-Transmission-Session-Id': self.sessionid} + request = urllib2.Request(self.url, query, headers) + request_count = 0 + while True: + error_data = "" + try: + try: + self._debug_request(request) + socket.setdefaulttimeout(timeout) # 30 seconds + if (sys.version_info[0] == 2 and sys.version_info[1] > 5) or sys.version_info[0] > 2: + response = urllib2.urlopen(request, timeout=timeout) + else: + response = urllib2.urlopen(request) + break + except urllib2.HTTPError, error: + error_data = error.read() + if error.code == 409: + logger.info('Server responded with 409, trying to set session-id.') + if request_count > 1: + raise TransmissionError('Session ID negotiation failed.', error) + if 'X-Transmission-Session-Id' in error.headers: + self.sessionid = error.headers['X-Transmission-Session-Id'] + request.add_header('X-Transmission-Session-Id', self.sessionid) + else: + raise TransmissionError('Unknown conflict.', error) + except urllib2.URLError, error: + raise TransmissionError('Failed to connect to daemon.', error) + except httplib.BadStatusLine, error: + if (request_count > 1): + raise TransmissionError('Failed to request %s "%s".' % (self.url, query), error) + finally: + if error_data: + self._debug_response(error, error_data) + request_count = request_count + 1 + result = response.read() + self._debug_response(response, result) + return result + + def _request(self, method, arguments={}, ids=[], require_ids=False, timeout=DEFAULT_TIMEOUT): + """Send json-rpc request to Transmission using http POST""" + + if not isinstance(method, (str, unicode)): + raise ValueError('request takes method as string') + if not isinstance(arguments, dict): + raise ValueError('request takes arguments as dict') + ids = self._format_ids(ids) + if len(ids) > 0: + arguments['ids'] = ids + elif require_ids: + raise ValueError('request require ids') + + query = json.dumps({'tag': self._sequence, 'method': method + , 'arguments': arguments}) + logger.info(query) + self._sequence += 1 + start = time.time() + http_data = self._http_query(query, timeout) + elapsed = time.time() - start + logger.info('http request took %.3f s' % (elapsed)) + + try: + data = json.loads(http_data) + except ValueError, e: + logger.error('Error: ' + str(e)) + logger.error('Request: \"%s\"' % (query)) + logger.error('HTTP data: \"%s\"' % (http_data)) + raise + + logger.info(json.dumps(data, indent=2)) + + if data['result'] != 'success': + raise TransmissionError('Query failed with result \"%s\"' + % data['result']) + + results = {} + if method == 'torrent-get': + for item in data['arguments']['torrents']: + results[item['id']] = Torrent(item) + if self.protocol_version == 2 and 'peers' not in item: + self.protocol_version = 1 + elif method == 'torrent-add': + item = data['arguments']['torrent-added'] + results[item['id']] = Torrent(item) + elif method == 'session-get': + self._update_session(data['arguments']) + elif method == 'session-stats': + # older versions of T has the return data in "session-stats" + if 'session-stats' in data['arguments']: + self._update_session(data['arguments']['session-stats']) + else: + self._update_session(data['arguments']) + elif method in ('port-test', 'blocklist-update'): + results = data['arguments'] + else: + return None + + return results + + def _format_ids(self, args): + """Take things and make them valid torrent identifiers""" + ids = [] + + if isinstance(args, (int, long)): + ids.append(args) + elif isinstance(args, (str, unicode)): + for item in re.split(u'[ ,]+', args): + if len(item) == 0: + continue + addition = None + try: + # handle index + addition = [int(item)] + except ValueError: + pass + if not addition: + # handle hashes + try: + int(item, 16) + addition = [item] + except: + pass + if not addition: + # handle index ranges i.e. 5:10 + match = re.match(u'^(\d+):(\d+)$', item) + if match: + try: + idx_from = int(match.group(1)) + idx_to = int(match.group(2)) + addition = range(idx_from, idx_to + 1) + except: + pass + if not addition: + raise ValueError(u'Invalid torrent id, \"%s\"' % item) + ids.extend(addition) + elif isinstance(args, (list)): + for item in args: + ids.extend(self._format_ids(item)) + else: + raise ValueError(u'Invalid torrent id') + return ids + + def _update_session(self, data): + self.session.update(data) + + @property + def rpc_version(self): + if self.protocol_version == None: + if hasattr(self.session, 'rpc_version'): + self.protocol_version = self.session.rpc_version + elif hasattr(self.session, 'version'): + self.protocol_version = 3 + else: + self.protocol_version = 2 + return self.protocol_version + + def _rpc_version_warning(self, version): + if self.rpc_version < version: + logger.warning('Using feature not supported by server. RPC version for server %d, feature introduced in %d.' % (self.rpc_version, version)) + + def add(self, data, timeout=DEFAULT_TIMEOUT, **kwargs): + """ + Add torrent to transfers list. Takes a base64 encoded .torrent file in data. + Additional arguments are: + + * `metainfo`, string, alternate way to pass base64 encoded torrent data + * `filename`, path or url, provide torrent data as a file path or URL. + * `paused`, boolean, Whether to pause the transfer on add. + * `download_dir`, path, The directory where the downloaded + contents will be saved in. + * `peer_limit`, number, Limits the number of peers for this + transfer. + * `files_unwanted`, + * `files_wanted`, + * `priority_high`, + * `priority_low`, + * `priority_normal`, + """ + args = {} + if data: + args = {'metainfo': data} + if 'metainfo' in kwargs: + pass + if 'filename' in kwargs: + pass + else: + raise ValueError('No torrent data or torrent url.') + for key, value in kwargs.iteritems(): + argument = make_rpc_name(key) + (arg, val) = argument_value_convert('torrent-add', + argument, value, self.rpc_version) + args[arg] = val + return self._request('torrent-add', args, timeout=timeout) + + def add_url(self, torrent_url, **kwargs): + """ + Add torrent to transfers list. Takes a url to a .torrent file. + Additional arguments are: + + * `paused`, boolean, Whether to pause the transfer on add. + * `download_dir`, path, The directory where the downloaded + contents will be saved in. + * `peer_limit`, number, Limits the number of peers for this + transfer. + * `files_unwanted`, + * `files_wanted`, + * `priority_high`, + * `priority_low`, + * `priority_normal`, + """ + torrent_file = None + if os.path.exists(torrent_url): + torrent_file = open(torrent_url, 'r') + else: + try: + torrent_file = urllib2.urlopen(torrent_url) + except: + torrent_file = None + + if not torrent_file: + raise TransmissionError('File does not exist.') + + torrent_data = base64.b64encode(torrent_file.read()) + return self.add(torrent_data, **kwargs) + + def remove(self, ids, delete_data=False, timeout=DEFAULT_TIMEOUT): + """ + remove torrent(s) with provided id(s). Local data is removed if + delete_data is True, otherwise not. + """ + self._rpc_version_warning(3) + self._request('torrent-remove', + {'delete-local-data':rpc_bool(delete_data)}, ids, True, timeout=timeout) + + def start(self, ids, timeout=DEFAULT_TIMEOUT): + """start torrent(s) with provided id(s)""" + self._request('torrent-start', {}, ids, True, timeout=timeout) + + def stop(self, ids, timeout=DEFAULT_TIMEOUT): + """stop torrent(s) with provided id(s)""" + self._request('torrent-stop', {}, ids, True, timeout=timeout) + + def verify(self, ids, timeout=DEFAULT_TIMEOUT): + """verify torrent(s) with provided id(s)""" + self._request('torrent-verify', {}, ids, True, timeout=timeout) + + def reannounce(self, ids, timeout=DEFAULT_TIMEOUT): + """reannounce torrent(s) with provided id(s)""" + self._rpc_version_warning(5) + self._request('torrent-reannounce', {}, ids, True, timeout=timeout) + + def info(self, ids=[], arguments={}, timeout=DEFAULT_TIMEOUT): + """Get detailed information for torrent(s) with provided id(s).""" + if not arguments: + arguments = self.torrent_get_arguments + return self._request('torrent-get', {'fields': arguments}, ids, timeout=timeout) + + def get_files(self, ids=[], timeout=DEFAULT_TIMEOUT): + """ + Get list of files for provided torrent id(s). + This function returns a dictonary for each requested torrent id holding + the information about the files. + """ + fields = ['id', 'name', 'hashString', 'files', 'priorities', 'wanted'] + request_result = self._request('torrent-get', {'fields': fields}, ids, timeout=timeout) + result = {} + for id, torrent in request_result.iteritems(): + result[id] = torrent.files() + return result + + def set_files(self, items, timeout=DEFAULT_TIMEOUT): + """ + Set file properties. Takes a dictonary with similar contents as the + result of get_files. + """ + if not isinstance(items, dict): + raise ValueError('Invalid file description') + for tid, files in items.iteritems(): + if not isinstance(files, dict): + continue + wanted = [] + unwanted = [] + priority_high = [] + priority_normal = [] + priority_low = [] + for fid, file in files.iteritems(): + if not isinstance(file, dict): + continue + if 'selected' in file and file['selected']: + wanted.append(fid) + else: + unwanted.append(fid) + if 'priority' in file: + if file['priority'] == 'high': + priority_high.append(fid) + elif file['priority'] == 'normal': + priority_normal.append(fid) + elif file['priority'] == 'low': + priority_low.append(fid) + self.change([tid], files_wanted = wanted + , files_unwanted = unwanted + , priority_high = priority_high + , priority_normal = priority_normal + , priority_low = priority_low, timeout=timeout) + + def list(self, timeout=DEFAULT_TIMEOUT): + """list all torrents""" + fields = ['id', 'hashString', 'name', 'sizeWhenDone', 'leftUntilDone' + , 'eta', 'status', 'rateUpload', 'rateDownload', 'uploadedEver' + , 'downloadedEver'] + return self._request('torrent-get', {'fields': fields}, timeout=timeout) + + def change(self, ids, timeout=DEFAULT_TIMEOUT, **kwargs): + """ + Change torrent parameters. This is the list of parameters that. + """ + args = {} + for key, value in kwargs.iteritems(): + argument = make_rpc_name(key) + (arg, val) = argument_value_convert('torrent-set' + , argument, value, self.rpc_version) + args[arg] = val + + if len(args) > 0: + self._request('torrent-set', args, ids, True, timeout=timeout) + else: + ValueError("No arguments to set") + + def move(self, ids, location, timeout=DEFAULT_TIMEOUT): + """Move torrent data to the new location.""" + self._rpc_version_warning(6) + args = {'location': location, 'move': True} + self._request('torrent-set-location', args, ids, True, timeout=timeout); + + def locate(self, ids, location, timeout=DEFAULT_TIMEOUT): + """Locate torrent data at the location.""" + self._rpc_version_warning(6) + args = {'location': location, 'move': False} + self._request('torrent-set-location', args, ids, True, timeout=timeout); + + def get_session(self, timeout=DEFAULT_TIMEOUT): + """Get session parameters""" + self._request('session-get', timeout=timeout) + return self.session + + def set_session(self, timeout=DEFAULT_TIMEOUT, **kwargs): + """Set session parameters""" + args = {} + for key, value in kwargs.iteritems(): + if key == 'encryption' and value not in ['required', 'preferred', 'tolerated']: + raise ValueError('Invalid encryption value') + argument = make_rpc_name(key) + (arg, val) = argument_value_convert('session-set' + , argument, value, self.rpc_version) + args[arg] = val + if len(args) > 0: + self._request('session-set', args, timeout=timeout) + + def blocklist_update(self, timeout=DEFAULT_TIMEOUT): + """Update block list. Returns the size of the block list.""" + self._rpc_version_warning(5) + result = self._request('blocklist-update', timeout=timeout) + if 'blocklist-size' in result: + return result['blocklist-size'] + return None + + def port_test(self, timeout=DEFAULT_TIMEOUT): + """ + Tests to see if your incoming peer port is accessible from the + outside world. + """ + self._rpc_version_warning(5) + result = self._request('port-test', timeout=timeout) + if 'port-is-open' in result: + return result['port-is-open'] + return None + + def session_stats(self, timeout=DEFAULT_TIMEOUT): + """Get session statistics""" + self._request('session-stats', timeout=timeout) + return self.session diff --git a/resources/lib/transmissionrpc-0.4/utils.py b/resources/lib/transmissionrpc-0.4/utils.py new file mode 100644 index 0000000..9e61c69 --- /dev/null +++ b/resources/lib/transmissionrpc-0.4/utils.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +# 2008-07, Erik Svensson + +import socket, datetime +import constants +from constants import logger + +UNITS = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB'] + +def format_size(size): + s = float(size) + i = 0 + while size >= 1024.0 and i < len(UNITS): + i += 1 + size /= 1024.0 + return (size, UNITS[i]) + +def format_speed(size): + (size, unit) = format_size(size) + return (size, unit + '/s') + +def format_timedelta(delta): + minutes, seconds = divmod(delta.seconds, 60) + hours, minutes = divmod(minutes, 60) + return '%d %02d:%02d:%02d' % (delta.days, hours, minutes, seconds) + +def format_timestamp(timestamp): + if timestamp > 0: + dt = datetime.datetime.fromtimestamp(timestamp) + return dt.isoformat(' ') + else: + return '-' + +class INetAddressError(Exception): + pass + +def inet_address(address, default_port, default_address='localhost'): + addr = address.split(':') + if len(addr) == 1: + try: + port = int(addr[0]) + addr = default_address + except: + addr = addr[0] + port = default_port + elif len(addr) == 2: + port = int(addr[1]) + if len(addr[0]) == 0: + addr = default_address + else: + addr = addr[0] + else: + addr = default_address + port = default_port + try: + socket.getaddrinfo(addr, port, socket.AF_INET, socket.SOCK_STREAM) + except socket.gaierror, e: + raise INetAddressError('Cannot look up address "%s".' % address) + return (addr, port) + +def rpc_bool(arg): + if isinstance(arg, (str, unicode)): + try: + arg = bool(int(arg)) + except: + arg = arg.lower() in [u'true', u'yes'] + if bool(arg): + return 1 + else: + return 0 + +TR_TYPE_MAP = { + 'number' : int, + 'string' : str, + 'double': float, + 'boolean' : rpc_bool, + 'array': list, + 'object': dict +} + +def make_python_name(name): + return name.replace('-', '_') + +def make_rpc_name(name): + return name.replace('_', '-') + +def argument_value_convert(method, argument, value, rpc_version): + if method in ('torrent-add', 'torrent-get', 'torrent-set'): + args = constants.TORRENT_ARGS[method[-3:]] + elif method in ('session-get', 'session-set'): + args = constants.SESSION_ARGS[method[-3:]] + else: + return ValueError('Method "%s" not supported' % (method)) + if argument in args: + info = args[argument] + invalid_version = True + while invalid_version: + invalid_version = False + replacement = None + if rpc_version < info[1]: + invalid_version = True + replacement = info[3] + if info[2] and info[2] <= rpc_version: + invalid_version = True + replacement = info[4] + if invalid_version: + if replacement: + logger.warning( + 'Replacing requested argument "%s" with "%s".' + % (argument, replacement)) + argument = replacement + info = args[argument] + else: + raise ValueError( + 'Method "%s" Argument "%s" does not exist in version %d.' + % (method, argument, rpc_version)) + return (argument, TR_TYPE_MAP[info[0]](value)) + else: + raise ValueError('Argument "%s" does not exists for method "%s".', + (argument, method)) + +def get_arguments(method, rpc_version): + if method in ('torrent-add', 'torrent-get', 'torrent-set'): + args = constants.TORRENT_ARGS[method[-3:]] + elif method in ('session-get', 'session-set'): + args = constants.SESSION_ARGS[method[-3:]] + else: + return ValueError('Method "%s" not supported' % (method)) + accessible = [] + for argument, info in args.iteritems(): + valid_version = True + if rpc_version < info[1]: + valid_version = False + if info[2] and info[2] <= rpc_version: + valid_version = False + if valid_version: + accessible.append(argument) + return accessible diff --git a/resources/lib/transmissionrpc/__init__.py b/resources/lib/transmissionrpc/__init__.py new file mode 100644 index 0000000..f4afa02 --- /dev/null +++ b/resources/lib/transmissionrpc/__init__.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# 2008-08, Erik Svensson + +from constants import * +from transmission import TransmissionError, Torrent, Session, Client + +__author__ = u'Erik Svensson ' +__version__ = u'0.3' +__copyright__ = u'Copyright (c) 2008 Erik Svensson' +__license__ = u'MIT' diff --git a/resources/lib/transmissionrpc/constants.py b/resources/lib/transmissionrpc/constants.py new file mode 100755 index 0000000..96ccc01 --- /dev/null +++ b/resources/lib/transmissionrpc/constants.py @@ -0,0 +1,230 @@ +# -*- coding: utf-8 -*- +# 2008-07, Erik Svensson + +import logging + +logger = logging.getLogger('transmissionrpc') +logger.setLevel(logging.ERROR) + +def mirror_dict(d): + d.update(dict((v, k) for k, v in d.iteritems())) + return d + +DEFAULT_PORT = 9091 + +TR_STATUS_CHECK_WAIT = (1<<0) +TR_STATUS_CHECK = (1<<1) +TR_STATUS_DOWNLOAD = (1<<2) +TR_STATUS_SEED = (1<<3) +TR_STATUS_STOPPED = (1<<4) + +STATUS = mirror_dict({ + 'check pending' : TR_STATUS_CHECK_WAIT, + 'checking' : TR_STATUS_CHECK, + 'downloading' : TR_STATUS_DOWNLOAD, + 'seeding' : TR_STATUS_SEED, + 'stopped' : TR_STATUS_STOPPED, +}) + +TR_PRI_LOW = -1 +TR_PRI_NORMAL = 0 +TR_PRI_HIGH = 1 + +PRIORITY = mirror_dict({ + 'low' : TR_PRI_LOW, + 'normal' : TR_PRI_NORMAL, + 'high' : TR_PRI_HIGH +}) + +TR_RATIOLIMIT_GLOBAL = 0 # follow the global settings +TR_RATIOLIMIT_SINGLE = 1 # override the global settings, seeding until a certain ratio +TR_RATIOLIMIT_UNLIMITED = 2 # override the global settings, seeding regardless of ratio + +RATIO_LIMIT = mirror_dict({ + 'global' : TR_RATIOLIMIT_GLOBAL, + 'single' : TR_RATIOLIMIT_SINGLE, + 'unlimeted' : TR_RATIOLIMIT_UNLIMITED +}) + +# A note on argument maps +# These maps are used to verify *-set methods. The information is structured in +# a tree. +# set +- - [, , , , ] +# | +- - [, , , , ] +# | +# get +- - [, , , , ] +# +- - [, , , , ] + +# Arguments for torrent methods +TORRENT_ARGS = { + 'get' : { + 'activityDate': ('number', 1, None, None, None), + 'addedDate': ('number', 1, None, None, None), + 'announceResponse': ('string', 1, None, None, None), + 'announceURL': ('string', 1, None, None, None), + 'bandwidthPriority': ('number', 5, None, None, None), + 'comment': ('string', 1, None, None, None), + 'corruptEver': ('number', 1, None, None, None), + 'creator': ('string', 1, None, None, None), + 'dateCreated': ('number', 1, None, None, None), + 'desiredAvailable': ('number', 1, None, None, None), + 'doneDate': ('number', 1, None, None, None), + 'downloadDir': ('string', 4, None, None, None), + 'downloadedEver': ('number', 1, None, None, None), + 'downloaders': ('number', 4, None, None, None), + 'downloadLimit': ('number', 1, None, None, None), + 'downloadLimited': ('boolean', 5, None, None, None), + 'downloadLimitMode': ('number', 1, 5, None, None), + 'error': ('number', 1, None, None, None), + 'errorString': ('number', 1, None, None, None), + 'eta': ('number', 1, None, None, None), + 'files': ('array', 1, None, None, None), + 'fileStats': ('array', 5, None, None, None), + 'hashString': ('string', 1, None, None, None), + 'haveUnchecked': ('number', 1, None, None, None), + 'haveValid': ('number', 1, None, None, None), + 'honorsSessionLimits': ('boolean', 5, None, None, None), + 'id': ('number', 1, None, None, None), + 'isPrivate': ('boolean', 1, None, None, None), + 'lastAnnounceTime': ('number', 1, None, None, None), + 'lastScrapeTime': ('number', 1, None, None, None), + 'leechers': ('number', 1, None, None, None), + 'leftUntilDone': ('number', 1, None, None, None), + 'manualAnnounceTime': ('number', 1, None, None, None), + 'maxConnectedPeers': ('number', 1, None, None, None), + 'name': ('string', 1, None, None, None), + 'nextAnnounceTime': ('number', 1, None, None, None), + 'nextScrapeTime': ('number', 1, None, None, None), + 'peer-limit': ('number', 5, None, None, None), + 'peers': ('array', 2, None, None, None), + 'peersConnected': ('number', 1, None, None, None), + 'peersFrom': ('object', 1, None, None, None), + 'peersGettingFromUs': ('number', 1, None, None, None), + 'peersKnown': ('number', 1, None, None, None), + 'peersSendingToUs': ('number', 1, None, None, None), + 'percentDone': ('double', 5, None, None, None), + 'pieces': ('string', 5, None, None, None), + 'pieceCount': ('number', 1, None, None, None), + 'pieceSize': ('number', 1, None, None, None), + 'priorities': ('array', 1, None, None, None), + 'rateDownload': ('number', 1, None, None, None), + 'rateUpload': ('number', 1, None, None, None), + 'recheckProgress': ('double', 1, None, None, None), + 'scrapeResponse': ('string', 1, None, None, None), + 'scrapeURL': ('string', 1, None, None, None), + 'seeders': ('number', 1, None, None, None), + 'seedRatioLimit': ('double', 5, None, None, None), + 'seedRatioMode': ('number', 5, None, None, None), + 'sizeWhenDone': ('number', 1, None, None, None), + 'startDate': ('number', 1, None, None, None), + 'status': ('number', 1, None, None, None), + 'swarmSpeed': ('number', 1, None, None, None), + 'timesCompleted': ('number', 1, None, None, None), + 'trackers': ('array', 1, None, None, None), + 'totalSize': ('number', 1, None, None, None), + 'torrentFile': ('string', 5, None, None, None), + 'uploadedEver': ('number', 1, None, None, None), + 'uploadLimit': ('number', 1, None, None, None), + 'uploadLimitMode': ('number', 1, 5, None, None), + 'uploadLimited': ('boolean', 5, None, None, None), + 'uploadRatio': ('double', 1, None, None, None), + 'wanted': ('array', 1, None, None, None), + 'webseeds': ('array', 1, None, None, None), + 'webseedsSendingToUs': ('number', 1, None, None, None), + }, + 'set': { + 'bandwidthPriority': ('number', 5, None, None, None), + 'downloadLimit': ('number', 5, None, 'speed-limit-down', None), + 'downloadLimited': ('boolean', 5, None, 'speed-limit-down-enabled', None), + 'files-wanted': ('array', 1, None, None, None), + 'files-unwanted': ('array', 1, None, None, None), + 'honorsSessionLimits': ('boolean', 5, None, None, None), + 'ids': ('array', 1, None, None, None), + 'peer-limit': ('number', 1, None, None, None), + 'priority-high': ('array', 1, None, None, None), + 'priority-low': ('array', 1, None, None, None), + 'priority-normal': ('array', 1, None, None, None), + 'seedRatioLimit': ('double', 5, None, None, None), + 'seedRatioMode': ('number', 5, None, None, None), + 'speed-limit-down': ('number', 1, 5, None, 'downloadLimit'), + 'speed-limit-down-enabled': ('boolean', 1, 5, None, 'downloadLimited'), + 'speed-limit-up': ('number', 1, 5, None, 'uploadLimit'), + 'speed-limit-up-enabled': ('boolean', 1, 5, None, 'uploadLimited'), + 'uploadLimit': ('number', 5, None, 'speed-limit-up', None), + 'uploadLimited': ('boolean', 5, None, 'speed-limit-up-enabled', None), + }, + 'add': { + 'download-dir': ('string', 1, None, None, None), + 'filename': ('string', 1, None, None, None), + 'files-wanted': ('array', 1, None, None, None), + 'files-unwanted': ('array', 1, None, None, None), + 'metainfo': ('string', 1, None, None, None), + 'paused': ('boolean', 1, None, None, None), + 'peer-limit': ('number', 1, None, None, None), + 'priority-high': ('array', 1, None, None, None), + 'priority-low': ('array', 1, None, None, None), + 'priority-normal': ('array', 1, None, None, None), + } +} + +# Arguments for session methods +SESSION_ARGS = { + 'get': { + "alt-speed-down": ('number', 5, None, None, None), + "alt-speed-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-begin": ('number', 5, None, None, None), + "alt-speed-time-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-end": ('number', 5, None, None, None), + "alt-speed-time-day": ('number', 5, None, None, None), + "alt-speed-up": ('number', 5, None, None, None), + "blocklist-enabled": ('boolean', 5, None, None, None), + "blocklist-size": ('number', 5, None, None, None), + "encryption": ('string', 1, None, None, None), + "download-dir": ('string', 1, None, None, None), + "peer-limit": ('number', 1, 5, None, None), + "peer-limit-global": ('number', 5, None, None, None), + "peer-limit-per-torrent": ('number', 5, None, None, None), + "pex-allowed": ('boolean', 1, 5, None, None), + "pex-enabled": ('boolean', 5, None, None, None), + "port": ('number', 1, 5, None, None), + "peer-port": ('number', 5, None, None, None), + "peer-port-random-on-start": ('boolean', 5, None, None, None), + "port-forwarding-enabled": ('boolean', 1, None, None, None), + "rpc-version": ('number', 4, None, None, None), + "rpc-version-minimum": ('number', 4, None, None, None), + "seedRatioLimit": ('double', 5, None, None, None), + "seedRatioLimited": ('boolean', 5, None, None, None), + "speed-limit-down": ('number', 1, None, None, None), + "speed-limit-down-enabled": ('boolean', 1, None, None, None), + "speed-limit-up": ('number', 1, None, None, None), + "speed-limit-up-enabled": ('boolean', 1, None, None, None), + "version": ('string', 3, None, None, None), + }, + 'set': { + "alt-speed-down": ('number', 5, None, None, None), + "alt-speed-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-begin": ('number', 5, None, None, None), + "alt-speed-time-enabled": ('boolean', 5, None, None, None), + "alt-speed-time-end": ('number', 5, None, None, None), + "alt-speed-time-day": ('number', 5, None, None, None), + "alt-speed-up": ('number', 5, None, None, None), + "blocklist-enabled": ('boolean', 5, None, None, None), + "encryption": ('string', 1, None, None, None), + "download-dir": ('string', 1, None, None, None), + "peer-limit": ('number', 1, 5, None, 'peer-limit-global'), + "peer-limit-global": ('number', 5, None, 'peer-limit', None), + "peer-limit-per-torrent": ('number', 5, None, None, None), + "pex-allowed": ('boolean', 1, 5, None, 'pex-enabled'), + "pex-enabled": ('boolean', 5, None, 'pex-allowed', None), + "port": ('number', 1, 5, None, 'peer-port'), + "peer-port": ('number', 5, None, 'port', None), + "peer-port-random-on-start": ('boolean', 5, None, None, None), + "port-forwarding-enabled": ('boolean', 1, None, None, None), + "seedRatioLimit": ('double', 5, None, None, None), + "seedRatioLimited": ('boolean', 5, None, None, None), + "speed-limit-down": ('number', 1, None, None, None), + "speed-limit-down-enabled": ('boolean', 1, None, None, None), + "speed-limit-up": ('number', 1, None, None, None), + "speed-limit-up-enabled": ('boolean', 1, None, None, None), + }, +} diff --git a/resources/lib/transmissionrpc/transmission.py b/resources/lib/transmissionrpc/transmission.py new file mode 100755 index 0000000..fb3867d --- /dev/null +++ b/resources/lib/transmissionrpc/transmission.py @@ -0,0 +1,606 @@ +# -*- coding: utf-8 -*- +# 2008-07, Erik Svensson + +import sys, os, time, datetime +import re +import httplib, urllib2, base64, socket + +try: + import json +except ImportError: + import simplejson as json + +from constants import * +from utils import * + +class TransmissionError(Exception): + def __init__(self, message='', original=None): + Exception.__init__(self, message) + self.message = message + self.original = original + + def __str__(self): + if self.original: + original_name = type(self.original).__name__ + return '%s Original exception: %s, "%s"' % (self.message, original_name, self.original.args) + else: + return self.args + +class Torrent(object): + """ + Torrent is a class holding the data raceived from Transmission regarding a bittorrent transfer. + All fetched torrent fields are accessable through this class using attributes. + This class has a few convenience properties using the torrent data. + """ + + def __init__(self, fields): + if 'id' not in fields: + raise ValueError('Torrent requires an id') + self.fields = {} + self.update(fields) + + def __repr__(self): + return '' % (self.fields['id'], self.fields['name']) + + def __str__(self): + return 'torrent %s' % self.fields['name'] + + def update(self, other): + """Update the torrent data from a Transmission arguments dictinary""" + fields = None + if isinstance(other, dict): + fields = other + elif isinstance(other, Torrent): + fields = other.fields + else: + raise ValueError('Cannot update with supplied data') + for k, v in fields.iteritems(): + self.fields[k.replace('-', '_')] = v + + def files(self): + """ + Get list of files for this torrent. This function returns a dictionary with file information for each file. + """ + result = {} + if 'files' in self.fields: + indicies = xrange(len(self.fields['files'])) + files = self.fields['files'] + priorities = self.fields['priorities'] + wanted = self.fields['wanted'] + index = 1 + for item in zip(indicies, files, priorities, wanted): + selected = bool(item[3]) + priority = PRIORITY[item[2]] + result[item[0]] = { + 'selected': selected, + 'priority': priority, + 'size': item[1]['length'], + 'name': item[1]['name'], + 'completed': item[1]['bytesCompleted']} + return result + + def __getattr__(self, name): + try: + return self.fields[name] + except KeyError, e: + raise AttributeError('No attribute %s' % name) + + @property + def status(self): + """Get the status as string.""" + return STATUS[self.fields['status']] + + @property + def progress(self): + """Get the download progress in percent as float.""" + try: + return 100.0 * (self.fields['sizeWhenDone'] - self.fields['leftUntilDone']) / float(self.fields['sizeWhenDone']) + except ZeroDivisionError: + return 0.0 + + @property + def ratio(self): + """Get the upload/download ratio.""" + try: + return self.fields['uploadedEver'] / float(self.fields['downloadedEver']) + except ZeroDivisionError: + return 0.0 + + @property + def eta(self): + """Get the "eta" as datetime.timedelta.""" + eta = self.fields['eta'] + if eta >= 0: + return datetime.timedelta(seconds=eta) + else: + ValueError('eta not valid') + + @property + def date_active(self): + """Get the attribute "activityDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['activityDate']) + + @property + def date_added(self): + """Get the attribute "addedDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['addedDate']) + + @property + def date_started(self): + """Get the attribute "startDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['startDate']) + + @property + def date_done(self): + """Get the attribute "doneDate" as datetime.datetime.""" + return datetime.datetime.fromtimestamp(self.fields['doneDate']) + + def format_eta(self): + """Returns the attribute "eta" formatted as a string.""" + eta = self.fields['eta'] + if eta == -1: + return 'not available' + elif eta == -2: + return 'unknown' + else: + return format_timedelta(self.eta) + +class Session(object): + """ + Session is a class holding the session data for a Transmission daemon. + + Access the session field can be done through attributes. + The attributes available are the same as the session arguments in the + Transmission RPC specification, but with underscore instead of hypen. + ``download-dir`` -> ``download_dir``. + """ + + def __init__(self, fields={}): + self.fields = {} + self.update(fields) + + def update(self, other): + """Update the session data from a session arguments dictinary""" + + fields = None + if isinstance(other, dict): + fields = other + elif isinstance(other, Session): + fields = other.fields + else: + raise ValueError('Cannot update with supplied data') + + for k, v in fields.iteritems(): + self.fields[k.replace('-', '_')] = v + + def __getattr__(self, name): + try: + return self.fields[name] + except KeyError, e: + raise AttributeError('No attribute %s' % name) + + def __str__(self): + text = '' + for k, v in self.fields.iteritems(): + text += "% 32s: %s\n" % (k[-32:], v) + return text + +class Client(object): + """ + This is it. This class implements the json-RPC protocol to communicate with Transmission. + """ + + def __init__(self, address='localhost', port=DEFAULT_PORT, user=None, password=None): + base_url = 'http://' + address + ':' + str(port) + self.url = base_url + '/transmission/rpc' + if user and password: + password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() + password_manager.add_password(realm=None, uri=self.url, user=user, passwd=password) + opener = urllib2.build_opener( + urllib2.HTTPBasicAuthHandler(password_manager) + , urllib2.HTTPDigestAuthHandler(password_manager) + ) + urllib2.install_opener(opener) + elif user or password: + logger.warning('Either user or password missing, not using authentication.') + self._sequence = 0 + self.session = Session() + self.sessionid = 0 + self.protocol_version = None + self.get_session() + self.torrent_get_arguments = get_arguments('torrent-get' + , self.rpc_version) + + def _debug_request(self, request): + logger.debug( + json.dumps( + { + 'request': { + 'url': request.get_full_url(), + 'request-headers': dict(request.header_items()), + 'request-data': json.loads(request.data), + } + }, + indent=2 + ) + ) + + def _debug_response(self, response, response_data): + try: + response_data = json.loads(response_data) + except: + pass + logger.debug( + json.dumps( + { + 'response': { + 'url': response.url, + 'code': response.code, + 'msg': response.msg, + 'headers': dict(response.headers), + 'data': response_data, + } + }, + indent=2 + ) + ) + + def _http_query(self, query): + headers = {'X-Transmission-Session-Id': self.sessionid} + request = urllib2.Request(self.url, query, headers) + request_count = 0 + while True: + error_data = "" + try: + try: + self._debug_request(request) + socket.setdefaulttimeout(10) + if (sys.version_info[0] == 2 and sys.version_info[1] > 5) or sys.version_info[0] > 2: + response = urllib2.urlopen(request, timeout=60) + else: + response = urllib2.urlopen(request) + break + except urllib2.HTTPError, error: + error_data = error.read() + if error.code == 409: + logger.info('Server responded with 409, trying to set session-id.') + if request_count > 1: + raise TransmissionError('Session ID negotiation failed.', error) + if 'X-Transmission-Session-Id' in error.headers: + self.sessionid = error.headers['X-Transmission-Session-Id'] + request.add_header('X-Transmission-Session-Id', self.sessionid) + else: + raise TransmissionError('Unknown conflict.', error) + except urllib2.URLError, error: + raise TransmissionError('Failed to connect to daemon.', error) + except httplib.BadStatusLine, error: + if (request_count > 1): + raise TransmissionError('Failed to request %s "%s".' % (self.url, query), error) + finally: + if error_data: + self._debug_response(error, error_data) + request_count = request_count + 1 + result = response.read() + self._debug_response(response, result) + return result + + def _request(self, method, arguments={}, ids=[], require_ids = False): + """Send json-rpc request to Transmission using http POST""" + + if not isinstance(method, (str, unicode)): + raise ValueError('request takes method as string') + if not isinstance(arguments, dict): + raise ValueError('request takes arguments as dict') + ids = self._format_ids(ids) + if len(ids) > 0: + arguments['ids'] = ids + elif require_ids: + raise ValueError('request require ids') + + query = json.dumps({'tag': self._sequence, 'method': method + , 'arguments': arguments}) + logger.info(query) + self._sequence += 1 + start = time.time() + http_data = self._http_query(query) + elapsed = time.time() - start + logger.info('http request took %.3f s' % (elapsed)) + + try: + data = json.loads(http_data) + except ValueError, e: + logger.error('Error: ' + str(e)) + logger.error('Request: \"%s\"' % (query)) + logger.error('HTTP data: \"%s\"' % (http_data)) + raise + + logger.info(json.dumps(data, indent=2)) + + if data['result'] != 'success': + raise TransmissionError('Query failed with result \"%s\"' + % data['result']) + + results = {} + if method == 'torrent-get': + for item in data['arguments']['torrents']: + results[item['id']] = Torrent(item) + if self.protocol_version == 2 and 'peers' not in item: + self.protocol_version = 1 + elif method == 'torrent-add': + item = data['arguments']['torrent-added'] + results[item['id']] = Torrent(item) + elif method == 'session-get': + self._update_session(data['arguments']) + elif method == 'session-stats': + # older versions of T has the return data in "session-stats" + if 'session-stats' in data['arguments']: + self._update_session(data['arguments']['session-stats']) + else: + self._update_session(data['arguments']) + elif method in ('port-test', 'blocklist-update'): + results = data['arguments'] + else: + return None + + return results + + def _format_ids(self, args): + """Take things and make them valid torrent identifiers""" + ids = [] + + if isinstance(args, (int, long)): + ids.append(args) + elif isinstance(args, (str, unicode)): + for item in re.split(u'[ ,]+', args): + if len(item) == 0: + continue + addition = None + try: + # handle index + addition = [int(item)] + except ValueError: + pass + if not addition: + # handle hashes + try: + int(item, 16) + addition = [item] + except: + pass + if not addition: + # handle index ranges i.e. 5:10 + match = re.match(u'^(\d+):(\d+)$', item) + if match: + try: + idx_from = int(match.group(1)) + idx_to = int(match.group(2)) + addition = range(idx_from, idx_to + 1) + except: + pass + if not addition: + raise ValueError(u'Invalid torrent id, \"%s\"' % item) + ids.extend(addition) + elif isinstance(args, (list)): + for item in args: + ids.extend(self._format_ids(item)) + else: + raise ValueError(u'Invalid torrent id') + return ids + + def _update_session(self, data): + self.session.update(data) + + @property + def rpc_version(self): + if self.protocol_version == None: + if hasattr(self.session, 'rpc_version'): + self.protocol_version = self.session.rpc_version + elif hasattr(self.session, 'version'): + self.protocol_version = 3 + else: + self.protocol_version = 2 + return self.protocol_version + + def _rpc_version_warning(self, version): + if self.rpc_version < version: + logger.warning('Using feature not supported by server. RPC version for server %d, feature introduced in %d.' % (self.rpc_version, version)) + + def add(self, data, **kwargs): + """ + Add torrent to transfers list. Takes a base64 encoded .torrent file in data. + Additional arguments are: + + * `paused`, boolean, Whether to pause the transfer on add. + * `download_dir`, path, The directory where the downloaded + contents will be saved in. + * `peer_limit`, number, Limits the number of peers for this + transfer. + * `files_unwanted`, + * `files_wanted`, + * `priority_high`, + * `priority_low`, + * `priority_normal`, + """ + args = {'metainfo': data} + for key, value in kwargs.iteritems(): + argument = make_rpc_name(key) + (arg, val) = argument_value_convert('torrent-add', + argument, value, self.rpc_version) + args[arg] = val + return self._request('torrent-add', args) + + def add_url(self, torrent_url, **kwargs): + """ + Add torrent to transfers list. Takes a url to a .torrent file. + Additional arguments are: + + * `paused`, boolean, Whether to pause the transfer on add. + * `download_dir`, path, The directory where the downloaded + contents will be saved in. + * `peer_limit`, number, Limits the number of peers for this + transfer. + * `files_unwanted`, + * `files_wanted`, + * `priority_high`, + * `priority_low`, + * `priority_normal`, + """ + torrent_file = None + if os.path.exists(torrent_url): + torrent_file = open(torrent_url, 'r') + else: + try: + torrent_file = urllib2.urlopen(torrent_url) + except: + torrent_file = None + + if not torrent_file: + raise TransmissionError('File does not exist.') + + torrent_data = base64.b64encode(torrent_file.read()) + return self.add(torrent_data, **kwargs) + + def remove(self, ids, delete_data=False): + """ + remove torrent(s) with provided id(s). Local data is removed if + delete_data is True, otherwise not. + """ + self._rpc_version_warning(3) + self._request('torrent-remove', + {'delete-local-data':rpc_bool(delete_data)}, ids, True) + + def start(self, ids): + """start torrent(s) with provided id(s)""" + self._request('torrent-start', {}, ids, True) + + def stop(self, ids): + """stop torrent(s) with provided id(s)""" + self._request('torrent-stop', {}, ids, True) + + def verify(self, ids): + """verify torrent(s) with provided id(s)""" + self._request('torrent-verify', {}, ids, True) + + def reannounce(self, ids): + """reannounce torrent(s) with provided id(s)""" + self._rpc_version_warning(5) + self._request('torrent-reannounce', {}, ids, True) + + def info(self, ids=[], arguments={}): + """Get detailed information for torrent(s) with provided id(s).""" + if not arguments: + arguments = self.torrent_get_arguments + return self._request('torrent-get', {'fields': arguments}, ids) + + def get_files(self, ids=[]): + """ + Get list of files for provided torrent id(s). + This function returns a dictonary for each requested torrent id holding + the information about the files. + """ + fields = ['id', 'name', 'hashString', 'files', 'priorities', 'wanted'] + request_result = self._request('torrent-get', {'fields': fields}, ids) + result = {} + for id, torrent in request_result.iteritems(): + result[id] = torrent.files() + return result + + def set_files(self, items): + """ + Set file properties. Takes a dictonary with similar contents as the + result of get_files. + """ + if not isinstance(items, dict): + raise ValueError('Invalid file description') + for tid, files in items.iteritems(): + if not isinstance(files, dict): + continue + wanted = [] + unwanted = [] + priority_high = [] + priority_normal = [] + priority_low = [] + for fid, file in files.iteritems(): + if not isinstance(file, dict): + continue + if 'selected' in file and file['selected']: + wanted.append(fid) + else: + unwanted.append(fid) + if 'priority' in file: + if file['priority'] == 'high': + priority_high.append(fid) + elif file['priority'] == 'normal': + priority_normal.append(fid) + elif file['priority'] == 'low': + priority_low.append(fid) + self.change([tid], files_wanted = wanted + , files_unwanted = unwanted + , priority_high = priority_high + , priority_normal = priority_normal + , priority_low = priority_low) + + def list(self): + """list all torrents""" + fields = ['id', 'hashString', 'name', 'sizeWhenDone', 'leftUntilDone' + , 'eta', 'status', 'rateUpload', 'rateDownload', 'uploadedEver' + , 'downloadedEver'] + return self._request('torrent-get', {'fields': fields}) + + def change(self, ids, **kwargs): + """ + Change torrent parameters. This is the list of parameters that. + """ + args = {} + for key, value in kwargs.iteritems(): + argument = make_rpc_name(key) + (arg, val) = argument_value_convert('torrent-set' + , argument, value, self.rpc_version) + args[arg] = val + + if len(args) > 0: + self._request('torrent-set', args, ids, True) + else: + ValueError("No arguments to set") + + def get_session(self): + """Get session parameters""" + self._request('session-get') + return self.session + + def set_session(self, **kwargs): + """Set session parameters""" + args = {} + for key, value in kwargs.iteritems(): + if key == 'encryption' and value not in ['required', 'preferred', 'tolerated']: + raise ValueError('Invalid encryption value') + argument = make_rpc_name(key) + (arg, val) = argument_value_convert('session-set' + , argument, value, self.rpc_version) + args[arg] = val + if len(args) > 0: + self._request('session-set', args) + + def blocklist_update(self): + """Update block list. Returns the size of the block list.""" + self._rpc_version_warning(5) + result = self._request('blocklist-update') + if 'blocklist-size' in result: + return result['blocklist-size'] + return None + + def port_test(self): + """ + Tests to see if your incoming peer port is accessible from the + outside world. + """ + self._rpc_version_warning(5) + result = self._request('port-test') + if 'port-is-open' in result: + return result['port-is-open'] + return None + + def session_stats(self): + """Get session statistics""" + self._request('session-stats') + return self.session diff --git a/resources/lib/transmissionrpc/utils.py b/resources/lib/transmissionrpc/utils.py new file mode 100644 index 0000000..3e4099e --- /dev/null +++ b/resources/lib/transmissionrpc/utils.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +# 2008-07, Erik Svensson + +import socket, datetime +import constants +from constants import logger + +UNITS = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB'] + +def format_size(size): + s = float(size) + i = 0 + while size >= 1024.0 and i < len(UNITS): + i += 1 + size /= 1024.0 + return (size, UNITS[i]) + +def format_speed(size): + (size, unit) = format_size(size) + return (size, unit + '/s') + +def format_timedelta(delta): + minutes, seconds = divmod(delta.seconds, 60) + hours, minutes = divmod(minutes, 60) + return '%d %02d:%02d:%02d' % (delta.days, hours, minutes, seconds) + +def format_timestamp(timestamp): + if timestamp > 0: + dt = datetime.datetime.fromtimestamp(timestamp) + return dt.isoformat(' ') + else: + return '-' + +class INetAddressError(Exception): + pass + +def inet_address(address, default_port, default_address='localhost'): + addr = address.split(':') + if len(addr) == 1: + try: + port = int(addr[0]) + addr = default_address + except: + addr = addr[0] + port = default_port + elif len(addr) == 2: + port = int(addr[1]) + if len(addr[0]) == 0: + addr = default_address + else: + addr = addr[0] + else: + addr = default_address + port = default_port + try: + socket.getaddrinfo(addr, port, socket.AF_INET, socket.SOCK_STREAM) + except socket.gaierror, e: + raise INetAddressError('Cannot look up address "%s".' % address) + return (addr, port) + +def rpc_bool(arg): + if isinstance(arg, (str, unicode)): + try: + arg = bool(int(arg)) + except: + arg = arg.lower() in [u'true', u'yes'] + if bool(arg): + return 1 + else: + return 0 + +TR_TYPE_MAP = { + 'number' : int, + 'string' : str, + 'double': float, + 'boolean' : rpc_bool, + 'array': list, + 'object': dict +} + +def make_python_name(name): + return name.replace('-', '_') + +def make_rpc_name(name): + return name.replace('_', '-') + +def argument_value_convert(method, argument, value, rpc_version): + if method in ('torrent-add', 'torrent-get', 'torrent-set'): + args = constants.TORRENT_ARGS[method[-3:]] + elif method in ('session-get', 'session-set'): + args = constants.SESSION_ARGS[method[-3:]] + else: + return ValueError('Method "%s" not supported' % (method)) + if argument in args: + info = args[argument] + invalid_version = True + while invalid_version: + invalid_version = False + replacement = None + if rpc_version < info[1]: + invalid_version = True + replacement = info[3] + if info[2] and info[2] <= rpc_version: + invalid_version = True + replacement = info[4] + if invalid_version: + if replacement: + logger.warning( + 'Replacing requested argument "%s" with "%s".' + % (argument, replacement)) + argument = replacement + info = args[argument] + else: + raise ValueError( + 'Method "%s" Argument "%s" does not exist in version %d.' + % (method, argument, rpc_version)) + return (argument, TR_TYPE_MAP[info[0]](value)) + else: + raise ValueError('Argument "%s" does not exists for method "%s".', + (argument, method)) + +def get_arguments(method, rpc_version): + if method in ('torrent-add', 'torrent-get', 'torrent-set'): + args = constants.TORRENT_ARGS[method[-3:]] + elif method in ('session-get', 'session-set'): + args = constants.SESSION_ARGS[method[-3:]] + else: + return ValueError('Method "%s" not supported' % (method)) + accessible = [] + for argument, info in args.iteritems(): + valid_version = True + if rpc_version < info[1]: + valid_version = False + if info[2] and info[2] <= rpc_version: + valid_version = False + if valid_version: + accessible.append(argument) + return accessible diff --git a/resources/settings.xml b/resources/settings.xml new file mode 100644 index 0000000..7812ec4 --- /dev/null +++ b/resources/settings.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/resources/skins/default/PAL/script-Transmission-details.xml b/resources/skins/default/PAL/script-Transmission-details.xml new file mode 100644 index 0000000..f9bc1bb --- /dev/null +++ b/resources/skins/default/PAL/script-Transmission-details.xml @@ -0,0 +1,20 @@ + + 20 + yes + + + textarea + 0 + 0 + 720 + 40 + true + + font11 + white + center + + + + + diff --git a/resources/skins/default/PAL/script-Transmission-main.xml b/resources/skins/default/PAL/script-Transmission-main.xml new file mode 100644 index 0000000..b7873bd --- /dev/null +++ b/resources/skins/default/PAL/script-Transmission-main.xml @@ -0,0 +1,216 @@ + + 20 + + 1 + 20 + 20 + + + + backdrop + -20 + -20 + 720 + 576 + black.png + + + -10 + -8 + 700 + 560 + transmission-main.png + WindowOpen + WindowClose + + + + textarea + 0 + 0 + 700 + true + + font11 + white + center + + + 0 + 10 + + + Add torrent + 0 + 0 + 70 + 70 + center + top + 45 + + 20 + 12 + + + Remove torrent + 0 + 70 + 70 + 70 + center + top + 45 + + 20 + 11 + 13 + + + Stop torrent + 0 + 150 + 70 + 70 + center + top + 45 + + 20 + 12 + 14 + + + Start torrent + 0 + 220 + 70 + 70 + center + top + 45 + + 20 + 13 + 15 + + + Stop all torrents + 0 + 300 + 70 + 70 + center + top + 45 + + 20 + 14 + 16 + + + Start all torrents + 0 + 370 + 70 + 70 + center + top + 45 + + 20 + 15 + 17 + + + Exit + 0 + 450 + 70 + 70 + center + top + 45 + + 20 + 16 + + + + + Torrent list + 90 + 35 + 560 + 500 + list + vertical + true + 11 + + + 0 + 0 + 610 + 70 + list-bg.png + + + 10 + 0 + 640 + 20 + ListItem.label + + + 15 + 20 + 635 + 20 + ListItem.label2 + + + + + 0 + 0 + 610 + 70 + Control.HasFocus(20) + list-bg-selected.png + + + 0 + 0 + 610 + 70 + !Control.HasFocus(20) + list-bg-selected-nofocus.png + + + 10 + 0 + 640 + 20 + ListItem.label + true + + + 15 + 20 + 635 + 20 + ListItem.label2 + + + + + diff --git a/resources/skins/default/media/black.png b/resources/skins/default/media/black.png new file mode 100644 index 0000000000000000000000000000000000000000..c1c2937c02daf2bb09d4c11c21a1484c009bd87a GIT binary patch literal 265 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgga9!^#n)mKaTY=J_OC9V-A&iT2y zsd*&~&PAz-C8;S2<(VZJ3hti10pX2&;y^_yo-U3d6}R4AU}R)a;5o1$^S_yX20y=` s#nml0axEE|SU3a}92yuXV0>t1w>{2ioGyDX3}_#Nr>mdKI;Vst0LUjjUjP6A literal 0 HcmV?d00001 diff --git a/resources/skins/default/media/blue.png b/resources/skins/default/media/blue.png new file mode 100644 index 0000000000000000000000000000000000000000..b877c718763eb928bfe92d3c107eb10c52b94467 GIT binary patch literal 227 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1SD0tpLGH$#^NA%Cx&(BWL^R}oCO|{#S9GG z!XV7ZFl&wkP>{XE)7O>#CJ!g8n#vCD2bX|Ck|nMYCC>S|xv6<249-QVi6yBi3gww4 z84B*6z5(HleBwYw0iG_7AsP4Ho;T!WFyLS?m|<&^ICtd(g-ltK)#`fHg>xE60SET+ Y8}DNBP%*e=2{fC*)78&qol`;+0ID%X{r~^~ literal 0 HcmV?d00001 diff --git a/resources/skins/default/media/list-bg-selected-nofocus.png b/resources/skins/default/media/list-bg-selected-nofocus.png new file mode 100644 index 0000000000000000000000000000000000000000..afc588e15d2175819ae81676a66019a4230c68a6 GIT binary patch literal 1346 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 kNKysytxWL$f70bECIX zGML|ZhNKJYGPC5FogEG?O4<{X<4fnW8wo`!tN$)eQ94%le&efOmCs%ne$oz`%hV9E zP(fmT?#YkQp~er-yk6axkQ@7C#f;snK5u(lH___xCau?g_tvkxx_EzY&*5Jm-Bh)e z80u9d0F6}QdQsAa=upK&cozgd#>LN zeqy)$f~`#D{l_1-zx;TpIL`4{N_lQovYa@O1TaS?83{1OTjD(d+;K literal 0 HcmV?d00001 diff --git a/resources/skins/default/media/transmission-main.png b/resources/skins/default/media/transmission-main.png new file mode 100644 index 0000000000000000000000000000000000000000..65e1f82cea18dc2369c3ae6559bc77c9e6832ae2 GIT binary patch literal 155056 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̋RQZ5ZMw*vMDshg)k+COv_u|QK0a|qL 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

  • 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 literal 0 HcmV?d00001 diff --git a/resources/skins/default/media/transmission-main.xcf b/resources/skins/default/media/transmission-main.xcf new file mode 100644 index 0000000000000000000000000000000000000000..6f638f7bcc8616ca7e01c42367c738659a66fc42 GIT binary patch literal 1053942 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�f|bq5tMXHRtWR2%l=HXity2Hf{oKyR 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

    =gFkjtI<;TlbccA^Q8p(@9_s& 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

    AO=o|C{^%i_=>{8jVRh}I!8uWK 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 literal 0 HcmV?d00001 diff --git a/resources/skins/default/skin.xml b/resources/skins/default/skin.xml new file mode 100644 index 0000000..c2a086b --- /dev/null +++ b/resources/skins/default/skin.xml @@ -0,0 +1,11 @@ + + pal + pal + 2.1 + 0 + + + default + correl + + \ No newline at end of file diff --git a/resources/skins/media/.directory b/resources/skins/media/.directory new file mode 100644 index 0000000..9120ff5 --- /dev/null +++ b/resources/skins/media/.directory @@ -0,0 +1,3 @@ +[Dolphin] +Timestamp=2009,12,9,0,31,14 +ViewMode=1 diff --git a/resources/skins/media/transmission-512.png b/resources/skins/media/transmission-512.png new file mode 100644 index 0000000000000000000000000000000000000000..96c17bde4b5aa6e1a053e35d734663c91881b229 GIT binary patch literal 43855 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

    2_VIZUe8x6qux` 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 J^(r`V4 literal 0 HcmV?d00001