PK":P݇cpyamf/__init__.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Python C-extensions for L{PyAMF}. @since: 0.4 """ PKĩ:U3  cpyamf/util.soELF>?@e@8@&#|B|B PP!P!P)/ 0P0P!0P!Ptd 8 8 8QtdCTSC#>7N0*<?,QMFB+= $LJ;5 AD8PH%G.416)-& R' !9(:/E3K2"OI@M  MOR|CEvsqXMC~e ;~,[U + hw_])!hm"/IYweBNz??8<M(oi~!kPy! q) rPy! ; +/ `!x__gmon_start___init_fini__cxa_finalize_Jv_RegisterClasses_Py_NoneStructPyTraceBack_TypePyExc_TypeErrorPyErr_SetStringPyClass_TypePyInstance_Type_PyThreadState_Current_Py_TrueStruct_Py_ZeroStructPyObject_IsTruePyString_FromStringPyModule_GetDictPyString_FromStringAndSizePyCode_NewPyFrame_NewPyTraceBack_HerePyString_FromFormatPyDict_NextPyString_Type_PyString_EqPyDict_SetItemPyString_AsStringPyErr_FormatPyType_IsSubtypePyInt_TypePyInt_AsLongPyExc_OverflowErrorPyMem_MallocmemcpyPyMem_FreePyObject_GetAttrPyExc_NameErrorPyErr_SetObjectPyObject_CallPyTuple_NewPyInt_FromLongPyErr_OccurredPyDict_SizePyDict_GetItemPyErr_WriteUnraisableinitutilPyLong_FromStringPyString_InternFromStringPyUnicodeUCS2_DecodeUTF8Py_InitModule4PyImport_AddModulePyObject_SetAttrString__pyx_type_6cpyamf_4util_BufferedByteStreamPyType_ReadyPyCObject_FromVoidPtrPyDict_SetItemStringPyObject_GetAttrStringPyList_NewPyObject_SetAttrPyCObject_Import_PyFloat_Unpack8PyDict_NewPyObject_CallFunctionObjArgsPyInt_AsUnsignedLongMaskPyFloat_FromDoublePyString_AsStringAndSizePyLong_FromUnsignedLongPyFloat_TypePyFloat_AsDouble_PyFloat_Pack4_PyFloat_Unpack4PyObject_IsInstancePyObject_HasAttrPyObject_RichComparePyUnicode_TypePyUnicodeUCS2_AsUTF8StringPyString_AsEncodedObjectPyExc_NotImplementedError_PyFloat_Pack8libpthread.so.0libc.so.6_edata__bss_start_endGLIBC_2.2.5aui (P!{6`T!`T!8`!h5H`!Ax`!`r!`!s!`!s!`!}!`!B`!0Ba! t!a!y!@a!Pa!Ja!z!a!z!a!z!a!z!a!z!a!z!b!z!b!6 b!}!(b!T!@b!Pz!Hb!T!`b!Xz!hb!U!b!`z!b! U!b!}!b!U!b!hz!b!U!b!pz!b!!U!c!xz!c!*U! c!}!(c!/U!@c!}!Hc!:U!`c!~!hc!DU!c!~!c!PU!c!~!c![U!c!~!c!fU!c! ~!c!pU!d!(~!d!U! d!z!(d!U!@d!0~!Hd!U!`d!8~!hd!U!d!@~!d!U!d!H~!d!U!d!P~!d!U!d!X~!d!U!e!`~!e!U! e!h~!(e!V!@e!p~!He!V!`e!x~!he!0V!e!~!e!BV!e!~!e!NV!e!~!e![V!e!~!e!fV!f!~!f!rV! f!z!(f!zV!@f!~!Hf!V!`f!~!hf!V!f!z!f!V!f!z!f!V!f!z!f!V!f!z!f!V!g!z!g!V! g!~!(g!V!@g!z!Hg!V!`g!~!hg!V!g!z!g!V!g!z!g!V!g!z!g!V!g!~!g!V!h!~!h!V! h!~!(h!V!@h!~!Hh!V!`h!~!hh!V!h!z!h!V!h!~!h!V!h!~!h!V!h!z!h!V!i!!i!V! i!z!(i!W!@i!z!Hi!W!`i!z!hi!W!i!{!i!#W!i!{!i!(W!i!{!i!-W!i!{!i!2W!j! {!j!T!?T!@T!CT!D T!E(T!G0T!I8T!J@T!KHT!LHZH5z!%|!@%z!h%r!h%j!h%b!h%Z!h%R!h%J!h%B!hp%:!h`%2!h P%*!h @%"!h 0%!h %!h % !h%!h%!h%!h%!h%!h%!h%!h%!h%!hp%!h`%!hP%!h@%!h0%!h %!h%!h%!h%z!h %r!h!%j!h"%b!h#%Z!h$%R!h%%J!h&%B!h'p%:!h(`%2!h)P%*!h*@%"!h+0%!h, %!h-% !h.%!h/%!h0%!h1%!h2%!h3%!h4%!h5%!h6%!h7p%!h8`%!h9PHH=!HtHÐU=9!HATSubH=8!t H=!H+!L%!Hm9!L)HHXH9s DHBHM9!AHB9!H9r.9![A\fUH=!Ht"H!HtH=!IAÐG<@uT1H~!H 1AHHH H9uH HH!HH Hf.1H~H 1HHH H9uHD1=8!>gffffff.G<@thu(H~cH1DBHHH H9uHH~;H1DHHH H9uHf1=O8!>f1fff.SHW HHtu H HGP(HCH[L8Aff.H HHt HIA1DHHW H!HG Htu HBHP(1HfH\$Hl$HLd$Ll$H(HIHtHtHEH;-{!Hf!H9EH%!H5H8nHtMtA$A$Ht EEtxH\$Hl$Ld$Ll$ H(EE1HIT$H;p!zH;!tqHz!H5cH8PfDHEHLX(H\$Hl$Ld$Ll$ H(AfID$LP(>HCHߐP(Dt]H; !tlH !H5LE1H88H5 !H*fDHEH1P( HCHP(IT$fDIT$LH !HHxHL`PLhXHPHHXPHhXHt tcMtA$A$t7M^AEAEKIELLID$LP(DfDHG@P(DfDH;= !tH;= !tH;= !tkfD1ffff.H\$Lt$HHl$Ld$Ll$L|$HxH=d4!?HIk 3!HIMH= 4!UHI}H=111HIt}L 3!HD$81ɋ3!111MLl$(Lt$ LL$1ۉD$0LL$LL$L $*HHt0HH !1LH8HHt3!H߉C|AAMtAEAEMtA$A$HtEEHt>u3HCHHl$PH\$HLd$XLl$`Lt$hLX(L|$pHxAH\$HHl$PLd$XLl$`Lt$hL|$pHxDH!H=J1HIMkAE111ۃAIFLP(DHEHP(D0IELP(DID$LP(Dff.SHHHtH[H2!H=^H1!o1!H1!CȐAWMcAVIAUIATIUJ,SHHHD$8L|$0HT$ LL$HD$8HD$HD$DHD$0D$DHD$DHT$Ht$LLK_HMHHt$8H91Hu@H90DHHHuH~H{ !H9wHtBHHH Ht)H9G;FutHHt$8H HuI9tRI$H8H9LHH9t3HH8H9G;FuHHt$8H9uH|$ t;HT$0H|$ JHHD$0L)HIHt$8 HIHH!HT$H5H819HH[]A\A]A^A_H;HD$0L)HIVHH8H!HO$HT$H5AH81HH[]A\A]A^A_HtHMHt$8oHr!HT$H5H81VHt$8SH1H(HHt7H1/!HCHV!HC H.!@C!HC(C0HH[É$H!L FH HH5E1H81t 1fDHCH1P(@fffff.H!H9Gt fDHGHHe!H9GtHHcH9uHfDHOHk!H5TH8tffff.AUIATLcLUSHfH~"KL%1HDH9LLH?HH[]A\A]ffff.H\$Hl$HHHHtHHl$H\$HH!HH8fff.AWIAVIAUATUSHL%e!H5-!A$HHH5,!1HHHL-!L9m'HHD$H|$$EEH5-!LHHFH5o,!1HHHVEEL9kHHD$H|$RlHHpALp1H=+!HHIxA$A$yH52,!L:HHmHHH+!1HHH+!HCHIEEiBA$A$H5+!LHI2bHHpH7+!1HLH%+!HCH"+!H+!HC HHWA$A$EEH5+!LHH3H5*!LHHBH5C*!1HYHIRtHHWL`1HHHIdEE{A$A$PH51*!L9HI@H|$HHTHHhHX1HLHHuA$A$QEE(H5)!LHH~H|$ HH;FHI|Hh1HHHHA$A$EEH5)!L HHeHIH(!1LHH(!ID$VHHJEEA$A$vAELAEAEu IELP(HH[]A\A]A^A_@HEHP( HCHߐP(L- L9mHEHD$fDHEHP(L9k.HCHD$-fDHCHP(fD-ID$LP(DrHCHߐP(DGID$LP(DHCHߐP(DHEHP(DHEHP(D3HCHߐP(D ID$LP(DHCHߐP(DMID$LP(DHCHߐP(DpHEHP(DIHCHߐP(DHEHP(DID$LP(DHEHP(D9ID$LP(DHCHߐP(DID$LP(HCHP(pHEHP(D2H\%!MH<%!$!f H3%!H=1H%!ME1H$!$!i H$!fu HCHP(Ht EEt)MtA$A$uID$LP(uDHEHP(DfDHH{$!ME1HX$!#!n HO$!of.HA$!MH!$!#!| H$!H$!ME1H#!#! H#!nHH#!M1E1H#!?#! H#!H#!MH#!#! Hx#!CHt#!M1E1HO#!"! HF#!QHB#!H%#!"! H#!H#!E1H"!"! H"!H"!H"!\"! H"!H"!H"!2"! H"!H"!Hz"!"! Hq"!Hm"!HP"!!! HG"!RHC"!H&"!!! H"!H"!E1H!!!! H!!H!!H!!]!! H!!H!!H!!3!! H!!H!!H{!! !! Hr!!}Hn!!HQ!! !!HH!!HD!!H'!! !!H!!PH!!H ! ! !H !H !H !a !!H !H !E1H !4 !$!H !H !H| ! !!!Hs !>Ho !HR !!'!HI !THE !H( !!.!H !*H !H!!?!H!H!H!b!H!H!H!H!8!B!H!fff.H\$Hl$HLl$Ld$ILt$L|$HXHHVAH5!LHD$HHH5!1H&HHH H9EH2II=EEDIELP0I9HH!Ht$I} DEHL9+H=< !11H|!H_!!hHV!HL AH $LIHAH5HHIH AH812H!H!d!H!H=N11HH\$(Hl$0Ld$8Ll$@Lt$HL|$PHXfH~H H9G3IIIDHHHu !1HHf !HEH=!.HHEE)11HuH!H!X!H!@AH!Ht$I} HH9t:H=K!11 H!Hn!!He!H5!LHHL=HHwHI7HX1HHHHEEA$A$H|$DHHH!H!$!H!HEHP(HCHߐP(D`Lu@lLg@HCHߐP(DXID$LP(D1HEHP(DHCHߐP(DHEHP(DHHD$SH5}!HHZSHL$L FH5>!AH1cH|$HHIH H5!LHI)H5!LHHH5!1HHHWH H9EHHHEEHHH'HH+Hh1HLfHHA$A$t[HjHCHP(HXHCHP(fD3HEHP(DRID$LP(DfDH]@kHCHD$H#HH!Hn!!9He!DHEEyHEHP(jH8!H!!1H!@H!H!!4H!HwhHCHP(YCHH!H!!H!H!Hd!!H[!HW!H:!!H1!H-!H!!H!A$A$ID$LP(H!H!V!H!H!H!,!H!H!Ht!!Hk!Hg!HJ!!HA!5H=!H !!H! H!1H!!H!H!H!X!H!GH H!1H!!H!{fH!Hd!!H[!OHW!1H8!!H/!#HD$H!!H!!H!)H!H!h!H!fff.H\$Hl$L|$Ld$Ll$Lt$H8H HL`HLhPLpXH@HH@PH@XKIHHxHHXPHhXL`HLhPLpXHtHtHtEEu HEHP(MLAAt+H\$Hl$Ld$Ll$ Lt$(L|$0H8IGLH\$Hl$Ld$Ll$ Lt$(LX(L|$0H8AHCHP(\HG@P(D2H= H\$Hl$Ld$Ll$ Lt$(L|$0H8 f.AUIATUHSHHHt HH9HwIAE<@'uGHLI,~HHH9uH!I} LPHL[]A\A]@HI,~XHHI9ufDHHHK!1HރH<!HCH=!HEHP(@HCHߐP(DnH!Hg!!N H^!xHCHP(iHA!H$!!H H!?fDAUIATIUSHHH HH9!HHH!1HރH!HCH=D!HHX411HEEHh!HK!!l HB!HH=[]A\A]l@HH9ALHAE<@uLMHJT%~HHH9uH!I} DHPHH[]A\A]+MJD%~fDXHHH9ufD1=!>wHEHP(fHCHߐP(DH<!H!!e H!HCHP(H!H!j!_ H!fffff.Ll$H\$IHl$Ld$Lt$L|$H80u-IE(H\$Hl$Ld$Ll$ Lt$(L|$0H8fDH5!H HHoH55!1HKHHy(L=) L9}HWIIEEH5R!I} YHHHH+H !1HHHCH !HC HIEEA$A$oH5 !I} HI}H5 !1H2HH A$A$kL9{HAHHUIm(AE0I} H51 !!H!fH!H!!H{!Hw!HZ!!HQ!fff.AW1AVAUATUSH{HH! H4 1H!HH4!A HH"! H=11HH ! HHH!i HH!H- H Hu1fDH{HEHH8tAH H+H{t{tv{fuHsH{HEHH8uH!H!!%H!H!e!%H!fHsH{1҃HEJDHI H5B!H=1AHHT!H=V_HH=!H=(!H5?H)H2!H!!&H !H=VpH!tH!H[]A\A]A^A_@H=!HGP(H!H!2!%H!fH!H=j!HH?H!H=K!H!HHHt!H=%!H!HHHV!H=!H!HH2H8!H=!H!HbHlH!H=!Hl!H!H!L% >!Hw!HLH!HH!HH!H#H!HH!H' H!H H!MH=!1I$oHHMH5׿HHŋu HCHP(H=w!H5Lx$H=a!H5L%!L=\!/HI111HIt+H=!dHIA$A$kAEAEIHtEEu HEHP(HH5!H=!HH H5ھH=!H\$H!Ho H!Hj H!D$|$H(!H=i!1D<R!F!D$<@H5-!H !f.H!H!zR!&H!fDH!H!"!%H!zH!Hj!z!&Ha!PH]!H@!z!&H7!&H HH8H!!H!H!!%H!H!i!&H!H& HH8{H!HI!H!"!%H!H HH87Hx!H!HP! %HG!RH HH8H1!H!H ! %H! HT HH8H H!H hP %H H HH8bH HH!H{  %Hr }H HH8H\ H!H4 f %H+ 6HH52 H(H H 5j *&H HCHP(H H ' %H H Ho  %Hf uHb HE  %H< +H8 H  %H !H H  %H H H U %H IELP(ID$LfP(D~HCH@P(DHHD:HE1MLLL1HHB H% 5 (&H UHHSH_H} H;= H;= t H;= t茿DHHDH 1HރH HCH= HH11HEEH= H < H bDH HD$Ht$H} ډHH9tPH= 11XH H DJ 7H H=ܯ1H[]fDH|$H( 蕾HuH Hd F EH[ fHEHP(HCHߐP(DH, H ; H N茾HH H=H :^ H 21H H <* H H Hr < Hi HCHP(ff.ATIUSH H;=^ t2H;= H;=X ͼ@A|$0@jH5K L[HHH5 1HξHHtOH H9EtZHHHEEtID$(H)[]A\HEHP(@HCHߐP(HV H9EuH]f.vHHH; 1HH, HEH= HHEE11HKtXH H E2 H H=[]1A\ID$LfDHCHߐP(DfDHEHP(DdH< H D H vH H J # H LH H JY & H HCHP( @+H H Hv J + Hm EEHEHP(HN H1 E H( H$ H E H fff.USHHH H;= t0H;= H;= {fH5 HHHH5x 1H莻HHEE1Hj H9C<H蘺HH6u HCHP(1HH[]VHHH 1HރH HCH=q HHtu11H1EEtDH H 4 ! H H=H1[]f.HEHP(fDfDHCHߐP(DvHEHP(H. H9CHkH H 3}  H bH H 6S . H 8H H 6) 1 H EEHEHP(Hs HV 4  HM HI H, 4  H# HCHP(D苷HH H 6d 6 H ff.USHHH H;= H;= t#H;= tOfDD軸HHDHk 1HރH\ HCH= DHH11H荻EEH H bn H _DH HD$Ht$H{ tSH=T 11H H i Hv H='ڽ1HH[]fDn C<@uH|$LD$H53 L H5 H= `HHH5- HUHHHOHCHP(H=DC<@uvLD$L 跴HHH\ H? { }H6 HEHP(%HCHߐP(DLD$1fDH5 LH5 LuH5 H= +HHH5 H HHH Hx u FHo HCHP(H5A H=" HHJH5 H袳HHMH H s %H H H aZ tH HfD1= >%1= >]H Hs b Hj Hf HI b H@ H< H q H H H q H qH H sY "H GH H u/ CH UHSHHH H;= H;=L t H;= t@D苳HHDH 1HރH HCH= HH11H]EEH H > 2H H= H1[]fHT$Ht$H農tH H[]fH1 T$Ht$H{ PC0HEHP(fD_HCHߐP(D*H H  H BH H [ +H HCHP(H H  %H fff.UHSHH H H9H;=, t H;= tDkHHDH# 1HރH HCH= HH 11H=EEthH H :"  H H=1HH[]HEHP0HtH: HH[]DHEHP(@HCHߐP(DZH$ H 9 c H nH H :k r H DH H :A x H HCHP(fff.SHH H;= t/H;=H tH;= t|$u1[HCHߐ[DH0 H=YH  XH n[Ll$L|$IH\$Hl$Ld$Lt$HHL- AEH H;= t0H;= L9|W@fbHS Ht$I HD$H1 P HIAEAEH Ht$LPAIW Mw H5l LtHHJ.HH!H 1HHH HCHIEEA$A$aAG0AEMLA$A$u ID$LP(HHl$ H\$Ld$(Ll$0Lt$8L|$@HHÐfHHHs 1HރHd HCH= HH11H=EEtpH MH 3 #H H=1DI HGP(DTIELP(DHEHP(D{HCHߐP(DJID$LP(DHCHߐP(D_HEHP(D8H MH 2: #H H MH > $Hv Hr MHR : #HI HE MH% 3 #H H MH 3 #H u HCHP(HIEE8HEHP()H MH > $H H MHh > $H_ kf.Ld$Ll$IH\$Hl$H(H H;=Z It3H;= H;=Q ƧDH5 I} bHHHHA$1L`HH躩HIEEEA$A$u ID$LP(H AE0H\$Hl$Ld$Ll$ H(@~HHH 1HރHt HCH= HHtm11HYEEt Z#H H=( 1?@HEHP(fDfDHCHߐP(DfDHCHߐP(DHEHP(DH4 H % >#H bH H ({ g#H 8H H (Q j#H f.HEEHEHP(H Hk & M#Hb H^ HA & S#H8 yHCHP(jH H ( p#H USHHH H;= H;= t#H;= tnfDDHHDH 1HރH HCH= tHH11H轩EEH- H  r"H H=kH1[H]H{ H5 XHHH5 1H˥HHHtAHH[]HEHP(fDOHCHߐP(DHCHߐP(HH[H]HI H,  V"H# H H  "H H H f "H HCHP(H H # e"H H Hk  k"Hb ATIUSH H;=~ t.H;=% H;=x q@t~H5 I|$ 荢HHxH5 1HHH EEu HEHP(H AD$0[]A\fHHnH 1HރH HCH= tHHftm11HEEt uďHzH, H=H - PH j1=H H 5b H H H 58 H HCHP(H Hg 2 oH^ HZ H= 2 uH4 fUHSHH0 H9FH^HHxH} H;=& t2H;=͢ 'H;= 蕍@HDHHWHX 1HރHI HCH= 聏HHO^11HʒEE)H: H  |H H=x1H[]H9HEHHPH E0H[]@HHHc 1HރHT HCH=! 蔎HH11HݑEEtpHQ H4  RH+ fDH^ HEHP(fDHCHߐP(DHEHP(D{HCHߐP(DJH H % 6H uHzH| H=}HX  &HO 躓1=HA H$  oH H H  uH HCHP(H H E EH H H  KH fUHSHH H9FH讋HHxH} H;=v t2H;= 'H;=p @Hx>H.HEHHP H E0H[]HH"Hc 1HރHT HCH=1 蜋HH)11HEEHU H8  H/ H=h}蓑H1[]f.VHHH 1HރH HCH=q HH11H-EEtpH H  H{ GfDH^ HEHP(fDHCHߐP(DHEHP(D{HCHߐP(DJH H u H dHzH H={H 6 H 1H Ht  Hk 7Hg HJ  HA HCHP(H$ H  H H H k H fUSHHHЛ H9FHHD$HvH{ H;=ě t0H;=k %H;= 3fHD$H蘈HH\H 1HރH HCH= &HHTc11HoEE.H H P dH H="z1H[]@HDHg Ht$H{ PH C0H[]f覇HHH 1HރH HCH= 4HH11H}EEtpH H b :H fDHF HEHP(fDHCHߐP(DHEHP(D{HCHߐP(DJHT H7  H. p贄H|H H=}xH  H Z18H H R WH H H ( ]H HCHP(Ht HW  -HN HJ H-  3H$ fUSHHH H9FHNHD$HfH{ H;= t0H;= H;= 胂fHD$Hfx6H=.Ho Ht$H{ PH C0H[]Ð趄HHH 1HރH HCH= DHH!11H荇EEH H n H׾ H=pv;H1[]fHHH3 1HރH$ HCH=! 蔃HH11H݆EEtpHQ H4 ½ H+ OfDHFHEHP(fDHCHߐP(DHEHP(D{HCHߐP(DJH H % H HH| H= uHX  HO 躈1HA H$  H ?H H  H  HCHP(HԼ H E H H H  H fUSHHH H;= H;=? t#H;= tfDD{HHDH 1HރH HCH= HHg11HMEEH H . H _DHa HD$Ht$H{ tKH= 11ۃH\ H? ͺ H6 H=r蚆1H[]ÐHCHt$HPHHuH H q Hں HEHP(HCHߐP(DH H  H KH He  H\ HCHP(H? H"  H @USHHH H;=, H;=ϑ t#H;=& t|fDD HHDH 1HރH HCH=! ~HHg11H݁EEHM H0  ;H' _DH HD$Ht$H{ tKH= 11kH Hϸ ] ]HƸ H=p*1H[]ÐHCHt$HPH|HuH Hs  kHj HEHP(HCHߐP(DH< H  H KH H  4H HCHP(HϷ H @ .H @USHHH H;= H;=_ t#H;= t/zfDD|HHDH 1HރH HCH= $|HHg11HmEEHݶ H N H _DH HD$Ht$H{ tKH=4 11~H| H_  HV H=n躁1H[]ÐHCHt$HPH$zHuH H  H HEHP(HCHߐP(DH̵ H = H KH H  H| HCHP(H_ HB д H9 @USHHH H;=L H;= t#H;=F twfDD+zHHDH# 1HރH HCH=A yHHg11H|EEHm HP ޳ HG _DH HD$Ht$H{ tKH=ĵ 11|H H } H H=?lJ1H[]ÐHCHt$HPHwHuH H  H HEHP(HCHߐP(DH\ H? Ͳ H6 KH2 H  H HCHP(H HҲ ` Hɲ @USHHH H;=܊ H;= t#H;=֊ tOufDDwHHDH 1HރH HCH=ѳ DwHHg11HzEEH H n #Hױ _DH HD$Ht$H{ tKH=T 11zH H  NHv H=i|1H[]ÐHCHt$HPDuHuH@ H#  eH HEHP(HCHߐP(DH Hϰ ] Hư KH° H 3 H HCHP(H Hb  HY @USHHH H;=l H;= t#H;=f trfDDKuHHDH3 1HރH$ HCH=a tHHW 11HxEEH Hp { Hg _DH1 HD$Ht$H{ tKH= 11wH, H  H H=gjz1H[]ÐHD$H8rHuHޮ H O H fDHEHP(HCHߐP(DH Ho z Hf [Hb HE {ӭ H< 'HCHP(H H { H @H\$Ld$HHl$Ll$H8L% A$H H;= t2H;= L9apfDfH[ HD$Ht$H{ )H= 11LuHO H2 s =H) H=f1xu HCHP(HH\$Hl$ Ld$(Ll$0H8f.&rHHH 1HރH HCH=A qHHu11HtEEHm LHM n۫ HD HD$8+pHIkA$A$H I9ELCpHH_HLoHHHЫ LH w> \H yfHEHP(%HCHߐP(DH| LH\ m HS %fDID$LP(,I]@3H$ H n H u HCHP(LH LHª nP H H LH u# JH ^nHHz LHZ w ZHQ #fff.ATIUSH H;=^ t2H;= H;=X l@H5[ LkmHH#H5ȩ 1HnHH03HmHËEEA|$0#I|$(H)~mH []A\ÿnHH1H 1HރHt HCH=Ѫ DnHH)tm11HqEEt1@H\$D$HkHl H} HPH~ E0H([]1= >fkHH9Hs 1HރHd HCH= 4kHH111H}nEEtPH Hԥ b H˥ H=_/qH(1[]fDFD$HEHP(fDfDHCHߐP(DjHt HW  HN ~HJ H=^H&  H p1H H  H H Hˤ Y H¤ HCHP(@USHHH H;=| H;=_| t#H;=| t/gfDDiHHDH[ 1HރHL HCH= $iHHI11HmlEEHݣ H N NH VDH Ht$H{ tTH== 11lH Hh  pH_ H=\n1H[]f.C<@th11@H|$xfffZZUfHuH H r Hۢ wfD1=ߢ >fHEHP(HCHߐP(DH H  2Hv Hr HU  AHL HH H+  GH" HCHP(@ATIUHSHH H%VI|$ H;=y tH;=y t!H;=y tmd@JDfHHDH 1HރH HCH= dfHH)11HiEEH H _ |H fH\L H]AH \$LIH\AH5SH]HIHx AH81cH Hv ] RHm H=Zk1H []A\fDH! HD$Ht$I|$ 9~~H=ǡ 11hH H f H H~Hw H9GdHHc‰H9H=Q 11hH H| h Hs fDH|$HCHP(/H5ɚ I|$ ]HHHc;^HIIc'^HIa_HH'L`1Lh HH_HI0EEtLHCHP(LH}E1Hq H9_HWHEHP(fDID$LP(DWHEHP(DlHW@@IELP(DHEHP(DaH 11H -q Hژ H\HD$HD$AŋUM;H5d H\HHD$,AA+H5A H\H8DEHL$L TH51 1HgfH|$iH|$E1H`iAO[HAH HΗ ,\ w Hŗ Hp H5JH8 ]5[HH H{ ,  Hr 9DHE HD$HEHD$E @H1 1H 0 H FH 11H .r Hۖ Ho H5JH8 \KZHAH H , ~ H NfH E1Ha . HX A$1ۃA$ID$L1P(yH2 1H 0 H GH H 0w H Hߕ H• 0P H \H H 0& H YHbH} H` , u HW UHK H. , s H% HD$fDH\$Hl$HLl$Ld$HHHIHVL% $HfPL ,QAH P$LIHPAH5GHPHIHl AH81WHw HZ  "HQ H=JN_1HH\$(Hl$0Ld$8Ll$@HHH?XHN HD$SJSH5 H.XHUSHL$L =PH5{ AH1a4Ld$DI} H;=k H;=xk t$H;=k tHVDXHHDH 1HރH HCH=ɔ HBHP(fDIFL1P(@HEHP(fDHCHߐP(D~Ml$tH5} H|$(G?G AHH H~ 1HH} HEH=} 9AHH? EE11HDH{ Ll$H{ ^{ H{ H=6&GH5| Lq> *H5| LQ>  H5{ L>HH H5>{ 1HT@HI iHT$=H5~{ L>HI @@HH H{ 1HLH{ HC?HHK A$A$(EEH5 { H|$ =HH H5z L=HHC H54z 1HJ?HI =e?HHL`1HH?HIEE8A$A$H5"z L*=HI >HH A1LpHL>HH A$A$EMEHEHMP(ID$LP(DHEHP(DID$LP(DHx Ll$Hx @x EHD$(Hx Hx Ll$Hzx x Hqx Hmx Ll$HKx w HBx vDIFLP(fHCHߐP(DHCHߐP(DHEHP(DHBHאP(DHCHߐP(DHEH@P(DHCH@P(DID$LP(DH{;HO HD$HD$0SH5w He;HSHL$0L 3H5_ AH1)EL|$0HT$HCHP(ID$LP(DHCH@P(DHEH@P(DHCH@P(D.ID$LP(DHCHD$0IfH1v Hv u H v ?Hv E1Hu uu Hu Mu HCMHP(MtA$A$t/HEEHEHP(fDID$LP(DHou HRu t &HIu fHEu MLl$1Hu t Hu MHu Ll$Ht }t Ht l8HHt Ll$1Ht >t Ht fHt E1Ll$1Hzt t Hqt Hmt Ll$HKt s HBt vH>t Ll$Ht s Ht KHt Ll$Hs {s Hs 0Hs E1Ll$Hs Is Hs Hs Ll$Hs s Hs Hs Ll$H]s r THD$(HKs HGs Ll$H%s r EHs PHs Ll$1Hr r ,Hr Hr Ll$Hr Sr )Hr Hr Ll$Hr $r 2Hr Hr E1Ll$Hdr q \H[r xHWr Ll$H5r q cH,r dH(r Ll$Hr q vHq 1Hq Ll$Hq eq QHq Hq Ll$Hq 6q WHq Hq Ll$Hyq q THpq Hlq MMHIq p H@q ]H11H/ Hf LHf Ujf Hf *fDHVA H5JA Hb+HHA$HA$ID$LHP(DID$LP(DHT$ HH+Hf T$ H4$I} PAE0HEHP(fD?HCHߐP(D HCHߐP(DHEHP(DHe LHe I2e xHe He Hze We Hqe Hme HPe Jd HGe u HCHP(LH+e LH e Jd He YHd LHd Uld Hd EE HEHP(Hd LHd U'd Hd Hd LHld Sc Hcd H_d LH?d Qc H6d AVHIAUATIUSH~H5~< H9t t(A$LH5e C(HH\L-< L9t-H;;  H;; Hd&A$A$/(HIJH:e 1LH+e ID$H=d :(HHA$A$C11H+Hb Hb bb Hb H=/.[]A\A]A^Ð1HCHP( H5^d L&HHL9t-H;<: &H;: H%:H5c Lk&HHLL9t-H;9 H;!: H$q/H5c L%HHL9t-H;`9 zH;9 mH%$ HCHP(@LD[#AF1[]A\A]A^fV&HHHb 1HރHb HCH=ib %HI)11L-)A$A$H` H~`  ` qHu` ID$LP(HCHߐP(D$HCHߐP(Dz1D1ND1mf.HCHP(fDID$LP(DH_ H_ %_ H_ u HCHP(MA$A$ID$LP(HN_ H1_ ^ H(_ H'_ H _ ^ H_ nH^ H^ n^ H^ DH^ H^ D^ jH^ ID$LP(HCHߐP(DH|^ H_^ ] HV^ H6 H5H8#wH2^ H^ ] H ^ H^ H] y] H] H] H] O] H] :H] H] %] H] H] Hm] \ Hd] H`] HC] \ dH:] jDLd$Ll$ILt$H\$IHl$H(H L-25 L9H;=4 tH;=)5 tnD"HHDH{_ 1HރHl_ HCH=)^ !HH11H$EEHU\ H8\ [ H/\ H=@'1H$Hl$Ld$Ll$Lt$ H(@H51\ 1LO HHvL9t$H;3 thH; 4 t_HttOtYH=?] 11$H[ Hz[ [ Hq[ =@1uHCHP(uH5[ LHH%L9t,H;2 H;O3 H:L8HHID$HLP H2 AD$0HEHP(=HCHߐP(D 1fDtHlZ HOZ Y HFZ HBZ H%Z Y HZ HCHP(HY HY pY HY HCHP(HY HY 3Y HY hHY H{Y  Y HrY QHnY HQY X HHY HjH6Y HY X HY H Y HX zX HX fffff.Ll$Lt$IH\$Hl$ILd$L|$H8H H;=0 H;=p0 t$H;=0 t@lDHHDHc[ 1HރHT[ HCH=Y 4HH11H} EELHW HW ^W HW H=+#1H\$Hl$Ld$Ll$ Lt$(L|$0H8fDW IDžAF<@11ۅHd/ I9EL$H<$LHV I~ LPLzH3/ AF0-fDH-W H=V HJHHH5X H/HH6 HHAE1LhHHxHIEEL;%e. t,L;%. L;%Z. L!A$A$HV HIAF<@L'HEHP(fDHCHߐP(Dj1=U >AE$17fH5!V H=U 'HHH5zV HHI#-HHRAE1LhHLHHA$A$d=HQEEJH5SU H=4T &HHBH5U HHHI_HH,AE1LhHHHIEE(LA$A$ HS HIfHS HIfDHCHP(rfHCHߐP(DID$LP(DHEHP(DH S HR ~}R HR HR HR SR HR @MA$A$ID$LP(@HCHߐP(DHCHߐP(DHEHP(DID$LP(D<1=7R >ZHi* HH8HQ HQ pQ HQ @HCHP(HCHߐP(DHEHP(DID$LP(DH|Q H_Q P HVQ HRQ E1H2Q P H)Q u HCHP(HSEEBHEHP(3HP HP ]P HP HP E1HP 0P HP HP H{P  P HrP DHnP HQP O HHP rHCHP(cH+P E1H P O JHP HO HO oO 6HO HO HO EO 9HO aHO HO O CHO VHO HcO N =HZO HVO H9O N xH0O H,O HO N nHO HO HN sN kHN HN E1HN FN rHN HN HN N HN UHSHH$ HtHs$ HHHuH[ÐHHraise: arg 3 must be a traceback or Noneinstance exception may not have a separate valueraise: exception must be an old-style class or instancecpyamf.util.BufferedByteStream.endian.__get__%s() got multiple values for keyword argument '%s'%s() got an unexpected keyword argument '%s'%s() takes %s %d positional argument%s (%d given)value too large to convert to intcpyamf.util.BufferedByteStream.__add__cpyamf.util.BufferedByteStream.peekcpyamf.util.BufferedByteStream.pack_uintcpyamf.util.BufferedByteStream.pack_intcpyamf.util.BufferedByteStream.c_lengthcpyamf.util.BufferedByteStream.read_utf8_stringcpyamf.util.BufferedByteStream.c_remainingcpyamf.util.BufferedByteStream.c_at_eofcpyamf.util.BufferedByteStream.read_doublecpyamf.util.BufferedByteStream.writecpyamf.util.BufferedByteStream.at_eofcpyamf.util.BufferedByteStream.__len__cpyamf.util.BufferedByteStream.consumecpyamf.util.BufferedByteStream.writelinescpyamf.util.BufferedByteStream.readlinecpyamf.util.BufferedByteStream.flushcpyamf.util.BufferedByteStream.closecpyamf.util.BufferedByteStream.getvaluecpyamf.util.BufferedByteStream.tellcpyamf.util.BufferedByteStream.write_24bit_uintcpyamf.util.BufferedByteStream.read_ulongcpyamf.util.BufferedByteStream.write_24bit_intcpyamf.util.BufferedByteStream.write_shortcpyamf.util.BufferedByteStream.write_ushortcpyamf.util.BufferedByteStream.write_charcpyamf.util.BufferedByteStream.write_ucharcpyamf.util.BufferedByteStream.read_24bit_intcpyamf.util.BufferedByteStream.read_24bit_uintcpyamf.util.BufferedByteStream.read_longcpyamf.util.BufferedByteStream.read_shortcpyamf.util.BufferedByteStream.read_ushortcpyamf.util.BufferedByteStream.read_charcpyamf.util.BufferedByteStream.read_ucharcpyamf.util.BufferedByteStream.remainingcpyamf.util.BufferedByteStream.write_floatcpyamf.util.BufferedByteStream.read_floatcpyamf.util.BufferedByteStream.readcpyamf.util.BufferedByteStream.seekcpyamf.util.BufferedByteStream.readlinescpyamf.util.BufferedByteStream.truncatecpyamf.util.BufferedByteStream.__init__cpyamf.util.BufferedByteStream.write_longcpyamf.util.BufferedByteStream.write_utf8_stringcpyamf.util.BufferedByteStream.endian.__set__cpyamf.util.BufferedByteStream.write_ulongcpyamf.util.BufferedByteStream.write_doublecpyamf.util.BufferedByteStream%s (%s:%d)%s() keywords must be stringsexactly__new__peekat leastat most4294967295__builtin____builtins____pyx_vtable__BufferedByteStream__import__cStringIO_CAPIcStringIOcpyamf.utilreadseekreadlinestruncate__init____del__cpyamf/util.cutil.pyxtellat_eofremaininggetvalueread_ucharread_charread_ushortread_shortread_ulongread_longread_24bit_uintread_24bit_intwritewrite_ucharwrite_charwrite_ushortwrite_shortwrite_ulongwrite_longwrite_24bit_uintwrite_24bit_intread_utf8_stringwrite_utf8_stringread_doublewrite_doubleread_floatwrite_float__add__closeflushreadlinewritelinesconsumeendian;?t4 4 L d$ |d  T  Ddd|TT" $-4.T0|$39DG$JD$NdTStUdWW\_$bD$edgjmpsv$dzD~dādԇD$$DdD Ԭ4 T | d $ D zRx P4Lp5Ad|7DJQ0X 3$ eJ[ OA4  BEE E(D0E8DDXAI d|SD$HcBEG A(F0DN 4 BEE B(A0A8DP$ @ JMQ`4(b@$TX*BEA D(G0$|P,BBED A(G0$x.tJ[@44) BDB B(A0A8DP?AGD0$xBDBDA DE%AAG dH-AAG0MADG0OADD QA$RJ[PV]JQ0$YAAG D8\BDA d^BDA haAAG cAAG HfvAGD ilAAG0kADD $oADD DsADD dvAAG08zAAG0}lAAG0lAAG0XlAAG0lAAG0$lAAG0DH\AAG0dJQ@BDA ADD@xAAG0$BDD G@$ BBD D(GP4JQP$T8 JMQp4| $BBB B(A0D8GJY0OJML@,BHB D(A0$RJML0$DP J^@{6Qa ; +Xo   hR!ph680$ ooopoo0P!<<&<6<F<V<f<v<<<<<<<<<==&=6=F=V=f=v=========>>&>6>F>V>f>v>>>>>>>>>??&?6?F?V?f?v???`T!utf8strict Python C-extensions for L{PyAMF}. @since: 0.4 __cinit____init__tellseekat_eofremaininggetvaluereadread_ucharread_charread_ushortread_shortread_ulongread_longread_24bit_uintread_24bit_intwritewrite_ucharwrite_charwrite_ushortwrite_shortwrite_ulongwrite_longwrite_24bit_uintwrite_24bit_intread_utf8_stringwrite_utf8_stringread_doublewrite_doubleread_floatwrite_float__len__peektruncate__add__closeflushreadlinereadlineswritelinesconsumebufvalueposmodenobjvallscsizeselfothersizehintiterablefpconstbasestringgetvaluereadseektellTypeErrorValueErrorOverflowErrorIOErrorEOFErrorNaNNegInfPosInfisNaNisNegInfisPosInfRuntimeErrorUnable to coerce buf->StringIOString value expected!@<>Not a valid endian typeinteger out of rangeinteger out of rangebuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closeduchar not in rangebuffer is closedchar not in rangebuffer is closedushort not in rangebuffer is closedshort not in rangebuffer is closedbuffer is closedbuffer is closedn is out of rangebuffer is closedn is out of rangebuffer is closedbuffer is closedvalue must be Unicode or strbuffer is closedbuffer is closedbuffer is closedbuffer is closedCannot peek backwardsbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closedbuffer is closed Reads a 24 bit unsigned integer from the stream. @since: 0.4 Reads a 24 bit integer from the stream. @since: 0.4 Writes a 24 bit unsigned integer to the stream. Writes a 24 bit integer to the stream. Chops the tail off the stream starting at 0 and ending at C{tell()}. The stream pointer is set to 0 at the end of this function. @since: 0.4 h58A`r!s!s!}!EB0B t!y!Jz!z!z!z!z!z!z!6}!T! Pz!T! Xz!U!`z! U!}!U!hz!U! pz!!U! xz!*U!}!/U! }!:U! ~!DU! ~!PU! ~![U! ~!fU!  ~!pU!(~!U!z!U!0~!U! 8~!U! @~!U! H~!U! P~!U! X~!U! `~!U!h~!V!p~!V!x~!0V!~!BV! ~!NV! ~![V! ~!fV! ~!rV!z!zV!~!V! ~!V!z!V!z!V!z!V! z!V! z!V! ~!V!z!V!~!V!z!V!z!V!z!V!~!V!~!V!~!V!~!V!~!V!z!V!~!V!~!V!z!V! !V! z!W!z!W! z!W! {!#W!{!(W!{!-W!{!2W!  {! # E# O2i#  # *'# # ! # $i# w+( # a*) # ,# '-# ).E# >,/W# 0# F+1 # 42 # 3i# w4 # G5 # _6 #  7w # 8# 9# #:# 0;# 4(<# !=# > #eh<~sy][  b b'''8>Sb^d~bbSbbPbbbb$+b/b/E\KQbf,,qwbb5bbb 0B H# 2# #)# d# # 5#( !#0 h#8 "h#@ n.h#H #P $h#X #` F,#h : #p #x # 5# 4h# h# h# oh# $h# v# R5# d# I# h-# B(# # h0# D# (# 9/# # W)# +# 2#  P *# Ǐ# v-# 4-# K0S# P~#( ̩#0 r ͗#8 Ϗ#@ -#H !M  6'# uՏ#  #}1  l , # 5# z@# %f#2+ (   p   7  b  b"   d  $ b> ] s"j p i     bs3sAT    W3WbB   l / , k"# #}# V$b# J%#K - %(# )b# D0*b# Y+b#doc,#(.E % #get a#set #doc #  #  Ge  6 b#  W#  i#% ^  6 b#  W# / 5#( #, 6 $b#  $W#  $b# $ %i# ^ &b# x '#$ m 6 b#  W#  b# m# } {@  6 b#  W# Y4# .# # *#( #0 0#8i+([ 6b# W# k[# # # ] lrv& bK_isHC C# # 1# # 1# #( t#0 7#8 b#@_ts  3# 4;# %6# ,7b# 78b# 39b# ;#( S%<#0 0=#8 >#@ #@#H A#P /B#X (D#` E#h F#p KH#x  Jb# p Kb# f M# O4Ni#I5!#)bb% ; 6b# W# b# &# # 1#( ,#0 )#8 j'#@ '#H #P (#X #` #h RL#p b#x ."b#| .#b# 0/%b# &# 'b# @(b# %)b# *b# +m#RIA?!0b @  # $&# );# ,s# P,/Q# +4s#( ;9#0 9#8bbbb;b!QbA p'#s#ni# # # V#0W 810 62b# 2W# '3# 4# 5# 68#( 7?#083 <# 0=# 5># ?# r3@;# KAQ#( B#00iii8iii ;8i%bQAp @ 6 b#  W# < b# b# Ib# Ab# # ,#( (#0 3#8 _#@ q5#H #P #X b#` E4#h3.W  ~  b#  b# 2 b#K@ ~ ,*bWb&#b 8,W&# $&_%&&&%&&b+&X&XM)&X%&XC&&U&b-+&g&c.&bkey&pos&XE&6+&53/(bJt/(J w&'bK'W'80'&'b!bad'B'z{M5|bW}&#~b wb|x5&ybkzRW{b&#|b"#"$$%%\''' ''tb''T'L&0i@1Aw','kI(iQ)2i|3i)+RWi)&#b0#b*N@!f*s@+P#,$$-@-@&58@AAw(,U'kZ'i)28)+R"W8)&#bE0#b*A*|A+#,$$-TA-HA.&G$AB/oG$pH$&M$bB+BwY/oM$/vM$2/aM$eN$bpO$0dV$b0BgB/oV$pW$1tmpX$2' ' 'tb' '''T'L.K'pBEh 'K'' K'n/tbK'*,0'B2sD'###,@3L333` m(b xm(4 ESEw 5 . '`EG!''+)Y')')"' )'b )&' )%'! !bad'(0% _$GH= "/o_$u /x_$ +p`$#,3 $%'-/G04&b HJ 9#'+/& '&9# 'l&Z '&' '&X? 'g&b 1key& 6 &7pos&XD)%&9#)"&9#V*E'J*'0J!bad'*6+'I+8'#R#F'Zb#,+%/Wb8#####y#m"$$$"###"$$%%$0 :$JbK$/t:$/a:$/k:$1p;$1o<$T+?#A$#i##]##Q#,@$u#9_K;K####y#m:K;K$$$2(i$x(4$pKKw$5$$(b5%x("(ival(b;$KKt%5%,p3%.3'%d.,9KSL%''59R['J9Xk:R!1;X3C'&KC'%C'&D';%`LL>&5%5%"3%k0"R LTZ<'',R R'R  S i#T i) U )WV )&#W )0#X 1):#Y iq)D#Z V_!*e!Q<$n )'#$+$ #$0`Z$e)',J'+'%/)Ji)'5\i)ri)WF&#b)0#):#p)D# )N#ik!* [*.#\&*\*Z*k*!]@<$9(#$=_[[)####y#m:[[3r"$$<$0()#$>`h))X"6m,) =#<$~)#$6Re a!.'0efs#*'%'#4' ''1ctx'#=|Ree'A*###:Ree3$+'###,@3;$3$3$3<%.G3 fh%+', 3&'2 8&' i'}5 8k !1 i&# b)0# '):# ')D# b%( X *[ f* 7g* h+pw #,$$-g- g. h"kn(,', ('2 iR)' i))}5 iV*  ik !1 i&# b)0# *):# *)D# b* o *r i* j* "k+ #,$$-i-i0i0kqA+-',z+A i)Wi+&# b)0#! ,):#"B,)D##i,)N#$.*_k*>k<$0P-#$+$`#$"%b.%"#?q %b.%i2"'.%"'"'#'-$'%'D&'$''('!bad<'?[%q|.1)%p/o&s&@P%<-%/, %-+-%5?/<.&X0,0%.<%p%^/#+&#"&,3%(0<%%/#+&#"&,3%^0<%@%/#+&#"&,3%0<%%/#+&#"&,3%0<% %0#+&#"&,` 3%1<% %00#+&#"&, 3%61+% %#+&#"&,@ 3%l1)dV?)&#eb?0#fb):#g@)D#h}@)N#ib8A* **!ч**O*i= =at<6# <p 6#, 3A$--+ [#,$$-n-\02`tB7',cB' B)'5zC)]XC)WC)&#b D0#b):# VD)D# D)N# bDe*5`*jv*O9 p# 0b4R dE8',R ~E'NR E)rS iE)WT  F)&#U biF0#V b):#W F)D#X F * *  9 c # 0JXpDGu9',J|G)WKXG)&#LbG0#Mb*x*{*j9 xX# 0#H:',#WH'N#H)k#H/#M)f#]I)W#J)&##bNJ0##b):##J)D##J)N##K,$*#n*2$9 5Y## 02-# Le;',-#BL'3-#L)W.#L)&#/#b0M0#0#b):#1#yM)D#2#M)N#3#N#*]#*#+ 0>## 0S(F"N5<',F"N'NF"O)WG"YO)&#H"bO0#I"b):#J"O)D#K"P"u"*"O9 1V"# 0}-!%NQ =',!Q'N!Q)W!R)&#!b=R0#!b):#!R)D#!.S2"*"Қ*7"29 Ú!# 0u!0S=',u!6T'Nu!YT)Wv!T)&#w!bT0#x!b):#y!!U)D#z!U!*!v*!9 ;c!# 0  qV>', V'N V)W =W)&# bW0# b):# W)D# X *O9 1 # 0   2Y?', Y'N Y)W Y)&# bZZ0# b):# Z)D# K[> % *C ߣ9  # 0 [@',S\'Q\)g18 ])Wz])&#b]0#b):#^)D#^*.*&>2*~*H79 Bj# 0  o_A',_'N_)k;`)W_`)&#b`0#b):#`)D#:au*?a*z9 Ѩ # 0V/GaB',Ga'QGb)g1Hi3c)WIc)&#Jbc0#Kb):#LGd)D#Md*.Sŭ*&V?*~*U<$`PB#$9 Ck`# 0neC',e'f)q1i4g)Wg)&# bg0#!b):#"Hh)D##h*.)u*&,*U.*<$&C#$9 6# 0)piD',i'j)q1i5k)Wk)&#bl0#b):#\l)D#m*.%*& *޲*<$D#$9 ˲# 0 ιmF', n'n)q1i6o)Wo)&#b0p0# b):# yp)D# !q*.ո*&Q}*=*gZ<$E#$9 U}# 0 yйnqCG',y)r'yr)q1ziSs)W{t)&#|b`t0#}b):#~t)D#Qu*.u*&*>*R<$ $G#$9 -# 0 pܿu3H',Yv'N|v)kv)Wv)&#bw0#b):#hw)D#w*`*Ⱦ9 }# 0OL x#I',x'Nx)kx)Wy)&#bFy0#b):#y)D#yt*>`*y89 # 0h PGzJ',z'Nz)k{&[)W7{)&#bm{0#b):#{)D#|*@*9 ]# 0',n|#K',|'N|)k:}&[)W^})&#b}0#b):#})D#9~** *9 # 0d 0~'L',~'N)ka&F)W)&#b0#b):#)D#`n*& *Q*s9 =a# 0{M',{'N{?)k|)W})&#~b0#b):#+)D#**9 # 0.EN','N)k)&Z)W)&#b80#b):#)D#݅)N#if*f*@*k= +O2N# +$PZ#$0G 5O',G A'NG )A H i)WI U)&#J b0#K b):#L )D#M | *w  * {9 X # 0LP',r'0)15=6kPf5?)Wu)&#b0#b):#)D#P*.*&6*"*B;= cP# + #,3$-:-*0PόR',/'NR2 .)k!f5"?)W#Ӎ)&#$b 0#%b):#&R)D#'*Q@*s**= ]2Q# +}#,3 $--0&@>T',&'+&'%/&>)g1'b)k(ڒ)/)b&)W*o)&#+b0#,b):#-)D#.J* Q *.S*&V**!H= C`cS# =_ ^RS####y#m: ^3$$<$@KS#R%,3%ɔ$'%>'T)2X^63mP,) <,6/Re a!0R bV',R '+R '%/R )S bh)(T b)WU ›)&#V b 0#W b):#X T)D#Y )N#Z )X#[ *  A*. *& G* 2  =_A U####y#m:A3y$$<$@~ U#R%,3%$'%<$ V#R%,3% $'%= Lp @V# >`V)_ X6` V@,) n 6\ be a! V 0"X',"X'+"'%/"\)) ")W"s)&#"b0#"b):#")D#"t)N#"* "%*."*&"@#"#=_%z" X####y#m:%z3e$$>IX)"X6"m@, ) "= Dh"kX# 6"Re a!01SZ','+զ'%/N)Ji)'5A 8)k:)W)&#b"0#b):#~)D#&)N#ů)X#8m* *. *& < *6&*B **!**= )Z# =_sZ####y#m:s3$$<$PZ#$>Z)X6m,) ز6Re a!0cb ]','+'%/ǵ)kŷ)141 i1 i) )  1)W b)&#b)0#b):#M)D#ٿ)N#i)X#)b#bl#b* 5F*.7*&:1*^6*7*wF*!_= !E\# <$\#$=_F65]####y#m:F3$$> u])X?6m,p) $ 6Re b!0f4 gV^',4'q14)W5 )&#6bC)0#7b):#8)D#9W)N#:i^**d * =  . E^# < p^# < v^# +$ #$0/bp4`',b'1b<)c)kd)1eX )Wf)&#gb)0#hb%):#in)D#jN#kbX#l?J**5*Ov**!4< Px`# 9 5Z# 6Gb`,GvGWHb&#Ib0#J:#KD#LbN#Mbt0/c$b a/oc$/vc$/xc$J+4`e$#R`#F`,3^`3j`3v`8$`$`$`%`-`-`%`< Pa# < a# < a# + # 0!! c','q12)W{)&#b)0#bY):#)D#N#b)X#8Q ***%= b# < b# + @# 0Y !p+Re','q1)ke)f5byb)W0)S)&#b!)0#bj):#)D#N#b)X#3)b#5 *`"*$!*@"**"*7"= L!p!d# <pd#,3u$-"-"<%d#+&#"&,$%< @e# +p#,3$-3$-#$ 'be  're A;e y!cA<1b y!AO y!A? y!Ar, y!Anb y!Ab y!A.$ f (P!Ag y!AG y!Ad  T!6&*D z!6!G y!6H z!6@.Ib  z!6JR z!6KR z!6.LR  z! g 64-Uf T!6"Vf T!6"Wf T!6Z,X (z!6f,Y 0z!6Z 8z!6[ @z!61\ Hz! g 6J]g T!624^ }!6X2_f T!6 '` Pz! 6h 6$a&h U!6{$b Xz!6c&h  U!6Vd `z! h 6H eh U!6f }!6egg U!6h hz!6 if !U!6v2j pz!6k&h *U!6dl xz! ^i 6mNi /U!6*n }!6R og :U!67p }! i 6Sqi DU!65r ~!6\sNi PU!63t ~!6{uNi [U!6lv ~!60wg fU!6.x ~! j 6,yvj pU!6z  ~! j 6-{j U!6| (~! j 6-}j U!6 ~ z!6&i U!6+ 0~!63Ni U!6 8~! k 6M k U!6R- @~!6i U!6+ H~!6)i U!6 P~!6 Ni U!6z0 X~! Rl 6 &Bl U!6 `~!6-vj V!6 h~!6 -Bl V!6 p~! l 6*-l 0V!6 x~!6 i BV!6f ~!6k NV!6 ~!66Ni [V!6 ~!6T0i fV!6r ~!6 rV!6 ~!6!&h zV!6  z!6$3f V!6+ ~!6b  V!6L ~!6Z j V!6G/ z!6&(j V!6\ z!6 f V!6 z!6g V!6  z!6Ni V!6 z!6,  V!6& ~!6-o V!6( z!6sj V!6X ~!6o V!6J z!6Q &h V!6o  z! :p 6-*p V!6 z!6U*o V!6 ~!6Wo V!6 ~!6-*p V!6 ~!6.*p V!6 ~!6-*p V!6 ~!6.&h V!6h z!6W &h V!6  ~!64j V!6* ~!6#f V!6y z!6&f V!6+ !62 W!6 z!6Ni W!6>- z!6 $f W!6 z!6$&h #W!6 {!6#$&h (W!6 {!6o&h -W!6 {!6H g 2W!6/) {!6Ni B*p<B"*p@B"*p>B"*p!B"*p>B#*p@B#*p!6 {! vv 69fv W!6  {!6 {!6% {!61 {!6& {!6  {! w 6D$w W!6O$ *p W!6Z$ *p W!6e$ *p W!6p$ *p W! w 6w% w W!6  {! w 6%w X!6 {!6Qw  X!6"  {!6%Bl @X!6.  |!6!Bl `X!6:  |!6%Bl X!6F  |!6%Bl X!6 |!6%Bl X!6  |!6%Bl X!6 (|!6!Bl Y!6O!  0|!6L&!Bl  Y!6[!" 8|!6#Bl @Y!6g!$ @|!6$%Bl `Y!6s!& H|!6`&'Bl Y!6!( P|!6k&)Bl Y!6!* X|!6$+Bl Y!6!, `|!6}&-Bl Y!6!. h|!6&/Bl Z!6!0 p|!6&1Bl  Z!6!2 x|!6&3Bl @Z!61"4 |!6="5 |!6$6Bl `Z! Z{ 6P'7J{ Z!6I"8 |!6U"9 |!6[':Bl Z!6f';l Z!6a"< |!6m"= |!6q'>Bl Z!6|'? [!6y"@ |!6"A |!6'BBl  [!6'CJ{ @[!6"D |!6'EBl `[!6:F |!6'GBl [!6#H |!6#I |!6(JBl [!6(Kl [!6#L |!6aM |!6 )NBl [!6)Ol \!6mP |!6(QBl  \!6(R T!6#S |!6$T }!6(UBl @\!6(V&h T!6B)Wh T! @~ 6)X0~ `\!6{Y }!6+ZBl \!6 %[ }!6m*\Bl \!6%] }!6x*^Bl \!6#%_  }!6*`Bl \!6/%a (}!6*bw ]!6;%c 0}!6*dBl  ]!6G%e 8}!6*fBl @]!6g @}!6*hBl `]!6_%i H}!6*jBl ]!6k%k P}!6*lBl ]!6&m X}!6+nBl ]!6)&o `}!6+pBl ]! v W6 f ^! N6f) `^! € A6 ^! 863F؀  _!  6# `_!68$0 }! KJ &6rm$:  t! p 6$` y!6$B `r!6v#$ s!6$ s!6$l }! K 6*%ށ y!  6 >%  b! : 6@|&* b!CI!CDP1y]DxKC KC CGC) KCP KC] /KC&KC1&KC< KCI,C+-CA/C$6ChLE3$K  `!&/home/aurel32/debian/co-packages/glibc/glibc-2.9/build-tree/amd64-libc/csu/crtn.S/home/aurel32/debian/co-packages/glibc/glibc-2.9/csuGNU AS 2.19.1U%% : ; I$ > $ > $ >   I : ;  : ;I8 I !I/ : ; : ; I8 &I : ; ' II : ;  : ; '  : ; : ; I8 : ;I : ; .: ;' I : ;I4: ;I : ;.: ;' 4: ;I: ;I .: ;' ! : ;" #1$41% 1&.: ;' I@ ': ;I(: ;I )4: ;I* : ;+1UX Y, U- 1..: ;' @/: ;I0.: ;' I@14: ;I21RUX Y3414.1@ 5164: ;I 74: ;I 8 91X Y: ;.1@<1UX Y=1X Y> U?.? : ;' @@1UX YA4: ; I B4: ;IC4: ; I? < D4: ;I? < E4: ;I?  U%h /home/aurel32/debian/co-packages/glibc/glibc-2.9/build-tree/amd64-libc/csucrti.S ? Ku=/0K ;K +$g% cpyamf/usr/lib/gcc/x86_64-linux-gnu/4.3.3/include/usr/include/bits/usr/include/usr/local/include/python2.3util.cstddef.htypes.hstdio.hlibio.hobject.hmethodobject.hstructmember.hdescrobject.hintobject.hfloatobject.hstringobject.htupleobject.hclassobject.hpystate.htraceback.hframeobject.hcStringIO.hcompile.hunicodeobject.hboolobject.hlongobject.hpyerrors.h @uJL 9JTt6v!X ft,^X twJv<Xu tJJL 9JTX6v&XJ,^t twJv<Xs 6"H>uPG?YMK;gY0X=u"H1&!rWfth$uttxYfKKKKKK=N/1st!~ %8@g ֱ;=hF\8@/#,].fm<%Bo YWzX փN<2 -V JJfJXG+z1L,Lg;=0  J J{3 5dJLL;/ Xuiϴ* ttf  Xw. < wJ G?c >Y;=1r < tvt XnȻ of ZKM .Zx~= .Z{y=/ ZO .[ZO/ [ZO1 Zx~=1  ~Xo%otrtqs!tqsttqs"tqs"tqst%~J+~.-K!)~tH-0C-2*-o** ***-*******-*** *z*x6 (s< <f~fv j  u< < fu ~+ u< u JnJ%}/Ji ZxT=v.g t*?ZO1 ~Ktkqs~tqJ:0}<()i@ZOk+xttiȑ 8~)*-}(8* *%]#~**X*y*p*, *<  *A,*6p"KKLL;ugCx.I0t|t|tt|t|tt}t}tt}t}tt}t}tt}t}tt}>ttjt t|x;Y)K:IEX vXc5N*\ Je,:.EX+@7(a',' **u8 *. v< ff;u u< u JxJ%<( J!tX fxT=v4Z\+Mh'/qtK X*  e**,%Kk)'*x6(r<<f / JYmX&f M/ JZN+Mh1 . X}) u< u JpJ%}*Jl%CZxT=v滮(}qt  tqstl3v 1g .Zx~=/1 Y ;YI2tqs(t  <[ZO1 .M/ JZ}:0}<(pS &Jstst~t-.0~ (}#--a---B/-y*b*-*}**JJ<n<Xf   vX <JuշX f Jvt X X .Zx~=    v< Jw?ZO1}XfZx~= .{% u< u JJ%{%uJ Z\~=M . 1ZO1~-p tqs=tqs~ttttqsthxT=v$*~fut  <Zx~=/ ZO .ZN+Mh/~- tu}J8/4stqtrJqs|t{<(qsts|t *(=/s }*4i/A 4/v//z2~/8g/1 /*/2/[////#0y0;-z//14/0 -z0C//---/}/*$X#$J![X fxT=v%B$\'O. #/\#"f[  rZ#\#.\./Q</$.ZqtztTJ****"*A # t`t XJYY`X$f   >:JF<=a=fN~%ZxT=v(<ZxT=va3"c.t X~qtqJ-*%K~-t<n-c-./;Cf%\<.g-3 ZxT=v0%;D_.!.h<.g <.g <.g2";XC ZxT=v0*YtqtW.).<H.8.<..$qJ%KG,q'q*^*2J;*Dz*E****/#%J!ZX fxT=v%%!Z%.Z.gJd.=.C.0L%Z%.Z.g K .rht,*;%M.Z**-*[; 8(J!dX fxT=v%})cf<NXh 1t,  X rZ}t;=gfZ\+Mhe.e.g0 NX1 ~JqPt2t+t~Z\+Mh/!Z\+Mh!0 K<dt tsz~J*)}0 tszOttg . sz~J*(KY)~**v*%~l-* *z*;*v*** -*h /home/aurel32/debian/co-packages/glibc/glibc-2.9/build-tree/amd64-libc/csucrtn.S ;K +Kx @@AA5AB0B7D$pBJQ0 E3,`EeJ[GOA< HBEE E(D0E8DJAI pKKSD,KcBEG A(F0`LDN <L BEE B(A0A8DP,`Z JMQ`$0eb@,fBEA D(G0,hBBED A(G0$0ktJ[@<q) BDB B(A0A8DP$|AGD0$DBDA $%AAG $0-AAG0$`ADG0$ADD pA$J[P$]JQ0$AAG $BDA $0BDA $AAG $AAG $ vAGD $lAAG0$ADD $ADD $pADD $ AAG0$йAAG0$plAAG0$lAAG0$PlAAG0$lAAG0$0lAAG0$\AAG0$JQ@$BDA $ADD@$PAAG0,BDD G@,BBD D(GP$JQP, JMQp<$BBB B(A0D8G$ JY0$pOJML@4BHB D(A0$RJML0$ !P J^@__pyx_kp_NegInf__pyx_k_writelinesPy_tracefunc__pyx_arg_c_unused2__pyx_arg_l__pyx_arg_n_fileno__pyx_k_remaining__pyx_init_filenames__pyx_doc_6cpyamf_4util_18BufferedByteStream_write_24bit_uint__pyx_k_isNaNsq_ass_slice__pyx_pf_6cpyamf_4util_18BufferedByteStream___len__tp_getattrPyExc_TypeErrorsq_itemco_argcountnb_add__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_24bit_uint__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_short__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_char__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_utf8_stringob_refcnt__pyx_filenamessq_ass_itemgetsegcountproc__pyx_kp_read_ulongsq_inplace_repeatcl_setattrlong_valnb_lshift__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_24bit_uintsq_inplace_concattp_is_gcco_firstlineno_shortbufnb_powercl_getattr__pyx_kp_read_ushort__pyx_kp_posvtableob_sstate__pyx_kp_sizesq_repeatcurexc_valueold_tbsq_concat__pyx_pf_6cpyamf_4util_18BufferedByteStream_readtp_itemsize__pyx_kp_OverflowError__pyx_vtable_6cpyamf_4util_BufferedByteStream__pyx_f_6cpyamf_4util_18BufferedByteStream_c_at_eofinitprocPyString_Typein_classcodec_search_cachePyGetSetDeftp_bases__pyx_pf_6cpyamf_4util_18BufferedByteStream_peek__off_t__pyx_pf_6cpyamf_4util_18BufferedByteStream_seekcl_nameis_unicode__pyx_kp_readline__pyx_kp_write_uchar__pyx_L10_lockPyFloat_Typesetattrofuncf_valuestacktp_dealloc__pyx_k_read_ucharnb_long_typeobjectnb_floor_divide__pyx_kp_3__pyx_kp_4__pyx_kp_5__pyx_kp_6__pyx_kp_7__pyx_kp_8bf_getwritebuffernb_inplace_lshift__pyx_tp_as_number_BufferedByteStreaminvalid_keyword_type__pyx_pf_6cpyamf_4util_18BufferedByteStream___new____pyx_k_pos__pyx_pf_6cpyamf_4util_18BufferedByteStream_consume__pyx_kp_cempty_string__pyx_kp_lf_stacktop__pyx_kp_n__pyx_kp_s__pyx_k___len____pyx_pf_6cpyamf_4util_18BufferedByteStream___add____pyx_kp_seek__pyx_tp_clear_6cpyamf_4util_BufferedByteStream__pyx_kp_read_floatcgetvaluevalues__pyx_k_basestringtp_richcompare__pyx_k_seek_IO_write_endPyThreadStatenb_remaindervisitprocPyInt_Type__pyx_L4_argument_unpacking_done_Py_TrueStructis_identifiernb_inplace_multiplyob_sval__pyx_tp_as_buffer_BufferedByteStreamnum_maxtp_comparef_stacksize__pyx_int_neg_2147483648PyMemberDefinterninterpob_type__pyx_v_old_postp_freetick_counter__pyx_getprop_6cpyamf_4util_18BufferedByteStream_endiangetter__pyx_mdoc__pyx_kp_mode__pyx_builtin_IOError__pyx_obj_6cpyamf_4util_BufferedByteStream__pyx_L5_argtuple_error__pyx_k_write_longco_nlocals__pyx_pf_6cpyamf_4util_18BufferedByteStream_getvalue__pyx_v_sizehintnb_and__pyx_v_cur_pos__pyx_k_modetp_callasync_excgilstate_counterf_localsplusob_itemtp_str__pyx_k_getvalue__pyx_pf_6cpyamf_4util_18BufferedByteStream_tell__pyx_kp_isPosInfco_filename__Pyx_PyObject_IsTrueternaryfuncPyTypeObject__pyx_k_consumePyTraceBack_Type__pyx_k_write_ushort__pyx_k___add__sq_contains_chainPycStringIO_CAPIf_exc_valuecreadtp_setattr__pyx_string_tab__pyx_kp_selfold_valrichcmpfuncunsigned charf_nlocals__pyx_k_readlinemp_ass_subscript__pyx_v_objbf_getreadbuffer_IO_lock_t__pyx_k_at_eof__pyx_k_self__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_ushort__pyx_k_read_double__pyx_kp_readlines__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_uchartp_dictoffset__pyx_f_6cpyamf_4util_is_broken_float__pyx_builtin_basestring__pyx_k_TypeError__pyx_k_close__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_long__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_ulongPyNumberMethods_Py_ZeroStruct__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_24bit_intPyMethodDefInputTypegetwritebufferproc__pyx_kp_valuefunction_namemp_subscriptOutputTypetp_clear__pyx_kp_writelines__pyx_1arg_passed_twice__pyx_k_readlinesin_weakreflist__pyx_f_6cpyamf_4util_18BufferedByteStream_pack_int__pyx_k_ValueErrornum_minuse_tracing__pyx_b__pyx_f__pyx_m__pyx_rco_freevars__pyx_v_buftp_initobjobjargprocob_size__pyx_kp_write_doubletp_dict_IO_write_ptrtp_as_mapping__pyx_kp_write_ulongsetattrfunc__pyx_k_write_short__pyx_k_IOError__pyx_v_otherfirst_kw_arg__pyx_kp_isNegInfPyExc_NotImplementedErrorbinaryfunc__pyx_kp_read_double__pyx_k_read_ulong__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_char__pyx_pf_6cpyamf_4util_18BufferedByteStream_closeob_ivaltmp_value__pyx_tp_new_6cpyamf_4util_BufferedByteStreamcodec_error_registry__pyx_kp___add____pyx_v_lengthkwds2cpyamf/util.cgetiterfuncnb_nonzero__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_floatintintargfunccodec_search_path__pyx_kp_at_eofdescrsetfunctmp_type__Pyx_Raisef_lasti__pyx_builtin_ValueErrordescrgetfuncunused__Pyx_CheckKeywordStringsnb_octnb_inplace_addkw_name__pyx_k_isPosInfco_code__pyx_pf_6cpyamf_4util_18BufferedByteStream_remaining_IO_save_basePyUnicode_Typereprfunc__Pyx_ErrRestore__pyx_kp_val__pyx_k_NegInfcurexc_traceback__pyx_builtin_OverflowError__pyx_kp_flush__pad2__pyx_kp_write_floatfrom_list__pyx_f_6cpyamf_4util_18BufferedByteStream_c_remainingpy_funcnameexact__pyx_arg_valPyTryBlock__pyx_vtabstruct_6cpyamf_4util_BufferedByteStreambf_getcharbuffer__pyx_k_read_floatPyExc_NameErrorpy_srcfilenb_divide__pyx_lineno__pyx_kp_70__pyx_f_6cpyamf_4util__get_native_endian_nextPyObjectnb_xor__pyx_kp_fpconstnb_negative__pyx_v_test__pyx_v_one__pyx_v_endian__pyx_v_new__pyx_L1_error__pyx_k_iterableprintfuncco_flags__pyx_v_size__pyx_k_val__pyx_pf_6cpyamf_4util_18BufferedByteStream___init____pyx_v_6cpyamf_4util_NaN__pyx_doc_6cpyamf_4util_18BufferedByteStream_read_24bit_uint__pyx_v_num_bytesco_name__pyx_kp_write__pyx_clineno__pyx_kp_29PyBufferProcsf_ncellsco_stacksizeml_flagstp_new__pyx_v_new_buffer__pyx_kp_sizehint__pyx_k_isNegInfb_handler__pyx_tp_traverse_6cpyamf_4util_BufferedByteStreamf_exc_tracebackmore_or_less__pyx_getsets_6cpyamf_4util_BufferedByteStreamnum_expectednb_inplace_true_dividenb_inplace_divide__pyx_k_RuntimeErrordestructorPyCFunctionf_trace_sbuf__pyx_kp_32_IO_save_end__pyx_k_write_double__pyx_kp_37__pyx_kp_38__pyx_kp_39__pyx_v_6cpyamf_4util_SYSTEM_ENDIANtp_delstdouttp_name__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_ulong__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_doubleclosure__pyx_v_encoded_string__pyx_kp_NaN__Pyx_SetVtablec_profilefunc_PyThreadState_Currenttp_as_sequencetmp_tbtp_as_buffer__pyx_v_6cpyamf_4util_NegInf__pyx_v_iterablenb_inplace_and__pyx_k_read_ushort__pyx_filename__pyx_v_valueshort unsigned intsysdict__pyx_tp_as_mapping_BufferedByteStream__import__f_blockstack__pyx_L0__pyx_kp_obj__pyx_L3__pyx_L4__pyx_L5__pyx_L6__pyx_L7__pyx_L8__pyx_L9__pyx_kp_read_shorttp_alloc__pyx_kp_RuntimeError__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_longin_dicttstate_head__pyx_kp_ValueError__pyx_v_pos__off64_tcoercion_IO_read_base__pyx_f_6cpyamf_4util_18BufferedByteStream_c_length__pyx_k_write_uchar__pyx_kp_59_IO_buf_endf_tstateinitutil__pyx_kp_read__pyx_methods_6cpyamf_4util_BufferedByteStreamtp_getattroallocfuncc_traceobj__pyx_pyargnames__pyx_k_NaN__Pyx_WriteUnraisable__pyx_k_readtp_methods_IO_write_basemoduletp_mro__pyx_kp_other__pyx_k_24global_dictintintobjargproc__pyx_kp_63__pyx_kp_64__pyx_v_done__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_floatf_code__pyx_doc_6cpyamf_4util_18BufferedByteStream_consumenb_or__pyx_int_4294967295Lunaryfunc_IO_marker__pyx_args__pyx_pf_6cpyamf_4util_18BufferedByteStream_6endian___set____pyx_v_remaining__pyx_methods__pyx_k_13nb_floatdlopenflagstraverseproc__pyx_kp_77PycStringIO__pyx_pf_6cpyamf_4util_18BufferedByteStream_readlinesinquiry__pyx_kp_isNaNnb_invertf_lineno__pyx_kp_read_charml_doc__pyx_k_32__Pyx_ErrFetchml_name__pyx_k_valuePyClass_Typenum_pos_argscwrite__Pyx_RaiseArgtupleInvalidlong doublekw_args__pyx_kp_20__pyx_kp_21__pyx_kp_22__pyx_kp_23__pyx_kp_24__pyx_kp_25__pyx_kp_26__pyx_kp_27__pyx_kp_28tp_as_number__pyx_k___cinit____pyx_k_read_short__pyx_k_23bf_getsegcount__pyx_kp_remainingtp_weaklistoffset__pyx_k_41__pyx_k_PosInfPyFrameObjectml_meth__pyx_kp_write_char__pyx_kp___len____pyx_kp_30__pyx_kp_31tp_doc__pyx_kp_33__pyx_kp_34__pyx_kp_35__pyx_kp_36__pyx_k_read_chargetattrofunc__Pyx_InitCachedBuiltinsnewfunc__pyx_v_minint__pyx_pf_6cpyamf_4util_18BufferedByteStream_6endian___get____pyx_kp_peeklen_changed__Pyx_AddTracebackPySequenceMethods__pyx_ptype_6cpyamf_4util_BufferedByteStreamstdin__pyx_kp_40__pyx_kp_41__pyx_kp_42__pyx_kp_43__pyx_kp_44__pyx_kp_45__pyx_kp_46__pyx_kp_47__pyx_kp_48__pyx_kp_49tp_weaklist__pyx_k_peek_IO_buf_base__pyx_k_34__pyx_k_39nb_positivehashfuncgetattrfunc_IO_read_end__pyx_kp_50__pyx_kp_51__pyx_kp_52__pyx_kp_53__pyx_kp_54__pyx_kp_55__pyx_kp_56__pyx_kp_57__pyx_kp_58py_globals__pyx_k_10__pyx_k_11__pyx_k_12__Pyx_InitGlobals__pyx_k_14__pyx_k_15__pyx_k_16__pyx_k_17__pyx_k_18__pyx_k_19_IO_FILE__pyx_t_1__pyx_t_2__pyx_t_3__pyx_t_4__pyx_t_5__pyx_t_6__pyx_t_7__pyx_t_8__pyx_tp_as_sequence_BufferedByteStream__pyx_v_old_other_pos__pyx_kp_60__pyx_kp_61__pyx_kp_62curexc_type__pyx_k_sizehint__pyx_kp_66__pyx_kp_69__pyx_k_20__pyx_k_21__pyx_k_22__pyx_cfilenmtp_hash__pyx_k_25__pyx_k_26__pyx_k_27__pyx_k_28__pyx_k_29__pyx_kp_tell__pyx_k_42__pyx_k_45nb_hex__pyx_k_50creadlineob_shashempty_dict__pyx_PyInt_int__Pyx_RaiseDoubleKeywordsError__pyx_k_tell__pyx_kp_71__pyx_kp_72__pyx_kp_73__pyx_kp_74__pyx_kp_75__pyx_kp_76c_tracefunc__pyx_kp_78__pyx_kp_79__pyx_k_30__pyx_k_31func_name__pyx_k_33f_nfreevars__pyx_k_35__pyx_k_36__pyx_k_37__pyx_k_38PyIntObjectpy_frame__pad1__pad3__pad4__pad5__pyx_k_5py_code__pyx_kp_80__pyx_kp_81__pyx_builtin_EOFError__pyx_k_40_markers__pyx_k_43__pyx_k_44setter__pyx_k_46__pyx_k_47__pyx_k_48__pyx_k_49__pyx_tp_dealloc_6cpyamf_4util_BufferedByteStreamf_back__pyx_kp_consume__pyx_v_result__pyx_vtab__pyx_kp___init__tp_memberstp_traversemp_length__pyx_kp_PosInf__pyx_k_51__pyx_k_52__pyx_k_53__pyx_k_54__pyx_k_55__pyx_k_56__pyx_k_57__pyx_k_58__pyx_k_59__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_shortGNU C 4.3.3 20090119 (prerelease)f_exc_typenb_inplace_xor__pyx_k_flushtp_subclassesnb_inplace_power__pyx_pf_6cpyamf_4util_18BufferedByteStream_readline__pyx_v_modeco_names__pyx_k_60__pyx_k_61tp_setattro__pyx_kp_buf__pyx_k_64__pyx_k_65__pyx_k_66__pyx_k_67freefunc__pyx_k_69__pyx_k_62__pyx_k_63nb_multiply__pyx_kp_TypeError__pyx_k_68num_foundnb_true_divide__pyx_doc_6cpyamf_4util_18BufferedByteStream_read_24bit_inttp_getsetf_locals__pyx_builtin_TypeErrorPyLong_Type__pyx_k_write_ulong__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_ushort__pyx_vtabptr_6cpyamf_4util_BufferedByteStream__pyx_k_objtp_iternext__pyx_k_71__pyx_k_72__pyx_k_73__pyx_k_74__pyx_k_75__pyx_k_76__pyx_k_77__pyx_k_78__pyx_k_79sq_length__pyx_kp_read_uchar__pyx_f_6cpyamf_4util_is_big_endian__pyx_kp_truncategetreadbufferprocinvalid_keywordtp_descr_get__pyx_k_OverflowErrorPyClassObjecttp_iter__pyx_v_bytesNewInputnb_inplace_floor_divide__pyx_k_80__pyx_k_81kwdict__pyx_k_70__pyx_kp_write_shortPyExc_OverflowError__pyx_kp_iterable__pyx_builtin_RuntimeErrorgetcharbufferproctp_basenb_rshiftNewOutput__pyx_int_0__pyx_int_2__pyx_empty_tupleco_constsf_globals__pyx_f_6cpyamf_4util_swap_bytestp_printlong long unsigned intrecursion_depth__pyx_v_self__pyx_k_3__pyx_k_4_cur_column__pyx_k_6__pyx_k_7__pyx_k_8__pyx_k_9__pyx_kp_basestring__pyx_kp_write_ushortnb_inplace_remainder__pyx_pf_6cpyamf_4util_18BufferedByteStream_flush__pyx_k_writeempty_list__pyx_k_c__pyx_kp_EOFError__pyx_k_buf__pyx_k_l__pyx_k_n__pyx_k_s_object__pyx_v_6cpyamf_4util_PosInfPyCodeObject__pyx_v_6cpyamf_4util_float_brokenkw_allowednb_absolute_IO_backup_base__pyx_k_sizef_restricted_IO_read_ptrcl_dict__pyx_kp_read_long__pyx_L3_error__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_uchar__pyx_v_chars_read__pyx_kwdsf_iblocknb_inplace_or__pyx_kp_close__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_24bit_int__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_utf8_stringob_fval__pyx_setprop_6cpyamf_4util_18BufferedByteStream_endiantp_reprtp_cachePy_ssize_traise_errorpycobj_old_offsetsq_slice__pyx_k_write_floatnb_inplace_rshift__pyx_kp_write_long__pyx_f_6cpyamf_4util_18BufferedByteStream_unpack_int__Pyx_StringTabEntry__pyx_k_read_longc_profileobjcl_delattrPyInstance_Typelong long int__pyx_v_i__pyx_k_EOFError__pyx_skip_dispatch_Py_NoneStruct_flags2__pyx_v_n__pyx_v_valPyMappingMethodsf_builtins__pyx_v_c__pyx_int_2147483647modules__pyx_v_l__pyx_v_s__pyx_v_t__pyx_pf_6cpyamf_4util_18BufferedByteStream_truncate__pyx_v_x__pyx_pf_6cpyamf_4util_18BufferedByteStream_writetp_flags__pyx_k___init____Pyx_Import__pyx_kp_getvalue/home/buildbot/slaves/pyamf/debian64-py23/build__pyx_k_fpconstnb_subtract__pyx_PyInt_longb_level__pyx_pf_6cpyamf_4util_18BufferedByteStream_writelines__pyx_k_truncate__Pyx_InitStrings__pyx_f_6cpyamf_4util_18BufferedByteStream_pack_uint__pyx_v_bytes_left__pyx_k_write_char__Pyx_GetNameco_varnames__pyx_type_6cpyamf_4util_BufferedByteStreamiternextfunc__pyx_doc_6cpyamf_4util_18BufferedByteStream_write_24bit_int__pyx_kp___cinit__co_lnotabthread_idcl_bases__pyx_pf_6cpyamf_4util_18BufferedByteStream_at_eofnb_int__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_doubleold_exc__pyx_k_othertp_descr_set__Pyx_ParseOptionalKeywordsnb_coerceshort int__pyx_v_buffer_vtable_offsettp_basicsizenb_inplace_subtract__pyx_v_leco_cellvars__pyx_v_maxint__pyx_f_6cpyamf_4util_18BufferedByteStream_unpack_uint__pyx_v_big_endiannb_divmod__pyx_kp_IOErrorobjobjprocPyInterpreterStateUfrUUTTfUrUJfT{T4PDVPbePfPPT'DTQ Q'DQR 'RBDR 'TPPP2DPPQwQwP]U]{SUTPPTQQwwUUQQ w w0U\Q2\2>Q>\aQam\m{QQTST(S(>T>SQV-V>VU\UmxUU\2\a\m\]7] a]m]PP%.P9FPUUwEw U dSSSP^E^6p]]E]NQP_E_loP\E\baVVEVdfSSESPQwQwPUUPZTbePlSwwww w(w0w80 wU ] ] 0 ]T \ \ 0 \Q w  - - O w O  0 w R ^ ^ 0 ^XY0 w77TT  # T# - - E TE O O W TW  T 0 5S5nQn- S- E QE S S Q 0 S V V 0 V0 1 w1 : w: w 0 @ U0 6 T0 @ QC F P S  U U  w c w & U) W U) : RD \ R, . R. : QF M PM \ Qa c Qp r wr w ww ~ w~  w  w( w0p } U} ]p T S w $ w U T  V $ V P $ S0 2 w2 7 w7 < w< > w > ? w(? @ w0@ D w8D w0 \ U\ ^^0 R TR __q]S]]]&]:]]g]]]/]qSISS_ b PqSISSS|  P ] TVT]qVq]VM]MV=V] V]V]V w / / ; w; @pp@ww=@=@=S@~@@-@-@@ PM\=S\`\&\j\\ /\c\w$wU]$]TCS)T)STXS%5TvS S!!S""S##SF$$SQ`VV&V%5VV V9!c!V!!V^#g#V##VF$$V%\\O\%\,5\}\.1P D"\" #\P$z$\8%5} !!"PS9S!"SQQPQ: Q QT Y Q\LOP5}\X[P !9!\!!\D""\ #F$\@CPSUXP69PP%S5SsvP  P S !S""S"#S#$S#$F$S]`PV#&P5VP 9!Vc!!V!^#Vg##V#F$V^^^%^5}^ Su S S 9!^!!^!"^##S$#$S<tX=R)CRRPRP*R RPF$P$P$$w$6&w$%U%%_%%_%-&_$%P%d%Ug%s%U%%U%%U&&U%%S%%S%&S%%V%%V%&V %*%P7%>%PK%S%Pg%x%P&6&P@&B&wB&G&wG&H&wH&L&w L&S&w(S&Z(w0@&Y&UY&&]&']'Z(]@&Y&TY&&S&'S''T''S''S@&y&Qy&&V&'V''Q'J'V''V''V0(Z(V''P'Z(SG'J'P'0(V&&P&&P''P`(b(wb(g(wg(k(wk(l(w l(s(w(s(*w0`(}(U}(?)]D))])*]`(}(T}((S((T((SD)T)TT))S)*S`((Q(=)\D)\)Q\))\)*\((PD)K)P((P**S((P*x*Vx))P))P)*P**w*$1w**U**]*+U+$1]**P..P**S++P**V8+;+P,,P.L.VU..V.0VD00V0$1V**^l+,^,,V,u-^--^-.V.5.^<.L.^L.U.VU..^.0^0;0V;00^00V0$1^**\++P-5.\E.U.\z..\.J/\h//\/$1\0121w2161w6181w81:1w :1;1w(;1<1w0<1@1w8@1Y<wd33S33S#66Sx::S;Y<S13S33S77S34P>8E8P4B4P88PE4h4P.959Pk44P88P44P: :P44Pu9|9P44P99Pd33S33S55P7>8S/<Y<S55Vd33]33]66PJ::];Y<]d33\33\+6.6PJ::\;Y<\d33^33^?6B6PJ::^;Y<^d33V33V!67VJ::V;Y<V33@77@J:x:@33wH77wJ:x:ws7x7P33S67SJ:h:S`<a<wa<h<wh<l<wl<%?w0`<g<Ug<=V[==V=>VE>>V`<q<Tt<v<P[==S==Q==S==QE>>Sp=>`==P==P>>P<<P[=g=PE>L>P<<P==S>E>S>%?S<=P==V>E>V>%?V0?2?w2?6?w6?7?w7?tBw 0?;?U;?@\@@\@tB\?@P@@Pf??P6@J@P@@P5AGQGPQGGPGHPmHHPI3IPIIPJJwJJwJJwJLw0JJUJ;KSKKSKLSL-LS]LLSJJTJrKVKKVKLVL-LV]LLVLLVKLX L-LXKLdL-LdKKPK5KPKKP]LdLP8K;KP-L]LSLLSoKrKP-L]LVLLVKKPLLPMMwMMwM Mw MNw M MUM4MTFMUMTM NT NNPM[MSMMSM!NSMNwNS7MUMPMNPMNTNPXM[MP#NMNSwNNSMMP#NMNVNNVNNwNyOwNNU$O$OPwOwOPO$OP)O4OPAOHOPOOwOTwOOUOJQ_OQT_OOTOOTOQZQT POQ@Q-R@]RR@R,S@ST@ Q;Q\QQ\RR\RR\ S,S\6SYS\cSS\SS\ST\Q6QSQQSOOPOQZQPRRPPPP]Q`QP-RRS,STS"P%PPPQVQEQ^QQPQQVQ-R^-RRVRRVR,S^YSTVPPP]RR\SS\ T;Tw;T}Ww0 T?TU?T/U]4U}W] TKTTKTT\U*U\4U V\=VVW\U%UPUUPmTTP4UBUP=VDVPTTPEUHUPV}WSTTPwUzUPgVVVW}WVTTPUU\ V=V\VV\8W}W\WWwWWwWWwWZw WWUWWTWWTXXT{XXQXXQ YYQY(YQWWPXXP(Y/YPWWPiX|XS|XXVXXPX YS Y'YV|YYVYZSXXPiX|XS|XXVXXPX YV Y#YSRYYSYZVZZwZZwZZwZ\w ZZUZCZTRZYZTZZTq[q[PFZcZPZZP[[PZZPZZPa[n[Sn[o[Vt[[S[[V\T\VT\\SfZiZP[[Pa[n[Sn[o[Vt[[V[[S[T\S~\\V\\w\\w\\w\}_w \\U\\T\\T]]T]]P1^1^P\]P]]P^^P']*]P]]P!^.^S.^/^V4^b^Sb^^V^,_V,_}_S ] ]P]]P!^.^S.^/^V4^b^Vb^^S^,_SV_}_V__w__w__w_bw __U__T__T``T{``Q``Q aaQa(aQ__P``P(a/aP__Pi`|`S|``V``P` aS a'aV|aaVabS``Pi`|`S|``V``P` aV a#aSRaaSabVbbwbbwbbwbdw bbUbAbTVbebTc#cT ccQVcicQccQccQDbebPc(cPccPhbkbPb cS ccVHcKcPiccSccV dOdVOddSbbPb cS ccV+c.cPiccVccScOdSyddVddwddwddwdhw ddUdUeVeeVeeVe2fVfgVggVddTddPeeSeeSefSfUgSeePeePPgUgPdePeePeePffPReUePeeSeeVefPffVffSggVghS e#ePeeSeeV/f2fPffSffVUggSghV h!hw!h"hw"h)hw)hjw0 h-hU hQhTfhuhT i%iT ii`xi|iPiiPThuhP iiPiiPxh{hPji}iSiiSjjShhPji~iViiVjbjVjjwjjwjjwj>nw jjUjUkVkkVkkVkBlVllV mmVmnVjjTjjTjkTkkTk lTllT7mnS k#kPkkSkkV?lBlPllSl mV}mmSn>nV@nAnwAnEnwEnInwInqw @nZnUZnoV\opoVqooVooVJpYpVpZqVqqV@nbnTennTnnTqooTooTJpYpTppTennS\oooSqooSooSTpYpSp-qSjonoP(q-qPnnPqooPooPppPooP\oooSoopoVooPYppVppSZqqVqqSnnP\oooSoopoVooPYppSppV-qqSqqVqqwqqwqqwquw q rU rrVrrVAsUsVVssVs tVmt uVMuwuVqrTrKrT^rrTrrTVsjsTs tTttTrrSrrSAsTsSVspsSt tSmttSrrPSsSsPttPNr~rPrrPVsjsPmtttPrrPAsTsSTsUsVmspsP t=tV=tmtS uMuVMuuSrrPAsTsSTsUsVssP t=tS=tmtVtMuSwuuVuuwuuwuuwuNyw0uuUu.vSvvSvwSw wSwwSxxSuuTuuTv(vTvvTwwTwwTGxLxTuvwvv`vvwvw`wwwww`wxwxx`xNywvvPxxPvvPwwPx$xP]v`vPvvSvvVw wPwwVwxSxxVxNyS+v.vPvvSvvVOwRwPwwSwxVxxS'yNyVPyQywQyRywRyYywYy|w0PyjyUjyySyzSzzSzzSJ{Y{S{-|SPyryTryyTyyTy zTzzTJ{Y{T{{Twyywyy`yywyz`zJ{wY{{`{-|w-||`||wyyPzzP(|-|PyyPzzP{{P?zBzPzzSzzVzzPY{{V{{SZ||V||S zzPzzSzzVzzPY{{S{{V-||S||V||w||w||w|\w0||U|!}T6}E}T}}T}~`H~L~Po~x~P$}E}P}}P~~PH}K}P:~M~S~~S~\S}}P:~N~V~~V~2V`awabwbiwíw0`mU`TTKeT``P߀PPKWP5<PPS5S_́SPV5V_VЁсwсҁwҁفwف<w0Ё݁UЁT%TՂTЂx`(,POXP%PǂPP(+P-SxSσ<S_bP.VxVσV@AwABwBIwIw0@MU@qTT+ET@`PɅPtP+7PPPSS?Sτ҄PVV?Vwwww0UTTTX` P/8PPPP P SXSS?BPVXVV !w!"w")w)|w0 -U QTfuT %T `x|PPTuP PPx{Pj}SS|SPj~VVRVw$wUSS1SS"DSƎSϋTTTP1΍P"MP$PG\GrSr|\\΍S΍\$SGwVP΍VҋPPPP΍SMSSG]όҌPHKPP΍]΍V"M]MV$]SDMSS02w26w67w7/w 0;U;\\/\0cTv}T TȏSSҐSS/SPP PfP P$PP PVҐSҐVGSޑ/VP?BPVҐVSqVS01w15w59w9̔w0JUJVRVVГVV0RTX]TГTXw˓̔wPPZ_PPPP PГS_̔SORPГV̔VՒPPДєwєҔwҔٔwٔlw0ДݔUДT%T̕T&`S`#PnwP%PǕPՖܖP(+P$SՖSlS_bP%VՖV)lVFXPPprwrvwvzwzw wpU\\pTS×T֗T~TS5TTSTuT1SpSTTMSpQ"V~VGVuVQ VMVSSSQSPQGSS/1PPޛSX0XGX@ZPؙPPP$PƗP'PPPSGuSޛMS"PVGuV MVԘX×Q֗Q<QQ|QQQ×R֗RR>RŚ֚R֚PRP,RpRPwPwwww w(ZwUU\X\;\\-l\\Z\TVTSVXzTzSV 'V؟T؟V-=TmvV=VluVVZVQRSXkSΟSQPS=SZS<RSQSǝPǝS 0S05USmxSNPPPS=ISlwSSS<W]Q]P] D]DIUǟ]m]^]=]P]?k]JXQQQP !PmtP<U\P8;P\=m\l\\<SVPSP$'P-V=mVvV=lVuVV<J]JU\UW]\ ]LOP\-\=m]?]k]\<RS SbeP-S=mSxSIlSwS?SHkSS X}Q؟ܟQ4=QQQQQ !QܟQơQơˡQW]^]=]Z]9PPZP`{w{w`UD]I]`TST5SISܦS5ETSS`Q:VIJVƦV5EVէV,VV?\\5u\\է\-IQ-Q05Q PPP5SP٦ܦPESS:VGJPæƦPEVէV,V?\Pu\Q\\XRSRRR RRէRPP HwH%w TUTG_L%_ TTTST!SLjTjSGPSSȬS%T%/SȮSE-S;SʲS$S̳SS%S TQTaV.VLmVVEɰV-V%VadV.Vm)VZVV/VRVȮUVưɰPVұܱVR\VVʲԲVV$.VQ[V~VʳVVg&LGZkE-RzdV&.V.B^)ZVV/RVȮVұVܱRV\VʲVԲV$V.QV[~VVʳVVzVgS!3SPZSS<ESPPP%,PP&8\PȬ\P-\ұ$\Q\PgV&.VPZSȬS,/P=SRUP0S0EV-EVEuSuVSʲ$SS̳SpSpzVSP&=]GZ]Ȭ]svP-]߱]ײ]gw&LwGZwȮw߮wE-EwERwzw$w~wppwǴǴwX_RRRRRìR[lRl{PRP°R-R~P%P02w24w46w68w 89w(9=w0=Dw8DTw0RURw }w }  w =w =  Tw 0RTR]S]oToSڵTTƸTƸLSQ}T}SSS S=S TS0UQU϶VwYVb<VɺVͻV]VռVV3VV QV=V,=VVV3VgVVIxVV!PV V;hVTVl_Qa_s __= _ϵQb]u =* ߵw(Qbw(]w(uw(w( =w( Y]ٷ]Q]]]ͻ]-]uݼ]] ]]=,];`]l]]3]?b]n]]] ] SiSLXSSSuSMSS3SS*YSISSS SPPP}P PҽPPPܹPPúPPPϽP P*1PIPPS PknPiSPPPIuSSJMPPS3 SS=S*SYISSSS$'P^>\>^Q_^PPͻ^]\uռ^ռ\^/2Pp?\?Q^Q\3e^^ \\=t\t^\^\3^3b\b^\^Y^^\^I\B\Be^e\!^P]\]^\Yٷ]]ͻ]-]]ݼ],;]`l]]]3?]bn]]]̶϶PQYV9<PƺɺPͻ]VuռVPP3V VV=,V=VVV3VgVIVxV!VP V;VhV PPPٸXoRRRRƸRQbR}RKRW\RR=RNwPJTP`ww0`U]]`T}\\oxPPPPaxV3V}VVVPHfS}S[S PasSsxVPPSPSuS}VS1[V[SasSSu}SSw?w*U*"],?]/T/S,@SCSSSSSS\S\S\S\,\S\S\S \ ISI\S\S?\f,@I@}@@>F@s?@n,LIL}LL>FLs?LVVMPP,:PPP PP=@P@CPISASFPSs}SPV Q ,QorPVQPPQ VFVsV?Q@BwBJwJLwLPw PQw(Q;w0@WUW^V^W;^@WTW\R\W;\@lQt~Q5QPNNP:?PVPVV?VPPSP S /P/{S{PS P OSmpP=BPBSSSZPZkSkrPrS?;S@cwcw0@gUg]\l\@wTwg^l^OXPPAXVlPVKVV PTV-eVAXVKV/rVeVPSTrSSPASSSXVPPS P MSMoPoSVP/SV-SeSASSP-eSwwU^^T]]__e__G_S S(SSPSPVYP$'PSSYSFSsSESPPelPS SSXS@SS(YSPPMeSS-YSS\SFsSSPPSPdgPMSS-SSSSESSORPVPYVVV\\ Pe\\Y\\)\\(\w;XwX@#(ww$PPX_PPJYP??;;++0@0@hphpQgl_bleg a  a   3 @ c  / u((8F$$ FF$P$ %g%%&%g%%&&&''&&''d)x))*d)x))*P+l+8.H.m,,H.U.U1\1^1e1\1^19;;:;22e12j1z19;;:;221211111111221_2348J:>88348J:>8833>8P833>8P84 4884%44%488,434.9@9:4K4B4K4.9@9R4Y488`4q4h4q488x44::4444::44u994444u994499444499{555555555555;/<;; 6666<<;<;;B66<6?6.606(6+66#66666,707'7*7 7766,707'7*7 77 7'7J:x:67s7*7,7;7\7J:W:k7s7??#@@@C+CKDeD*G>GII*G>GIIGGIIGGII?TFTITjTjjllInenPp`pqrttuuwwYyryP{`{d@M’’4N4NxxM֚wd0@du0@}ơΟơΟZ@PZIاsTm%E%0l%<Yؼ T T@W<TJT8@wp!*JW?;`NWg?;p}jmEN8kehQLFI+:& ly q/24Coqs`r`r4dfhH`H`;;++.symtab.strtab.shstrtab.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rela.dyn.rela.plt.init.text.fini.rodata.eh_frame_hdr.eh_frame.ctors.dtors.jcr.data.rel.ro.dynamic.got.got.plt.data.bss.comment.debug_aranges.debug_pubnames.debug_info.debug_abbrev.debug_line.debug_frame.debug_str.debug_loc.debug_rangesXXdo@% - 5oppBo Q880$[h6h6p e;;`;;k??q++w2++Q  8 8::lP!PP!P P! P(P!(P0P!0PQ!QhR!hR`T!`T$ `y!Py Py0zzO?{ &'P* 40h46?wjJpJdXXoH0% k&X p8h6 ; ; ? + + 8:P!P! P!(P!0P!Q!hR!`T!`y! !"  ?'P!5P!C P!P ?f`y!uhy! @@P!xB P! p+ @ z!- @Ad A5 B 0B7 pB E3 `Ee.y!=y!Ky!Sy!ey!r(P! GOy! H J z!9 pKJ KSZ Kc{ `LD L Xz!y!`z!(z!0z!z!-xz!; `Z ly!x{!(}!{!z!a!z!hz! 0e fI{!U{!q hB{! 0ktb!8z! @z!$Hz!9 b!@JT!8Uy! cy!kz!{!x{! {!{!({!0{!8{!{!'p{!={!T}!8y! % Dz!T!  z!?z!YT! dz!T!  z! ||!T!|! |!  0-M }!Y @{!f P{!v H{!  ` x|!   |!  p7  k `}!w  ] z! X}!   H}! z!!  S z!b @}!n  0 z! 8}!   (|! pz!  ? {!K  v |! |!  l X|!   |!+ |!7  o |!{ |!  p |! |!  |!|!' й_|!k|!w plp|! lh|! Pl<`|!H lP|! 0lH|! \@|! H8|!T  |!  }! P}! N0|!Zz!ea!| |!z!z!a!  z!2a!IP}!Uz!h  Pz!0}!a! $z!{!{!+{!7{!Cz!Pb!f |! pO|!}!T! T! M{!Y{!e{!q{!}{!{! R|! !P }!X{!-`{!?h{!Q`r!0ws!Ps!}!  t!y!PJ}!]T! oT! U! U!}!U!U! !U! *U!}!/U! }!#:U! 5~!JDU! ^~!rPU! ~![U! ~!fU!  ~!pU!(~!U!U! 0~!U! 28~!FU! Y@~!oU! H~!U! P~!U! X~!U! `~!U!h~!V!'p~!2V!<x~!G0V!Q~!fBV! z~!NV! ~![V! ~!fV! ~!rV!zV!#~!5V! F~!WV!gV!uV!V! V! V! ~!V!V!~!V!V!V!V!&~!3V!?~!LV!X~!cV!m~!xV!~!V!V!~!V!~!V!V! !V! W! W! 3W! >#W!I(W!T-W!_2W! q  _!9{ `_! hR! `T! P! 0P!  !'!9!E!R!_!x!!!! ! !!! +!"$"4"E"P"k"w"""""""# ##+#<# q) E#R#"n#~########$$'$4$I$Z$i$e}$$$$$$Py!$$%$%8%I%W%h%% `!x%%%%!%%&&,&Py!3&>&K&Z& ;`&initfini.ccall_gmon_startcrtstuff.c__CTOR_LIST____DTOR_LIST____JCR_LIST____do_global_dtors_auxcompleted.6068dtor_idx.6070frame_dummy__CTOR_END____FRAME_END____JCR_END____do_global_ctors_auxutil.c__pyx_f_6cpyamf_4util_18BufferedByteStream_unpack_int__pyx_v_6cpyamf_4util_SYSTEM_ENDIAN__pyx_f_6cpyamf_4util_18BufferedByteStream_unpack_uint__pyx_tp_dealloc_6cpyamf_4util_BufferedByteStream__pyx_tp_traverse_6cpyamf_4util_BufferedByteStream__pyx_tp_clear_6cpyamf_4util_BufferedByteStream__Pyx_Raise__Pyx_PyObject_IsTrue__Pyx_AddTraceback__pyx_filename__pyx_clineno__pyx_m__pyx_empty_tuple__pyx_lineno__pyx_cfilenm__pyx_getprop_6cpyamf_4util_18BufferedByteStream_endian__pyx_f__Pyx_ParseOptionalKeywords__pyx_tp_new_6cpyamf_4util_BufferedByteStream__pyx_vtabptr_6cpyamf_4util_BufferedByteStream__pyx_PyInt_long__pyx_PyInt_int__pyx_f_6cpyamf_4util_swap_bytes__Pyx_GetName__pyx_pf_6cpyamf_4util_18BufferedByteStream___add____pyx_kp_tell__pyx_ptype_6cpyamf_4util_BufferedByteStream__pyx_kp_seek__pyx_int_0__pyx_int_2__pyx_kp_write__pyx_kp_read__pyx_pf_6cpyamf_4util_18BufferedByteStream_peekPycStringIO__pyx_builtin_RuntimeError__pyx_kp_74__pyx_builtin_ValueError__pyx_kp_size__pyx_pyargnames.11696__pyx_kp_peek__pyx_kp_remaining__Pyx_WriteUnraisable__pyx_f_6cpyamf_4util_18BufferedByteStream_pack_uint__pyx_kp_32__pyx_builtin_OverflowError__pyx_f_6cpyamf_4util_18BufferedByteStream_pack_int__pyx_kp_31__pyx_f_6cpyamf_4util_18BufferedByteStream_c_length__pyx_filenames__pyx_int_4294967295L__pyx_int_neg_2147483648__pyx_int_2147483647__pyx_string_tab__pyx_mdoc__pyx_methods__pyx_b__pyx_kp_basestring__pyx_kp_TypeError__pyx_builtin_basestring__pyx_kp_ValueError__pyx_builtin_TypeError__pyx_kp_OverflowError__pyx_kp_IOError__pyx_kp_EOFError__pyx_builtin_IOError__pyx_kp_RuntimeError__pyx_builtin_EOFError__pyx_vtable_6cpyamf_4util_BufferedByteStream__pyx_skip_dispatch__pyx_f_6cpyamf_4util_18BufferedByteStream_c_at_eof__pyx_f_6cpyamf_4util_18BufferedByteStream_c_remaining__pyx_kp_fpconst__pyx_k_9__pyx_v_6cpyamf_4util_float_broken__pyx_v_6cpyamf_4util_NaN__pyx_k_10__pyx_v_6cpyamf_4util_NegInf__pyx_k_11__pyx_v_6cpyamf_4util_PosInf__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_utf8_string__pyx_kp_64__pyx_k_65__pyx_kp_37__pyx_kp_35__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_double__pyx_kp_70__pyx_kp_NaN__pyx_kp_PosInf__pyx_kp_NegInf__pyx_pf_6cpyamf_4util_18BufferedByteStream_write__pyx_kp_49__pyx_pf_6cpyamf_4util_18BufferedByteStream_at_eof__pyx_kp_36__pyx_pf_6cpyamf_4util_18BufferedByteStream___len____pyx_pf_6cpyamf_4util_18BufferedByteStream_consume__pyx_kp_81__pyx_pf_6cpyamf_4util_18BufferedByteStream_writelines__pyx_kp_writelines__pyx_kp_80__pyx_pf_6cpyamf_4util_18BufferedByteStream_readline__pyx_kp_78__pyx_kp_readline__pyx_pf_6cpyamf_4util_18BufferedByteStream_flush__pyx_kp_flush__pyx_kp_77__pyx_pf_6cpyamf_4util_18BufferedByteStream_close__pyx_kp_close__pyx_kp_76__pyx_pf_6cpyamf_4util_18BufferedByteStream_getvalue__pyx_kp_39__pyx_kp_getvalue__pyx_pf_6cpyamf_4util_18BufferedByteStream_tell__pyx_kp_33__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_24bit_uint__pyx_kp_61__pyx_kp_60__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_ulong__pyx_kp_45__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_24bit_int__pyx_kp_63__pyx_kp_62__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_short__pyx_kp_57__pyx_kp_56__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_ushort__pyx_kp_55__pyx_kp_54__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_char__pyx_kp_53__pyx_kp_52__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_uchar__pyx_kp_51__pyx_kp_50__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_24bit_int__pyx_kp_48__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_24bit_uint__pyx_kp_47__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_long__pyx_kp_46__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_short__pyx_kp_44__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_ushort__pyx_kp_43__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_char__pyx_kp_42__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_uchar__pyx_kp_41__pyx_pf_6cpyamf_4util_18BufferedByteStream_remaining__pyx_kp_38__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_float__pyx_kp_73__pyx_pf_6cpyamf_4util_18BufferedByteStream_read_float__pyx_kp_72__pyx_pf_6cpyamf_4util_18BufferedByteStream_read__pyx_kp_40__pyx_kp_n__pyx_pyargnames.10015__pyx_pf_6cpyamf_4util_18BufferedByteStream_seek__pyx_kp_34__pyx_kp_pos__pyx_kp_mode__pyx_pyargnames.9601__pyx_pf_6cpyamf_4util_18BufferedByteStream_readlines__pyx_kp_sizehint__pyx_pyargnames.12256__pyx_kp_79__pyx_kp_readlines__pyx_pf_6cpyamf_4util_18BufferedByteStream_truncate__pyx_kp___init____pyx_kp_75__pyx_pyargnames.11845__pyx_pf_6cpyamf_4util_18BufferedByteStream___init____pyx_kp_20__pyx_kp_21__pyx_kp_24__pyx_kp_22__pyx_kp_23__pyx_kp_buf__pyx_pyargnames.9004__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_long__pyx_kp_59__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_utf8_string__pyx_kp_66__pyx_kp_69__pyx_k_68__pyx_k_67__pyx_setprop_6cpyamf_4util_18BufferedByteStream_endian__pyx_kp_26__pyx_kp_30__pyx_kp_27__pyx_kp_28__pyx_kp_29__pyx_kp_25__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_ulong__pyx_kp_58__pyx_pf_6cpyamf_4util_18BufferedByteStream_write_double__pyx_kp_71__pyx_kp_isNaN__pyx_kp_isNegInf__pyx_kp_isPosInf__pyx_tp_as_number_BufferedByteStream__pyx_tp_as_sequence_BufferedByteStream__pyx_tp_as_mapping_BufferedByteStream__pyx_tp_as_buffer_BufferedByteStream__pyx_methods_6cpyamf_4util_BufferedByteStream__pyx_getsets_6cpyamf_4util_BufferedByteStream__pyx_kp___cinit____pyx_k___cinit____pyx_k___init____pyx_k_tell__pyx_k_seek__pyx_kp_at_eof__pyx_k_at_eof__pyx_k_remaining__pyx_k_getvalue__pyx_k_read__pyx_kp_read_uchar__pyx_k_read_uchar__pyx_kp_read_char__pyx_k_read_char__pyx_kp_read_ushort__pyx_k_read_ushort__pyx_kp_read_short__pyx_k_read_short__pyx_kp_read_ulong__pyx_k_read_ulong__pyx_kp_read_long__pyx_k_read_long__pyx_kp_3__pyx_k_3__pyx_kp_4__pyx_k_4__pyx_k_write__pyx_kp_write_uchar__pyx_k_write_uchar__pyx_kp_write_char__pyx_k_write_char__pyx_kp_write_ushort__pyx_k_write_ushort__pyx_kp_write_short__pyx_k_write_short__pyx_kp_write_ulong__pyx_k_write_ulong__pyx_kp_write_long__pyx_k_write_long__pyx_kp_5__pyx_k_5__pyx_kp_6__pyx_k_6__pyx_kp_7__pyx_k_7__pyx_kp_8__pyx_k_8__pyx_kp_read_double__pyx_k_read_double__pyx_kp_write_double__pyx_k_write_double__pyx_kp_read_float__pyx_k_read_float__pyx_kp_write_float__pyx_k_write_float__pyx_kp___len____pyx_k___len____pyx_k_peek__pyx_kp_truncate__pyx_k_truncate__pyx_kp___add____pyx_k___add____pyx_k_close__pyx_k_flush__pyx_k_readline__pyx_k_readlines__pyx_k_writelines__pyx_kp_consume__pyx_k_consume__pyx_k_buf__pyx_kp_value__pyx_k_value__pyx_k_pos__pyx_k_mode__pyx_k_n__pyx_kp_obj__pyx_k_obj__pyx_kp_val__pyx_k_val__pyx_kp_l__pyx_k_l__pyx_kp_s__pyx_k_s__pyx_kp_c__pyx_k_c__pyx_k_size__pyx_kp_self__pyx_k_self__pyx_kp_other__pyx_k_other__pyx_k_sizehint__pyx_kp_iterable__pyx_k_iterable__pyx_k_fpconst__pyx_k_basestring__pyx_k_20__pyx_k_21__pyx_k_22__pyx_k_23__pyx_k_TypeError__pyx_k_ValueError__pyx_k_OverflowError__pyx_k_IOError__pyx_k_EOFError__pyx_k_NaN__pyx_k_NegInf__pyx_k_PosInf__pyx_k_isNaN__pyx_k_isNegInf__pyx_k_isPosInf__pyx_k_RuntimeError__pyx_k_24__pyx_k_25__pyx_k_26__pyx_k_27__pyx_k_28__pyx_k_29__pyx_k_30__pyx_k_31__pyx_k_32__pyx_k_33__pyx_k_34__pyx_k_35__pyx_k_36__pyx_k_37__pyx_k_38__pyx_k_39__pyx_k_40__pyx_k_41__pyx_k_42__pyx_k_43__pyx_k_44__pyx_k_45__pyx_k_46__pyx_k_47__pyx_k_48__pyx_k_49__pyx_k_50__pyx_k_51__pyx_k_52__pyx_k_53__pyx_k_54__pyx_k_55__pyx_k_56__pyx_k_57__pyx_k_58__pyx_k_59__pyx_k_60__pyx_k_61__pyx_k_62__pyx_k_63__pyx_k_64__pyx_k_66__pyx_k_69__pyx_k_70__pyx_k_71__pyx_k_72__pyx_k_73__pyx_k_74__pyx_k_75__pyx_k_76__pyx_k_77__pyx_k_78__pyx_k_79__pyx_k_80__pyx_k_81__pyx_doc_6cpyamf_4util_18BufferedByteStream_read_24bit_uint__pyx_doc_6cpyamf_4util_18BufferedByteStream_read_24bit_int__pyx_doc_6cpyamf_4util_18BufferedByteStream_write_24bit_uint__pyx_doc_6cpyamf_4util_18BufferedByteStream_write_24bit_int__pyx_doc_6cpyamf_4util_18BufferedByteStream_consume_GLOBAL_OFFSET_TABLE___dso_handle__DTOR_END___DYNAMICPyDict_SetItemStringPyString_InternFromString_Py_ZeroStructPyString_AsStringPyFrame_NewPyClass_TypePyType_ReadyPyInt_AsUnsignedLongMaskPyInstance_TypePyLong_FromUnsignedLongPyMem_Free__gmon_start___Jv_RegisterClassesPyCObject_FromVoidPtr_PyString_Eq_finiPyObject_CallFunctionObjArgsPyObject_IsTruePyExc_TypeErrorPyObject_HasAttrPyInt_TypePyString_FromStringAndSizePyDict_NextPyImport_AddModulePyUnicodeUCS2_DecodeUTF8PyCObject_ImportPyUnicodeUCS2_AsUTF8StringPyErr_FormatPyFloat_FromDouble_PyFloat_Unpack4PyCode_NewPyObject_GetAttrPyErr_Occurred_PyFloat_Unpack8initutilPyFloat_Type__cxa_finalize@@GLIBC_2.2.5PyErr_SetObjectPyErr_WriteUnraisablePyUnicode_Type_Py_TrueStructPyString_FromStringPyString_FromFormatPyInt_FromLongPyLong_FromStringPyDict_SizePyModule_GetDictPyDict_GetItemPyInt_AsLongPyObject_RichComparePyType_IsSubtype_PyFloat_Pack4memcpy@@GLIBC_2.2.5_PyFloat_Pack8PyTraceBack_TypePyString_AsEncodedObjectPyFloat_AsDoublePyObject_GetAttrString__bss_startPyObject_IsInstancePyObject_SetAttrString_Py_NoneStructPyExc_OverflowErrorPyObject_SetAttrPyObject_CallPyTraceBack_Here_PyThreadState_Current__pyx_type_6cpyamf_4util_BufferedByteStreamPyExc_NameErrorPy_InitModule4PyString_AsStringAndSize_endPyTuple_NewPyExc_NotImplementedErrorPyErr_SetStringPyString_Type_edataPyList_NewPyMem_MallocPyDict_SetItem_initPyDict_NewPKĩ:pAcpyamf/amf3.soELF>@@8@&#4.4. 00 0 ` 0000 00 PtdX-X-X-,,Qtd%3 '# *)%.1 2+!,-(0& $/"- A@ -/2|CE쀇sqX d + d),S"\?MrS~<9s 5 `5  `5   X+__gmon_start___init_fini__cxa_finalize_Jv_RegisterClassesPyString_FromStringPyModule_GetDictPyString_FromStringAndSizePyCode_New_PyThreadState_CurrentPyFrame_NewPyTraceBack_HerePyString_FromFormatinitamf3PyTuple_NewPyString_InternFromStringPyUnicodeUCS2_DecodeUTF8Py_InitModule4PyImport_AddModulePyObject_SetAttrStringPyObject_GetAttr_Py_ZeroStructPyExc_NameErrorPyErr_SetObjectPyInt_TypePyInt_AsLongPyMem_MallocPyMem_FreePyObject_Call_Py_NoneStructPyClass_TypePyInstance_TypePyExc_TypeErrorPyErr_SetStringPyErr_OccurredPyErr_FormatPyExc_OverflowErrorPyInt_FromLongPyErr_WriteUnraisablePyDict_SizePyDict_GetItemPyDict_NextPyString_Type_PyString_EqPyType_IsSubtypePyString_AsStringlibpthread.so.0libc.so.6_edata__bss_start_endGLIBC_2.2.5ui  (0 ,`3 `3 4 +4  4 +(4 `4 5 h4 5 x4  ,4 5 4 3 4 5 4 3 4 5 4 3 4 5 4 3 5 5 5 3 5 5 (5 3 1 1 1 1  1  1  2  2 2 "2 # 2 &(2 '02 +P2 X2 `2 h2 p2  x2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3  3 !3 $ 3 %(3 (03 )83 *@3 ,HH5 % @% h% h% h% h% h%z h%r h%j hp%b h`%Z h P%R h @%J h 0%B h %: h %2 h%* h%" h% h% h% h% h% h% h% hp% h`% hP% h@% h0% h % h% hHH= HtHÐU=! HATSubH=0 t H= H+ L% Hm! L)HHXH9s DHBHM! AHB! H9r.! [A\fUH= Ht"H HtH= IAÐH\$Lt$HHl$Ld$Ll$L|$HxH= HIk HIMH= HI}H=t111HIt}L x HD$81ɋs 111MLl$(Lt$ LL$1ۉD$0LL$LL$L $HHt0HH 1LH8SHHt H߉C|AAMtAEAEMtA$A$HtEEHt>u3HCHHl$PH\$HLd$XLl$`Lt$hLX(L|$pHxAH\$HHl$PLd$XLl$`Lt$hL|$pHxDH H= 1HPIMkAE111ۃAIFLP(DHEHP(D0IELP(DID$LP(Dff.U1SHkHH H-l H] H HHN *@H{gHEHH8tAH H+H{t{tV{fuHsH{vHEHH8uH H  H HsH{1҃VHEjDH H5 H=1AVHHt H=WHH] H=H H5@HxMHv H=/ HHH_ HX  H H[]DH  H  H H=H= tBH H[]H H b H fHGP(Hq HT " HK fH HH8H5 HR H   H H H  H DATH' USH9FkHHHH?AHfDHH?jHfDD3H1ɉ؃D HHHHTHڅu HCHP(H[]HA\fDHHHHHȀAEHHȀBDADHHȀ@HDBDHvT EDH H@cHHDHk 1HރH\ HCH=I HHYH=b EBHEH; ҉H; 7H H59H8EEttEEH Ho a= Hf H=W:[1]HA\H^HGP(HED_HEHP(DwHDHHž1E1HHž1E1 DHEHP(HCHߐP(DHUHH HHxHHXPL`XHPHHHPH@XHt tXHt t0MA$A$ID$LP(p@HCHߐP(DfDHG@P(DfDHHfMHBH H= H _e H i1|fH Hd e2 5H[ HW H: a H1 H- H a H HCHP(fH\$Hl$HLd$Ll$HLt$L|$HHVH=z H L T H A$LOH EH H5{ HOH AH81H; H k H H=L 1H\$hHl$pLd$xL$L$L$HĘH~ L{H! H9GHHcAH90H H5 H8bMHA! fDH5 LHIH5> 1HHHA$A$H~ H9SHtDL9Hn H5w H8HAfDt]1@xhHL HH H lT H} cfHCHߐP(1@yH5g LHHH5 1HHIWH ` I9L$MLUAH9&HO H5X H8HA5@A$A$EA HIHfDID$LP(H H9SHHCDL9L<yU@HW@|H, H L CH H H=M HL`HLhPLpXH@HH@PH@XIHHxHHXPHhXL`HLhPLpXHtHtHtEEu HEHP(MLQA1AIGLP(1H6 HH L FH  HCHP(fHG@P(D1HCHߐP(D-HCHߐP(DID$LP(DH5 L)HH:H5N 1HHIH I9D$LHˆT$ H9H} H5H8HD$ dA$A$uH\$ HL!H ŀ|$ H5 LTHHeH5y 1HHI>yH I9T$ZLAH9H H5H8HA$A$,L$ HHH HH *HHD?AHHEfD<ID$HCHߐP(DJIT$WH= \1DID$LP(DvDRf5HDSAH HD$0HD$8SXFVH5 H/HHD$0AECH5 HHHcCHY HL$0Ll$HLt$PL|$\HD$PHD$HD$\HL$L$LLLHI$HHt$PH90Luf.H91DrHH HuH~H H9H L@HHHH8G;FuHt$PfDHC HD$8HCHD$0SEL|$0H|$8Hk HN G HE :HA H$ G H A$A$ID$LP(ID$HCH@P(DoID$LP(DAf~LHY HL$H)HD$HHHH Hc L1 KHZ :HV H9 l H0 Ht$PHD$8AH H G H SQHt$PH I9H H~ H8H9t$G;FHI9HH8H9uH HO$HH59H81Hp HS k! HJ 0HtVI$Ht$P9H;9H HD$HHL$H)HHN^n~.>N^n~`3 Python C-extensions for L{PyAMF}. @since: 0.4 nstreamsignread_ucharOverflowErrorOut of range++5 5 ,5 3 5 3 5 3 5 3 5 3 5 3 GCC: (Debian 4.3.3-5) 4.3.3GCC: (Debian 4.3.2-4) 4.3.3 20090119 (prerelease)GCC: (Debian 4.3.2-4) 4.3.3 20090119 (prerelease)GCC: (Debian 4.3.2-4) 4.3.3 20090119 (prerelease)GCC: (Debian 4.3.3-5) 4.3.3L X+,<(a++(initamf3/home/aurel32/debian/co-packages/glibc/glibc-2.9/build-tree/amd64-libc/csu/crti.S/home/aurel32/debian/co-packages/glibc/glibc-2.9/csuGNU AS 2.19.1'('m+$8Iint Ci^i1{-o b# # # # +# #( #0 = #8 #@ #H #P  #X "#` V$#h (&b#p *b#t p ,p#x ]0F# 1T# 2# W6# t ?{# H# I# J# K# L-# Nb# P# X X# # .b#v  o  b  7wKfE gb# Wg7#? xg7 b# W7# b# # b# lb#$ t #(  #0  #8  #@ ) #H 4 #P #X #` #h o ? #p !  #x  4 #   #  # )%# ^ i# # # # !` # |$i# ( # ) # ,q#  -# .%# /7# C0i# 1 # 2 # z3i# 4 # r5 # F6 # }7W # 8# 9i# :i# ;i# B<i# =i# >t #E h~SYiii=*ziiiiiii5 bix bii3ib>Di^ibbiobibibibbi6biiibibC +1bFiQWbqibqLbiibi% bi0" o# o# o# lo# o# .o#( #0 XH#8 H#@ H#H #P H#X o#` {o#h o#p o#x zo# # H# H# tH# H#  H# o# o# 0o# Do# Wo# #  o# o# o# H o# o# o# Eo# Io# ]o# P M# o#  #  # 3# D^#( t̉#0 w#8 o#@   #HZ-  # o# ֹ#K   L | # #  # F# b h t    i`  b i bn  i iNz4   b iiaS J P i` ik q i iib S9S :  i 7ii$  i7b"   L v ,q d"# #*# $b# %#+ - (# Z)b# u *b# +b#doc,#w(.%  #get #set 4#doc # g # !GEF q  b# W 7#  i# >( #  $b# W $7# $b# %i# % &b# F '#$   b# W 7# b#  # i* ) z@   b# W 7# i# W i#  i# w i#(  i#0  i#83 5(   b# W 7#  # i# i#  i4iS ?Eb_ii_isH Y# '# i# +i# Ci# i#( (i#0 | i#8 [b#@__ts ' Y3'# 34#  6h# ]7b# 8b# 9b# *;8#( " <8#0 =i#8 ^ >i#@ T@i#H 9Ai#P Bi#X :Di#` fEi#h Fi#p Z Hi#x o Jb# Kb# Mi# Ni#!_g)CIbhihbin   b# W7# b# Qh# B# Ai#( i#0 i#8 #@ #H K i#P 8i#X di#` i#h g #p b#x "b#| #b# %b# &# 'b# (b# )b# *b# +#-R b [p#s#ni# # ,# 3#( )b# 4*b#p {  b# W 7# p b# (b# b# b# i# i#(  i#0 i#8 ci#@ i#H :i#P i#X b#` i#h   X b#  b#  b#S {  ,n~B @ Ai!JZ!j!tb!i "223i3ii3ictx4i2& =! bt[!& iZ iii";!b3# ! ba#  RM Nb OPQ S TT!HbxHiyJivalKb!Wi$xWi!;JJiKJxKLiMxN?OPJ Qb#pj## ##K#`#x###$_H%H9& Ii&Ji&RKi'&5Lip&_ M& N'bad(KhJ i) )#,*P+,#-./"-3+@,E-p+0rZijitbi#t ZijitbioiPi ii 1!i*_%i%i2&iK&xi&iJ b&T is&i))d# R#")W|**$+B6+P N Z0f r0~2  22&22622,2,2h-hv+023"4"006 0 0 !\ qb"kil"minolpkeyrijriposst"u"##j'bad#A!x i i ebbi?iJ iT i?b# ####X d p | 2& =f!J  ?Y x iyival?1fi+$ i$%fi] %fi %fi &gi &ehi &ii=jf&J kbs&T li5miP)))d) #6af!{o4f0"  *p!+0E *(e#F:+P R ^0j0v 00}  2k#,,,2 *J#X+0 d p |0* 5"2&+0=-;+ 0)000v*" PK=#4 +0?  K -" 4 +0?  K 7 R$&r5si$*_` ;$}q+ 00500Q 2*2*,2 *3*1*+@ &ji)5ny$ `4 iy$  $ 8b t5 8i 5 8i 5 8]i 5 8Kb 5 8b p5 8 % (0 8  5 8Pq 5 8Z 3 50.i x5 % 5Z4v% 3 5@ 5i 5 % 5K6% 3 57i 5 % 5,8% 3 59i 5 :& 5:*& 3 5d ;i 5 v& 52 <f& 3 5h=i 5 5>i 5 5i ?i 5 & 5 @& 3 +' 5V& 4 [*' 5:' 4 P' 55@' x4 939:3y=9 +9q9q9.  +9 /+98 &+9: &+9 +9/ ,i9-i96i9 hp /home/aurel32/debian/co-packages/glibc/glibc-2.9/build-tree/amd64-libc/csu/crtn.S/home/aurel32/debian/co-packages/glibc/glibc-2.9/csuGNU AS 2.19.1U%% : ; I$ > $ > $ >   I : ;  : ;I8 : ; : ; I8 I !I/ &I : ; ' II : ;  : ; '  : ; : ; I8 : ;I : ; .: ;' : ;I: ;I4: ;I4: ;I 1 41!.: ;' I ".: ;' # : ;$.: ;' @%: ;I&4: ;I' : ;(.? : ;' @) : ;*1UX Y+ U, 1-1UX Y.1/1X Y0411.: ;' I@2 131X Y4 54: ;I 61X Y7 U84: ; I 94: ; I? < :4: ;I? < U%h /home/aurel32/debian/co-packages/glibc/glibc-2.9/build-tree/amd64-libc/csucrti.S  Ku=/0K K X+$ cpyamf/usr/lib/gcc/x86_64-linux-gnu/4.3.3/include/usr/include/bits/usr/include/usr/local/include/python2.3amf3.cstddef.htypes.hstdio.hlibio.hobject.hmethodobject.hstructmember.hdescrobject.hintobject.hstringobject.htupleobject.hclassobject.hpystate.htraceback.hframeobject.hcompile.hboolobject.hlongobject.hpyerrors.h   %8@g ֱ;=hF\8@/#,].fm<;ugNt~tqt>t](Wt!0d*~ 4Jm}/.yt.yJz$ <  .@zw< <wJ <iX };txT=vptJw X|6%y 5t|tyt~')tKfKKKKK0sNt|Np;]**;%' +;u  u< u J~J %R7KJ;=zX|.I/xX tfy@| #t;=xXxfm.g<JLI/xw%tkt=KKLL p 9 @p!@pW(O!(O!(OW@pW@p X (5x27*` f  + (5x27*` f 3 X 9  9 7 xDx,l'D`x[d| a+f+.symtab.strtab.shstrtab.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rela.dyn.rela.plt.init.text.fini.rodata.eh_frame_hdr.eh_frame.ctors.dtors.jcr.data.rel.ro.dynamic.got.got.plt.data.bss.comment.debug_aranges.debug_pubnames.debug_info.debug_abbrev.debug_line.debug_frame.debug_str.debug_loc.debug_rangesXXho<% -5o fBoH H Qh h 0[ e`kqX+X+w2h+h+X-X-,--0 00 0 0 0(0 (000 001 1h82 82`3 `3 `5 `5`5@677) `c'j40k?"J `X8 %W X H h     X+ h+X--0 0  0 (0 00 1 82 `3 `5  !"  '0 50 C 0 P f`5 uh5  @0 0. 0  + e5 p5 5  5 5 *(0 84 Ix4 Y5 a3 8l4 `z5 5 5 t5 x5  5  \ "5 65 F5 T`4 j5 u3 3 3 3 3 3 82 `3 0 00 !0BN[kv   X+'2CR"n~  `5 *APdr5 `5  initfini.ccall_gmon_startcrtstuff.c__CTOR_LIST____DTOR_LIST____JCR_LIST____do_global_dtors_auxcompleted.6068dtor_idx.6070frame_dummy__CTOR_END____FRAME_END____JCR_END____do_global_ctors_auxamf3.c__Pyx_AddTraceback__pyx_filename__pyx_clineno__pyx_m__pyx_empty_tuple__pyx_lineno__pyx_cfilenm__pyx_string_tab__pyx_filenames__pyx_f__pyx_mdoc__pyx_methods__pyx_b__pyx_kp_OverflowError__pyx_builtin_OverflowError__pyx_skip_dispatch__pyx_k_1__pyx_pf_6cpyamf_4amf3_encode_int__pyx_kp_2__pyx_pf_6cpyamf_4amf3_decode_int__pyx_kp_read_uchar__pyx_kp_stream__pyx_kp_sign__pyx_pyargnames.8724__pyx_kp_n__pyx_k_n__pyx_k_stream__pyx_k_sign__pyx_k_read_uchar__pyx_k_OverflowError__pyx_k_2_GLOBAL_OFFSET_TABLE___dso_handle__DTOR_END___DYNAMICPyString_InternFromString_Py_ZeroStructPyString_AsStringPyFrame_NewPyClass_TypePyInstance_TypePyMem_Free__gmon_start___Jv_RegisterClasses_PyString_Eq_finiPyExc_TypeErrorPyInt_TypePyString_FromStringAndSizePyDict_NextPyImport_AddModulePyUnicodeUCS2_DecodeUTF8PyErr_FormatPyCode_NewPyObject_GetAttrPyErr_Occurred__cxa_finalize@@GLIBC_2.2.5PyErr_SetObjectPyErr_WriteUnraisablePyString_FromStringPyString_FromFormatPyInt_FromLongPyDict_SizePyModule_GetDictPyDict_GetItemPyInt_AsLonginitamf3PyType_IsSubtype__bss_startPyObject_SetAttrString_Py_NoneStructPyExc_OverflowErrorPyObject_CallPyTraceBack_Here_PyThreadState_CurrentPyExc_NameErrorPy_InitModule4_endPyTuple_NewPyErr_SetStringPyString_Type_edataPyMem_Malloc_initPKĩ:K:cpyamf/__init__.pyc; La^Ic@s dZdS(s7 Python C-extensions for L{PyAMF}. @since: 0.4 N(s__doc__(((s/build/bdist.linux-x86_64/egg/cpyamf/__init__.pys?sPKũ:%cpyamf/util.pydef __bootstrap__(): global __bootstrap__, __loader__, __file__ import sys, pkg_resources, imp __file__ = pkg_resources.resource_filename(__name__,'util.so') __loader__ = None; del __bootstrap__, __loader__ imp.load_dynamic(__name__,__file__) __bootstrap__() PKũ:Gcpyamf/amf3.pydef __bootstrap__(): global __bootstrap__, __loader__, __file__ import sys, pkg_resources, imp __file__ = pkg_resources.resource_filename(__name__,'amf3.so') __loader__ = None; del __bootstrap__, __loader__ imp.load_dynamic(__name__,__file__) __bootstrap__() PKũ:0,,cpyamf/util.pyc; Ic@sdatdS(cCsMdk}dk}dk}|itdatabb|i ttdS(Nsutil.so( ssyss pkg_resourcessimpsresource_filenames__name__s__file__sNones __loader__s __bootstrap__s load_dynamic(s pkg_resourcesssyssimp((s+build/bdist.linux-x86_64/egg/cpyamf/util.pys __bootstrap__s  N(s __bootstrap__(((s+build/bdist.linux-x86_64/egg/cpyamf/util.pys?s PKũ:j',,cpyamf/amf3.pyc; Ic@sdatdS(cCsMdk}dk}dk}|itdatabb|i ttdS(Nsamf3.so( ssyss pkg_resourcessimpsresource_filenames__name__s__file__sNones __loader__s __bootstrap__s load_dynamic(s pkg_resourcesssyssimp((s+build/bdist.linux-x86_64/egg/cpyamf/amf3.pys __bootstrap__s  N(s __bootstrap__(((s+build/bdist.linux-x86_64/egg/cpyamf/amf3.pys?s PK":$ pyamf/sol.py# -*- coding: utf-8 -*- # # Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Local Shared Object implementation. Local Shared Object (LSO), sometimes known as flash cookies, is a cookie-like data entity used by the Flash Player and Gnash. The players allow web content to read and write LSO data to the computer's local drive on a per-domain basis. @see: U{Local Shared Object on WikiPedia (external) } @see: U{Local Shared Object envelope (external) } @since: 0.1.0 """ import pyamf from pyamf import util #: Magic Number - 2 bytes HEADER_VERSION = '\x00\xbf' #: Marker - 10 bytes HEADER_SIGNATURE = 'TCSO\x00\x04\x00\x00\x00\x00' #: Padding - 4 bytes PADDING_BYTE = '\x00' def decode(stream, strict=True): """ Decodes a SOL stream. C{strict} mode ensures that the sol stream is as spec compatible as possible. @param strict: Ensure that the SOL stream is as spec compatible as possible. @type strict: C{bool} @return: A C{tuple} containing the C{root_name} and a C{dict} of name, value pairs. @rtype: C{tuple} @raise DecodeError: Unknown SOL version in header. @raise DecodeError: Inconsistent stream header length. @raise DecodeError: Invalid signature. @raise DecodeError: Invalid padding read. @raise DecodeError: Missing padding byte. """ if not isinstance(stream, util.BufferedByteStream): stream = util.BufferedByteStream(stream) # read the version version = stream.read(2) if version != HEADER_VERSION: raise pyamf.DecodeError('Unknown SOL version in header') # read the length length = stream.read_ulong() if strict and stream.remaining() != length: raise pyamf.DecodeError('Inconsistent stream header length') # read the signature signature = stream.read(10) if signature != HEADER_SIGNATURE: raise pyamf.DecodeError('Invalid signature') length = stream.read_ushort() root_name = stream.read_utf8_string(length) # read padding if stream.read(3) != PADDING_BYTE * 3: raise pyamf.DecodeError('Invalid padding read') decoder = pyamf.get_decoder(stream.read_uchar()) decoder.stream = stream values = {} while 1: if stream.at_eof(): break name = decoder.readString() value = decoder.readElement() # read the padding if stream.read(1) != PADDING_BYTE: raise pyamf.DecodeError('Missing padding byte') values[name] = value return (root_name, values) def encode(name, values, strict=True, encoding=pyamf.AMF0): """ Produces a SharedObject encoded stream based on the name and values. @param name: The root name of the SharedObject. @type name: C{basestring} @param values: A C{dict} of name value pairs to be encoded in the stream. @type values: C{dict} @param strict: Ensure that the SOL stream is as spec compatible as possible. @type strict: C{bool} @return: A SharedObject encoded stream. @rtype: L{BufferedByteStream} """ encoder = pyamf.get_encoder(encoding) encoder.stream = stream = util.BufferedByteStream() # write the header stream.write(HEADER_VERSION) if strict is True: length_pos = stream.tell() stream.write_ulong(0) # write the signature stream.write(HEADER_SIGNATURE) # write the root name if not isinstance(name, unicode): name = unicode(name) stream.write_ushort(len(name)) stream.write_utf8_string(name) # write the padding stream.write(PADDING_BYTE * 3) stream.write_uchar(encoding) for n, v in values.iteritems(): encoder._writeString(n) encoder.writeElement(v) # write the padding stream.write(PADDING_BYTE) if strict: stream.seek(length_pos) stream.write_ulong(stream.remaining() - 4) stream.seek(0) return stream def load(name_or_file): """ Loads a sol file and returns a L{SOL} object. @param name_or_file: Name of file, or file-object. @type name_or_file: C{str} or C{StringIO} @raise ValueError: Readable stream expected. """ f = name_or_file opened = False if isinstance(name_or_file, basestring): f = open(name_or_file, 'rb') opened = True elif not hasattr(f, 'read'): raise ValueError('Readable stream expected') name, values = decode(f.read()) s = SOL(name) for n, v in values.iteritems(): s[n] = v if opened is True: f.close() return s def save(sol, name_or_file, encoding=pyamf.AMF0): """ Writes a L{SOL} object to C{name_or_file}. @param sol: @type sol: @param name_or_file: Name of file, or file-object. @type name_or_file: C{str} or C{StringIO} @param encoding: AMF encoding type. @type encoding: C{int} @raise ValueError: Writable stream expected. """ f = name_or_file opened = False if isinstance(name_or_file, basestring): f = open(name_or_file, 'wb+') opened = True elif not hasattr(f, 'write'): raise ValueError('Writable stream expected') f.write(encode(sol.name, sol, encoding=encoding).getvalue()) if opened: f.close() class SOL(dict): """ Local Shared Object class, allows easy manipulation of the internals of a C{sol} file. """ def __init__(self, name): self.name = name def save(self, name_or_file, encoding=pyamf.AMF0): save(self, name_or_file, encoding) def __repr__(self): return '<%s %s %s at 0x%x>' % (self.__class__.__name__, self.name, dict.__repr__(self), id(self)) LSO = SOL PKݥ:![d՟՟pyamf/__init__.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ B{PyAMF} provides B{A}ction B{M}essage B{F}ormat (U{AMF}) support for Python that is compatible with the U{Flash Player}. @copyright: Copyright (c) 2007-2009 The PyAMF Project. All Rights Reserved. @contact: U{dev@pyamf.org} @see: U{http://pyamf.org} @since: October 2007 @version: 0.4.2 @status: Production/Stable """ import types from pyamf import util from pyamf.adapters import register_adapters __all__ = [ 'register_class', 'register_class_loader', 'encode', 'decode', '__version__' ] #: PyAMF version number. __version__ = (0, 4, 2) #: Class mapping support. CLASS_CACHE = {} #: Class loaders. CLASS_LOADERS = [] #: Custom type map. TYPE_MAP = {} #: Maps error classes to string codes. ERROR_CLASS_MAP = {} #: Alias mapping support ALIAS_TYPES = {} #: Specifies that objects are serialized using AMF for ActionScript 1.0 and 2.0. AMF0 = 0 #: Specifies that objects are serialized using AMF for ActionScript 3.0. AMF3 = 3 #: Supported AMF encoding types. ENCODING_TYPES = (AMF0, AMF3) class ClientTypes: """ Typecodes used to identify AMF clients and servers. @see: U{Flash Player on WikiPedia (external) } @see: U{Flash Media Server on WikiPedia (external) } """ #: Specifies a Flash Player 6.0 - 8.0 client. Flash6 = 0 #: Specifies a FlashCom / Flash Media Server client. FlashCom = 1 #: Specifies a Flash Player 9.0 client. Flash9 = 3 #: List of AMF client typecodes. CLIENT_TYPES = [] for x in ClientTypes.__dict__: if not x.startswith('_'): CLIENT_TYPES.append(ClientTypes.__dict__[x]) del x class UndefinedType(object): def __repr__(self): return 'pyamf.Undefined' #: Represents the C{undefined} value in a Flash client. Undefined = UndefinedType() class BaseError(Exception): """ Base AMF Error. All AMF related errors should be subclassed from this class. """ class DecodeError(BaseError): """ Raised if there is an error in decoding an AMF data stream. """ class EOStream(BaseError): """ Raised if the data stream has come to a natural end. """ class ReferenceError(BaseError): """ Raised if an AMF data stream refers to a non-existent object or string reference. """ class EncodeError(BaseError): """ Raised if the element could not be encoded to the stream. @bug: See U{Docuverse blog (external) } for more info about the empty key string array bug. """ class UnknownClassAlias(BaseError): """ Raised if the AMF stream specifies a class that does not have an alias. @see: L{register_class} """ class BaseContext(object): """ I hold the AMF context for en/decoding streams. """ def __init__(self): self.objects = util.IndexedCollection() self.clear() def clear(self): """ Completely clears the context. """ self.objects.clear() self.class_aliases = {} def reset(self): """ Resets the context. This is subtly different to the L{BaseContext.clear} method, which is a hard delete of the context. This method is mainly used by the L{remoting api} to handle context clearing between requests. """ self.objects.clear() self.class_aliases = {} def getObject(self, ref): """ Gets an object based on a reference. @raise ReferenceError: Unknown object reference. """ try: return self.objects.getByReference(ref) except ReferenceError: raise ReferenceError("Unknown object reference %r" % (ref,)) def getObjectReference(self, obj): """ Gets a reference for an object. @raise ReferenceError: Object not a valid reference, """ try: return self.objects.getReferenceTo(obj) except ReferenceError: raise ReferenceError("Object %r not a valid reference" % (obj,)) def addObject(self, obj): """ Adds a reference to C{obj}. @type obj: C{mixed} @param obj: The object to add to the context. @rtype: C{int} @return: Reference to C{obj}. """ return self.objects.append(obj) def getClassAlias(self, klass): """ Gets a class alias based on the supplied C{klass}. """ if klass not in self.class_aliases.keys(): try: self.class_aliases[klass] = get_class_alias(klass) except UnknownClassAlias: # no alias has been found yet .. check subclasses alias = util.get_class_alias(klass) if alias is not None: self.class_aliases[klass] = alias(klass, None) else: self.class_aliases[klass] = None return self.class_aliases[klass] def __copy__(self): raise NotImplementedError class ASObject(dict): """ This class represents a Flash Actionscript Object (typed or untyped). I supply a C{__builtin__.dict} interface to support C{get}/C{setattr} calls. @raise AttributeError: Unknown attribute. """ def __init__(self, *args, **kwargs): dict.__init__(self, *args, **kwargs) def __getattr__(self, k): try: return self[k] except KeyError: raise AttributeError('Unknown attribute \'%s\'' % (k,)) def __setattr__(self, k, v): self[k] = v def __repr__(self): return dict.__repr__(self) def __hash__(self): return id(self) class MixedArray(dict): """ Used to be able to specify the C{mixedarray} type. """ class ClassMetaData(list): """ I hold a list of tags relating to the class. The idea behind this is to emulate the metadata tags you can supply to ActionScript, e.g. C{static}/C{dynamic}. """ _allowed_tags = ( ('static', 'dynamic', 'external'), ('amf3', 'amf0'), ('anonymous',), ) def __init__(self, *args): if len(args) == 1 and hasattr(args[0], '__iter__'): for x in args[0]: self.append(x) else: for x in args: self.append(x) def _is_tag_allowed(self, x): for y in self._allowed_tags: if isinstance(y, (types.ListType, types.TupleType)): if x in y: return (True, y) else: if x == y: return (True, None) return (False, None) def append(self, x): """ Adds a tag to the metadata. @param x: Tag. @raise ValueError: Unknown tag. """ x = str(x).lower() allowed, tags = self._is_tag_allowed(x) if not allowed: raise ValueError("Unknown tag %s" % (x,)) if tags is not None: # check to see if a tag in the list is about to be clobbered if so, # raise a warning for y in tags: if y not in self: continue if x != y: import warnings warnings.warn( "Previously defined tag %s superceded by %s" % (y, x)) list.pop(self, self.index(y)) break list.append(self, x) def __contains__(self, other): return list.__contains__(self, str(other).lower()) # TODO nick: deal with slices class ClassAlias(object): """ Class alias. All classes are initially set to a dynamic state. @ivar attrs: A list of attributes to encode for this class. @type attrs: C{list} @ivar metadata: A list of metadata tags similar to ActionScript tags. @type metadata: C{list} """ def __init__(self, klass, alias, attrs=None, attr_func=None, metadata=[]): """ @type klass: C{class} @param klass: The class to alias. @type alias: C{str} @param alias: The alias to the class e.g. C{org.example.Person}. If the value of this is C{None}, then it is worked out based on the C{klass}. The anonymous tag is also added to the class. @type attrs: A list of attributes to encode for this class. @param attrs: C{list} @type metadata: A list of metadata tags similar to ActionScript tags. @param metadata: C{list} @raise TypeError: The C{klass} must be a class type. @raise TypeError: The C{attr_func} must be callable. @raise TypeError: C{__readamf__} must be callable. @raise TypeError: C{__writeamf__} must be callable. @raise AttributeError: An externalised class was specified, but no C{__readamf__} attribute was found. @raise AttributeError: An externalised class was specified, but no C{__writeamf__} attribute was found. @raise ValueError: The C{attrs} keyword must be specified for static classes. """ if not isinstance(klass, (type, types.ClassType)): raise TypeError("klass must be a class type") self.checkClass(klass) self.metadata = ClassMetaData(metadata) if alias is None: self.metadata.append('anonymous') alias = "%s.%s" % (klass.__module__, klass.__name__,) self.klass = klass self.alias = alias self.attr_func = attr_func self.attrs = attrs if 'external' in self.metadata: # class is declared as external, lets check if not hasattr(klass, '__readamf__'): raise AttributeError("An externalised class was specified, but" " no __readamf__ attribute was found for class %s" % ( klass.__name__)) if not hasattr(klass, '__writeamf__'): raise AttributeError("An externalised class was specified, but" " no __writeamf__ attribute was found for class %s" % ( klass.__name__)) if not isinstance(klass.__readamf__, types.UnboundMethodType): raise TypeError("%s.__readamf__ must be callable" % ( klass.__name__)) if not isinstance(klass.__writeamf__, types.UnboundMethodType): raise TypeError("%s.__writeamf__ must be callable" % ( klass.__name__)) if 'dynamic' in self.metadata: if attr_func is not None and not callable(attr_func): raise TypeError("attr_func must be callable") if 'static' in self.metadata: if attrs is None: raise ValueError("attrs keyword must be specified for static classes") def __str__(self): return self.alias def __repr__(self): return '' % ( self.alias, self.klass, id(self)) def __eq__(self, other): if isinstance(other, basestring): return self.alias == other elif isinstance(other, self.__class__): return self.klass == other.klass elif isinstance(other, (type, types.ClassType)): return self.klass == other else: return False def __hash__(self): return id(self) def checkClass(kls, klass): """ This function is used to check the class being aliased to fits certain criteria. The default is to check that the __init__ constructor does not pass in arguments. @since: 0.4 @raise TypeError: C{__init__} doesn't support additional arguments """ # Check that the constructor of the class doesn't require any additonal # arguments. if not (hasattr(klass, '__init__') and hasattr(klass.__init__, 'im_func')): return klass_func = klass.__init__.im_func # built-in classes don't have func_code if hasattr(klass_func, 'func_code') and ( klass_func.func_code.co_argcount - len(klass_func.func_defaults or []) > 1): args = list(klass_func.func_code.co_varnames) values = list(klass_func.func_defaults or []) if not values: sign = "%s.__init__(%s)" % (klass.__name__, ", ".join(args)) else: named_args = zip(args[len(args) - len(values):], values) sign = "%s.__init__(%s, %s)" % ( klass.__name__, ", ".join(args[:0-len(values)]), ", ".join(map(lambda x: "%s=%s" % (x,), named_args))) raise TypeError("__init__ doesn't support additional arguments: %s" % sign) checkClass = classmethod(checkClass) def _getAttrs(self, obj, static_attrs=None, dynamic_attrs=None, traverse=True): if static_attrs is None: static_attrs = [] if dynamic_attrs is None: dynamic_attrs = [] modified_attrs = False if self.attrs is not None: modified_attrs = True static_attrs.extend(self.attrs) elif traverse is True and hasattr(obj, '__slots__'): modified_attrs = True static_attrs.extend(obj.__slots__) if self.attr_func is not None: modified_attrs = True extra_attrs = self.attr_func(obj) dynamic_attrs.extend([key for key in extra_attrs if key not in static_attrs]) if traverse is True: for base in util.get_mro(obj.__class__): try: alias = get_class_alias(base) except UnknownClassAlias: continue x, y = alias._getAttrs(obj, static_attrs, dynamic_attrs, False) if x is not None: static_attrs.extend(x) modified_attrs = True if y is not None: dynamic_attrs.extend(y) modified_attrs = True if modified_attrs is False: return None, None sa = [] da = [] for x in static_attrs: if x not in sa: sa.append(x) for x in dynamic_attrs: if x not in da: da.append(x) return (sa, da) def getAttrs(self, obj, codec=None): """ Returns a tuple of lists, static and dynamic attrs to encode. @param codec: An optional argument that will contain the en/decoder instance calling this function. """ return self._getAttrs(obj) def getAttributes(self, obj, codec=None): """ Returns a collection of attributes for an object. Returns a C{tuple} containing a dict of static and dynamic attributes @param codec: An optional argument that will contain the en/decoder instance calling this function. """ dynamic_attrs = {} static_attrs = {} static_attr_names, dynamic_attr_names = self.getAttrs(obj, codec=codec) if static_attr_names is None and dynamic_attr_names is None: dynamic_attrs = util.get_attrs(obj) if static_attr_names is not None: for attr in static_attr_names: if hasattr(obj, attr): static_attrs[attr] = getattr(obj, attr) else: static_attrs[attr] = Undefined if dynamic_attr_names is not None: for attr in dynamic_attr_names: if attr in static_attrs: continue if hasattr(obj, attr): dynamic_attrs[attr] = getattr(obj, attr) return (static_attrs, dynamic_attrs) def applyAttributes(self, obj, attrs, codec=None): """ Applies the collection of attributes C{attrs} to aliased object C{obj}. It is mainly used when reading aliased objects from an AMF byte stream. @param codec: An optional argument that will contain the en/decoder instance calling this function. """ if 'static' in self.metadata: s, d = self.getAttrs(obj, codec=codec) if s is not None: for k in attrs.keys(): if k not in s: del attrs[k] util.set_attrs(obj, attrs) def createInstance(self, codec=None, *args, **kwargs): """ Creates an instance of the klass. @return: Instance of C{self.klass}. """ return self.klass(*args, **kwargs) class TypedObject(dict): """ This class is used when a strongly typed object is decoded but there is no registered class to apply it to. This object can only be used for 'simple' streams - i.e. not externalized data. If encountered, a L{DecodeError} will be raised. @ivar alias: The alias of the typed object. @type alias: C{unicode} @since: 0.4 """ def __init__(self, alias): dict.__init__(self) self.alias = alias def __readamf__(self, o): raise DecodeError('Unable to decode an externalised stream.\n\nThe ' 'class alias \'%s\' was found and because strict mode is False an' ' attempt was made to decode the object automatically. To decode ' 'this stream, a registered class with the alias and a ' 'corresponding __readamf__ method will be required.' % ( self.alias,)) def __writeamf__(self, o): raise EncodeError('Unable to encode an externalised stream.\n\nThe ' 'class alias \'%s\' was found and because strict mode is False an' 'attempt was made to encode the object automatically. To encode ' 'this stream, a registered class with the alias and a ' 'corresponding __readamf__ method will be required.' % ( self.alias,)) class TypedObjectClassAlias(ClassAlias): """ @since: 0.4 """ def createInstance(self, codec=None): return TypedObject(self.alias) def checkClass(kls, klass): pass class BaseDecoder(object): """ Base AMF decoder. @ivar context_class: The context for the decoding. @type context_class: An instance of C{BaseDecoder.context_class} @ivar type_map: @type type_map: C{list} @ivar stream: The underlying data stream. @type stream: L{BufferedByteStream} @ivar strict: Defines how strict the decoding should be. For the time being this relates to typed objects in the stream that do not have a registered alias. Introduced in 0.4. @type strict: C{bool} """ context_class = BaseContext type_map = {} def __init__(self, data=None, context=None, strict=False): """ @type data: L{BufferedByteStream} @param data: Data stream. @type context: L{Context} @param context: Context. @raise TypeError: The C{context} parameter must be of type L{Context}. """ # coerce data to BufferedByteStream if isinstance(data, util.BufferedByteStream): self.stream = data else: self.stream = util.BufferedByteStream(data) if context == None: self.context = self.context_class() elif isinstance(context, self.context_class): self.context = context else: raise TypeError("context must be of type %s.%s" % ( self.context_class.__module__, self.context_class.__name__)) self.strict = strict def readType(self): """ @raise NotImplementedError: Override in a subclass. """ raise NotImplementedError def readElement(self): """ Reads an AMF3 element from the data stream. @raise DecodeError: The ActionScript type is unsupported. @raise EOStream: No more data left to decode. """ try: type = self.readType() except EOFError: raise EOStream try: func = getattr(self, self.type_map[type]) except KeyError: raise DecodeError("Unsupported ActionScript type 0x%02x" % (type,)) return func() def __iter__(self): """ @raise StopIteration: """ try: while 1: yield self.readElement() except EOFError: raise StopIteration class CustomTypeFunc(object): """ Custom type mappings. """ def __init__(self, encoder, func): self.encoder = encoder self.func = func def __call__(self, data): self.encoder.writeElement(self.func(data, encoder=self.encoder)) class BaseEncoder(object): """ Base AMF encoder. @ivar type_map: A list of types -> functions. The types is a list of possible instances or functions to call (that return a C{bool}) to determine the correct function to call to encode the data. @type type_map: C{list} @ivar context_class: Holds the class that will create context objects for the implementing C{Encoder}. @type context_class: C{type} or C{types.ClassType} @ivar stream: The underlying data stream. @type stream: L{BufferedByteStream} @ivar context: The context for the encoding. @type context: An instance of C{BaseEncoder.context_class} @ivar strict: Whether the encoder should operate in 'strict' mode. Nothing is really affected by this for the time being - its just here for flexibility. @type strict: C{bool}, default is False. """ context_class = BaseContext type_map = [] def __init__(self, data=None, context=None, strict=False): """ @type data: L{BufferedByteStream} @param data: Data stream. @type context: L{Context} @param context: Context. @raise TypeError: The C{context} parameter must be of type L{Context}. """ # coerce data to BufferedByteStream if isinstance(data, util.BufferedByteStream): self.stream = data else: self.stream = util.BufferedByteStream(data) if context == None: self.context = self.context_class() elif isinstance(context, self.context_class): self.context = context else: raise TypeError("context must be of type %s.%s" % ( self.context_class.__module__, self.context_class.__name__)) self._write_elem_func_cache = {} self.strict = strict def writeFunc(self, obj): """ Not possible to encode functions. @raise EncodeError: Unable to encode function/methods. """ raise EncodeError("Unable to encode function/methods") def _getWriteElementFunc(self, data): """ Gets a function used to encode the data. @type data: C{mixed} @param data: Python data. @rtype: callable or C{None}. @return: The function used to encode data to the stream. """ for type_, func in TYPE_MAP.iteritems(): try: if isinstance(data, type_): return CustomTypeFunc(self, func) except TypeError: if callable(type_) and type_(data): return CustomTypeFunc(self, func) for tlist, method in self.type_map: for t in tlist: try: if isinstance(data, t): return getattr(self, method) except TypeError: if callable(t) and t(data): return getattr(self, method) return None def _writeElementFunc(self, data): """ Gets a function used to encode the data. @type data: C{mixed} @param data: Python data. @rtype: callable or C{None}. @return: The function used to encode data to the stream. """ try: key = data.__class__ except AttributeError: return self._getWriteElementFunc(data) if key not in self._write_elem_func_cache: self._write_elem_func_cache[key] = self._getWriteElementFunc(data) return self._write_elem_func_cache[key] def writeElement(self, data): """ Writes the data. Overridden in subclass. @type data: C{mixed} @param data: The data to be encoded to the data stream. """ raise NotImplementedError def register_class(klass, alias=None, attrs=None, attr_func=None, metadata=[]): """ Registers a class to be used in the data streaming. @type alias: C{str} @param alias: The alias of klass, i.e. C{org.example.Person}. @param attrs: A list of attributes that will be encoded for the class. @type attrs: C{list} or C{None} @type attr_func: @param attr_func: @type metadata: @param metadata: @raise TypeError: PyAMF doesn't support required init arguments. @raise TypeError: The C{klass} is not callable. @raise ValueError: The C{klass} or C{alias} is already registered. @return: The registered L{ClassAlias}. """ if not callable(klass): raise TypeError("klass must be callable") if klass in CLASS_CACHE: raise ValueError("klass %s already registered" % (klass,)) if alias is not None and alias in CLASS_CACHE.keys(): raise ValueError("alias '%s' already registered" % (alias,)) alias_klass = util.get_class_alias(klass) if alias_klass is None: alias_klass = ClassAlias x = alias_klass(klass, alias, attr_func=attr_func, attrs=attrs, metadata=metadata) if alias is None: alias = "%s.%s" % (klass.__module__, klass.__name__,) CLASS_CACHE[alias] = x return x def unregister_class(alias): """ Deletes a class from the cache. If C{alias} is a class, the matching alias is found. @type alias: C{class} or C{str} @param alias: Alias for class to delete. @raise UnknownClassAlias: Unknown alias. """ if isinstance(alias, (type, types.ClassType)): for s, a in CLASS_CACHE.iteritems(): if a.klass == alias: alias = s break try: del CLASS_CACHE[alias] except KeyError: raise UnknownClassAlias("Unknown alias %s" % (alias,)) def register_class_loader(loader): """ Registers a loader that is called to provide the C{Class} for a specific alias. The L{loader} is provided with one argument, the C{Class} alias. If the loader succeeds in finding a suitable class then it should return that class, otherwise it should return C{None}. @type loader: C{callable} @raise TypeError: The C{loader} is not callable. @raise ValueError: The C{loader} is already registered. """ if not callable(loader): raise TypeError("loader must be callable") if loader in CLASS_LOADERS: raise ValueError("loader has already been registered") CLASS_LOADERS.append(loader) def unregister_class_loader(loader): """ Unregisters a class loader. @type loader: C{callable} @param loader: The object to be unregistered @raise LookupError: The C{loader} was not registered. """ if loader not in CLASS_LOADERS: raise LookupError("loader not found") del CLASS_LOADERS[CLASS_LOADERS.index(loader)] def get_module(mod_name): """ Load a module based on C{mod_name}. @type mod_name: C{str} @param mod_name: The module name. @return: Module. @raise ImportError: Unable to import an empty module. """ if mod_name is '': raise ImportError("Unable to import empty module") mod = __import__(mod_name) components = mod_name.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod def load_class(alias): """ Finds the class registered to the alias. The search is done in order: 1. Checks if the class name has been registered via L{register_class}. 2. Checks all functions registered via L{register_class_loader}. 3. Attempts to load the class via standard module loading techniques. @type alias: C{str} @param alias: The class name. @raise UnknownClassAlias: The C{alias} was not found. @raise TypeError: Expecting class type or L{ClassAlias} from loader. @return: Class registered to the alias. """ alias = str(alias) # Try the CLASS_CACHE first try: return CLASS_CACHE[alias] except KeyError: pass # Check each CLASS_LOADERS in turn for loader in CLASS_LOADERS: klass = loader(alias) if klass is None: continue if isinstance(klass, (type, types.ClassType)): return register_class(klass, alias) elif isinstance(klass, ClassAlias): CLASS_CACHE[str(alias)] = klass else: raise TypeError("Expecting class type or ClassAlias from loader") return klass # XXX nick: Are there security concerns for loading classes this way? mod_class = alias.split('.') if mod_class: module = '.'.join(mod_class[:-1]) klass = mod_class[-1] try: module = get_module(module) except ImportError, AttributeError: # XXX What to do here? pass else: klass = getattr(module, klass) if callable(klass): CLASS_CACHE[alias] = klass return klass # All available methods for finding the class have been exhausted raise UnknownClassAlias("Unknown alias %s" % (alias,)) def get_class_alias(klass): """ Finds the alias registered to the class. @type klass: C{object} or class @rtype: L{ClassAlias} @return: The class alias linked to the C{klass}. @raise UnknownClassAlias: Class not found. @raise TypeError: Expecting C{string} or C{class} type. """ if not isinstance(klass, (type, types.ClassType, basestring)): if isinstance(klass, types.InstanceType): klass = klass.__class__ elif isinstance(klass, types.ObjectType): klass = type(klass) if isinstance(klass, basestring): for a, k in CLASS_CACHE.iteritems(): if klass == a: return k else: for a, k in CLASS_CACHE.iteritems(): if klass == k.klass: return k if isinstance(klass, basestring): return load_class(klass) raise UnknownClassAlias("Unknown alias %s" % (klass,)) def has_alias(obj): """ @rtype: C{bool} @return: Alias is available. """ try: alias = get_class_alias(obj) return True except UnknownClassAlias: return False def decode(stream, encoding=AMF0, context=None, strict=False): """ A generator function to decode a datastream. @type stream: L{BufferedByteStream} @param stream: AMF data. @type encoding: C{int} @param encoding: AMF encoding type. @type context: L{AMF0 Context} or L{AMF3 Context} @param context: Context. @return: Each element in the stream. """ decoder = _get_decoder_class(encoding)(stream, context, strict) while 1: try: yield decoder.readElement() except EOStream: break def encode(*args, **kwargs): """ A helper function to encode an element. @type element: C{mixed} @keyword element: Python data. @type encoding: C{int} @keyword encoding: AMF encoding type. @type context: L{amf0.Context} or L{amf3.Context} @keyword context: Context. @rtype: C{StringIO} @return: File-like object. """ encoding = kwargs.get('encoding', AMF0) context = kwargs.get('context', None) strict = kwargs.get('strict', False) stream = util.BufferedByteStream() encoder = _get_encoder_class(encoding)(stream, context, strict) for el in args: encoder.writeElement(el) stream.seek(0) return stream def get_decoder(encoding, data=None, context=None, strict=False): return _get_decoder_class(encoding)(data=data, context=context, strict=strict) def _get_decoder_class(encoding): """ Get compatible decoder. @type encoding: C{int} @param encoding: AMF encoding version. @raise ValueError: AMF encoding version is unknown. @rtype: L{amf0.Decoder} or L{amf3.Decoder} @return: AMF0 or AMF3 decoder. """ if encoding == AMF0: from pyamf import amf0 return amf0.Decoder elif encoding == AMF3: from pyamf import amf3 return amf3.Decoder raise ValueError("Unknown encoding %s" % (encoding,)) def get_encoder(encoding, data=None, context=None, strict=False): """ Returns a subclassed instance of L{pyamf.BaseEncoder}, based on C{encoding} """ return _get_encoder_class(encoding)(data=data, context=context, strict=strict) def _get_encoder_class(encoding): """ Get compatible encoder. @type encoding: C{int} @param encoding: AMF encoding version. @raise ValueError: AMF encoding version is unknown. @rtype: L{amf0.Encoder} or L{amf3.Encoder} @return: AMF0 or AMF3 encoder. """ if encoding == AMF0: from pyamf import amf0 return amf0.Encoder elif encoding == AMF3: from pyamf import amf3 return amf3.Encoder raise ValueError("Unknown encoding %s" % (encoding,)) def get_context(encoding): return _get_context_class(encoding)() def _get_context_class(encoding): """ Gets a compatible context class. @type encoding: C{int} @param encoding: AMF encoding version. @raise ValueError: AMF encoding version is unknown. @rtype: L{amf0.Context} or L{amf3.Context} @return: AMF0 or AMF3 context class. """ if encoding == AMF0: from pyamf import amf0 return amf0.Context elif encoding == AMF3: from pyamf import amf3 return amf3.Context raise ValueError("Unknown encoding %s" % (encoding,)) def flex_loader(alias): """ Loader for L{Flex} framework compatibility classes. @raise UnknownClassAlias: Trying to load unknown Flex compatibility class. """ if not alias.startswith('flex.'): return try: if alias.startswith('flex.messaging.messages'): import pyamf.flex.messaging elif alias.startswith('flex.messaging.io'): import pyamf.flex elif alias.startswith('flex.data.messages'): import pyamf.flex.data return CLASS_CACHE[alias] except KeyError: raise UnknownClassAlias(alias) def add_type(type_, func=None): """ Adds a custom type to L{TYPE_MAP}. A custom type allows fine grain control of what to encode to an AMF data stream. @raise TypeError: Unable to add as a custom type (expected a class or callable). @raise KeyError: Type already exists. """ def _check_type(type_): if not (isinstance(type_, (type, types.ClassType)) or callable(type_)): raise TypeError('Unable to add \'%r\' as a custom type (expected a class or callable)' % (type_,)) if isinstance(type_, list): type_ = tuple(type_) if type_ in TYPE_MAP: raise KeyError('Type %r already exists' % (type_,)) if isinstance(type_, types.TupleType): for x in type_: _check_type(x) else: _check_type(type_) TYPE_MAP[type_] = func def get_type(type_): """ Gets the declaration for the corresponding custom type. @raise KeyError: Unknown type. """ if isinstance(type_, list): type_ = tuple(type_) for (k, v) in TYPE_MAP.iteritems(): if k == type_: return v raise KeyError("Unknown type %r" % (type_,)) def remove_type(type_): """ Removes the custom type declaration. @return: Custom type declaration. """ declaration = get_type(type_) del TYPE_MAP[type_] return declaration def add_error_class(klass, code): """ Maps an exception class to a string code. Used to map remoting C{onStatus} objects to an exception class so that an exception can be built to represent that error:: class AuthenticationError(Exception): pass An example: C{add_error_class(AuthenticationError, 'Auth.Failed')} @type code: C{str} @raise TypeError: C{klass} must be a C{class} type. @raise TypeError: Error classes must subclass the C{__builtin__.Exception} class. @raise ValueError: Code is already registered. """ if not isinstance(code, basestring): code = str(code) if not isinstance(klass, (type, types.ClassType)): raise TypeError("klass must be a class type") mro = util.get_mro(klass) if not Exception in mro: raise TypeError('Error classes must subclass the __builtin__.Exception class') if code in ERROR_CLASS_MAP.keys(): raise ValueError('Code %s is already registered' % (code,)) ERROR_CLASS_MAP[code] = klass def remove_error_class(klass): """ Removes a class from C{ERROR_CLASS_MAP}. @raise ValueError: Code is not registered. @raise ValueError: Class is not registered. @raise TypeError: Invalid type, expected C{class} or C{string}. """ if isinstance(klass, basestring): if not klass in ERROR_CLASS_MAP.keys(): raise ValueError('Code %s is not registered' % (klass,)) elif isinstance(klass, (type, types.ClassType)): classes = ERROR_CLASS_MAP.values() if not klass in classes: raise ValueError('Class %s is not registered' % (klass,)) klass = ERROR_CLASS_MAP.keys()[classes.index(klass)] else: raise TypeError("Invalid type, expected class or string") del ERROR_CLASS_MAP[klass] def register_alias_type(klass, *args): """ This function allows you to map subclasses of L{ClassAlias} to classes listed in C{args}. When an object is read/written from/to the AMF stream, a paired L{ClassAlias} instance is created (or reused), based on the Python class of that object. L{ClassAlias} provides important metadata for the class and can also control how the equivalent Python object is created, how the attributes are applied etc. Use this function if you need to do something non-standard. @see: L{pyamf.adapters._google_appengine_ext_db.DataStoreClassAlias} for a good example. @since: 0.4 @raise RuntimeError: Type is already registered. @raise TypeError: C{klass} must be a class. @raise ValueError: New aliases must subclass L{pyamf.ClassAlias}. @raise ValueError: At least one type must be supplied. """ def check_type_registered(arg): # FIXME: Create a reverse index of registered types and do a quicker lookup for k, v in ALIAS_TYPES.iteritems(): for kl in v: if arg is kl: raise RuntimeError('%r is already registered under %r' % (arg, k)) if not isinstance(klass, (type, types.ClassType)): raise TypeError('klass must be class') if not issubclass(klass, ClassAlias): raise ValueError('New aliases must subclass pyamf.ClassAlias') if len(args) == 0: raise ValueError('At least one type must be supplied') if len(args) == 1 and callable(args[0]): c = args[0] check_type_registered(c) else: for arg in args: if not isinstance(arg, (type, types.ClassType)): raise TypeError('%r must be class' % (arg,)) check_type_registered(arg) ALIAS_TYPES[klass] = args register_class_loader(flex_loader) register_adapters() register_alias_type(TypedObjectClassAlias, TypedObject) PKS:dfnn pyamf/amf0.py# -*- coding: utf-8 -*- # # Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ AMF0 implementation. C{AMF0} supports the basic data types used for the NetConnection, NetStream, LocalConnection, SharedObjects and other classes in the Flash Player. @see: U{Official AMF0 Specification in English (external) } @see: U{Official AMF0 Specification in Japanese (external) } @see: U{AMF documentation on OSFlash (external) } @since: 0.1.0 """ import datetime, types import copy import pyamf from pyamf import util class ASTypes: """ The AMF/RTMP data encoding format constants. @see: U{Data types on OSFlash (external) } """ #: Represented as 9 bytes: 1 byte for C{0×00} and 8 bytes a double #: representing the value of the number. NUMBER = 0x00 #: Represented as 2 bytes: 1 byte for C{0×01} and a second, C{0×00} #: for C{False}, C{0×01} for C{True}. BOOL = 0x01 #: Represented as 3 bytes + len(String): 1 byte C{0×02}, then a UTF8 string, #: including the top two bytes representing string length as a C{int}. STRING = 0x02 #: Represented as 1 byte, C{0×03}, then pairs of UTF8 string, the key, and #: an AMF element, ended by three bytes, C{0×00} C{0×00} C{0×09}. OBJECT = 0x03 #: MovieClip does not seem to be supported by Remoting. #: It may be used by other AMF clients such as SharedObjects. MOVIECLIP = 0x04 #: 1 single byte, C{0×05} indicates null. NULL = 0x05 #: 1 single byte, C{0×06} indicates null. UNDEFINED = 0x06 #: When an ActionScript object refers to itself, such C{this.self = this}, #: or when objects are repeated within the same scope (for example, as the #: two parameters of the same function called), a code of C{0×07} and an #: C{int}, the reference number, are written. REFERENCE = 0x07 #: A MixedArray is indicated by code C{0×08}, then a Long representing the #: highest numeric index in the array, or 0 if there are none or they are #: all negative. After that follow the elements in key : value pairs. MIXEDARRAY = 0x08 #: @see: L{OBJECT} OBJECTTERM = 0x09 #: An array is indicated by C{0x0A}, then a Long for array length, then the #: array elements themselves. Arrays are always sparse; values for #: inexistant keys are set to null (C{0×06}) to maintain sparsity. ARRAY = 0x0a #: Date is represented as C{00x0B}, then a double, then an C{int}. The double #: represents the number of milliseconds since 01/01/1970. The C{int} represents #: the timezone offset in minutes between GMT. Note for the latter than values #: greater than 720 (12 hours) are represented as M{2^16} - the value. Thus GMT+1 #: is 60 while GMT-5 is 65236. DATE = 0x0b #: LongString is reserved for strings larger then M{2^16} characters long. It #: is represented as C{00x0C} then a LongUTF. LONGSTRING = 0x0c #: Trying to send values which don’t make sense, such as prototypes, functions, #: built-in objects, etc. will be indicated by a single C{00x0D} byte. UNSUPPORTED = 0x0d #: Remoting Server -> Client only. #: @see: L{RecordSet} #: @see: U{RecordSet structure on OSFlash (external) #: } RECORDSET = 0x0e #: The XML element is indicated by C{00x0F} and followed by a LongUTF containing #: the string representation of the XML object. The receiving gateway may which #: to wrap this string inside a language-specific standard XML object, or simply #: pass as a string. XML = 0x0f #: A typed object is indicated by C{0×10}, then a UTF string indicating class #: name, and then the same structure as a normal C{0×03} Object. The receiving #: gateway may use a mapping scheme, or send back as a vanilla object or #: associative array. TYPEDOBJECT = 0x10 #: An AMF message sent from an AVM+ client such as the Flash Player 9 may break #: out into L{AMF3} mode. In this case the next byte will be the #: AMF3 type code and the data will be in AMF3 format until the decoded object #: reaches it’s logical conclusion (for example, an object has no more keys). AMF3 = 0x11 #: List of available ActionScript types in AMF0. ACTIONSCRIPT_TYPES = [] for x in ASTypes.__dict__: if not x.startswith('_'): ACTIONSCRIPT_TYPES.append(ASTypes.__dict__[x]) del x class Context(pyamf.BaseContext): """ I hold the AMF0 context for en/decoding streams. AMF0 object references start at index 1. @ivar amf3_objs: A list of objects that have been decoded in L{AMF3}. @type amf3_objs: L{util.IndexedCollection} """ def __init__(self): self.amf3_objs = util.IndexedCollection() pyamf.BaseContext.__init__(self) def clear(self): """ Clears the context. """ pyamf.BaseContext.clear(self) self.amf3_objs.clear() if hasattr(self, 'amf3_context'): self.amf3_context.clear() def reset(self): """ Resets the context. @see: L{pyamf.BaseContext.reset} """ pyamf.BaseContext.reset(self) if hasattr(self, 'amf3_context'): self.amf3_context.reset() def getAMF3ObjectReference(self, obj): """ Gets a reference for an object. @raise ReferenceError: Object reference could not be found. """ try: return self.amf3_objs.getReferenceTo(obj) except KeyError: raise ReferenceError def addAMF3Object(self, obj): """ Adds an AMF3 reference to C{obj}. @type obj: C{mixed} @param obj: The object to add to the context. @rtype: C{int} @return: Reference to C{obj}. """ return self.amf3_objs.append(obj) def __copy__(self): cpy = self.__class__() cpy.amf3_objs = copy.copy(self.amf3_objs) return cpy class Decoder(pyamf.BaseDecoder): """ Decodes an AMF0 stream. """ context_class = Context # XXX nick: Do we need to support ASTypes.MOVIECLIP here? type_map = { ASTypes.NUMBER: 'readNumber', ASTypes.BOOL: 'readBoolean', ASTypes.STRING: 'readString', ASTypes.OBJECT: 'readObject', ASTypes.NULL: 'readNull', ASTypes.UNDEFINED: 'readUndefined', ASTypes.REFERENCE: 'readReference', ASTypes.MIXEDARRAY: 'readMixedArray', ASTypes.ARRAY: 'readList', ASTypes.DATE: 'readDate', ASTypes.LONGSTRING: 'readLongString', # TODO: do we need a special value here? ASTypes.UNSUPPORTED:'readNull', ASTypes.XML: 'readXML', ASTypes.TYPEDOBJECT:'readTypedObject', ASTypes.AMF3: 'readAMF3' } def readType(self): """ Read and returns the next byte in the stream and determine its type. @raise DecodeError: AMF0 type not recognized. @return: AMF0 type. """ type = self.stream.read_uchar() if type not in ACTIONSCRIPT_TYPES: raise pyamf.DecodeError("Unknown AMF0 type 0x%02x at %d" % ( type, self.stream.tell() - 1)) return type def readNumber(self): """ Reads a ActionScript C{Number} value. In ActionScript 1 and 2 the C{NumberASTypes} type represents all numbers, both floats and integers. @rtype: C{int} or C{float} """ return _check_for_int(self.stream.read_double()) def readBoolean(self): """ Reads a ActionScript C{Boolean} value. @rtype: C{bool} @return: Boolean. """ return bool(self.stream.read_uchar()) def readNull(self): """ Reads a ActionScript C{null} value. @return: C{None} @rtype: C{None} """ return None def readUndefined(self): """ Reads an ActionScript C{undefined} value. @return: L{Undefined} """ return pyamf.Undefined def readMixedArray(self): """ Read mixed array. @rtype: C{dict} @return: C{dict} read from the stream """ len = self.stream.read_ulong() obj = pyamf.MixedArray() self.context.addObject(obj) self._readObject(obj) ikeys = [] for key in obj.keys(): try: ikey = int(key) ikeys.append((key, ikey)) obj[ikey] = obj[key] del obj[key] except ValueError: # XXX: do we want to ignore this? pass ikeys.sort() return obj def readList(self): """ Read a C{list} from the data stream. @rtype: C{list} @return: C{list} """ obj = [] self.context.addObject(obj) len = self.stream.read_ulong() for i in xrange(len): obj.append(self.readElement()) return obj def readTypedObject(self): """ Reads an ActionScript object from the stream and attempts to 'cast' it. @see: L{load_class} """ classname = self.readString() alias = None try: alias = pyamf.load_class(classname) ret = alias.createInstance(codec=self) except pyamf.UnknownClassAlias: if self.strict: raise ret = pyamf.TypedObject(classname) self.context.addObject(ret) self._readObject(ret, alias) return ret def readAMF3(self): """ Read AMF3 elements from the data stream. @rtype: C{mixed} @return: The AMF3 element read from the stream """ if not hasattr(self.context, 'amf3_context'): from pyamf import amf3 self.context.amf3_context = amf3.Context() decoder = pyamf._get_decoder_class(pyamf.AMF3)(self.stream, self.context.amf3_context, strict=self.strict) element = decoder.readElement() self.context.addAMF3Object(element) return element def readString(self): """ Reads a string from the data stream. @rtype: C{str} @return: string """ len = self.stream.read_ushort() return self.stream.read_utf8_string(len) def _readObject(self, obj, alias=None): ot = chr(ASTypes.OBJECTTERM) obj_attrs = dict() key = self.readString().encode('utf8') while self.stream.peek() != ot: obj_attrs[key] = self.readElement() key = self.readString().encode('utf8') # discard the end marker (ASTypes.OBJECTTERM) self.stream.read(len(ot)) if alias: alias.applyAttributes(obj, obj_attrs, codec=self) else: util.set_attrs(obj, obj_attrs) def readObject(self): """ Reads an object from the data stream. @rtype: L{ASObject} """ obj = pyamf.ASObject() self.context.addObject(obj) self._readObject(obj) return obj def readReference(self): """ Reads a reference from the data stream. """ idx = self.stream.read_ushort() return self.context.getObject(idx) def readDate(self): """ Reads a UTC date from the data stream. Client and servers are responsible for applying their own timezones. Date: C{0x0B T7 T6} .. C{T0 Z1 Z2 T7} to C{T0} form a 64 bit Big Endian number that specifies the number of nanoseconds that have passed since 1/1/1970 0:00 to the specified time. This format is UTC 1970. C{Z1} and C{Z0} for a 16 bit Big Endian number indicating the indicated time's timezone in minutes. """ ms = self.stream.read_double() / 1000.0 tz = self.stream.read_short() # Timezones are ignored d = util.get_datetime(ms) self.context.addObject(d) return d def readLongString(self): """ Read UTF8 string. """ len = self.stream.read_ulong() return self.stream.read_utf8_string(len) def readXML(self): """ Read XML. """ data = self.readLongString() xml = util.ET.fromstring(data) self.context.addObject(xml) return xml class Encoder(pyamf.BaseEncoder): """ Encodes an AMF0 stream. @ivar use_amf3: A flag to determine whether this encoder knows about AMF3. @type use_amf3: C{bool} """ context_class = Context type_map = [ ((types.BuiltinFunctionType, types.BuiltinMethodType, types.FunctionType, types.GeneratorType, types.ModuleType, types.LambdaType, types.MethodType), "writeFunc"), ((types.NoneType,), "writeNull"), ((bool,), "writeBoolean"), ((int,long,float), "writeNumber"), ((types.StringTypes,), "writeString"), ((pyamf.ASObject,), "writeObject"), ((pyamf.MixedArray,), "writeMixedArray"), ((types.ListType, types.TupleType,), "writeArray"), ((datetime.date, datetime.datetime), "writeDate"), ((util.is_ET_element,), "writeXML"), ((lambda x: x is pyamf.Undefined,), "writeUndefined"), ((types.InstanceType,types.ObjectType,), "writeObject"), ] def __init__(self, *args, **kwargs): self.use_amf3 = kwargs.pop('use_amf3', False) pyamf.BaseEncoder.__init__(self, *args, **kwargs) def writeType(self, type): """ Writes the type to the stream. @type type: C{int} @param type: ActionScript type. @raise pyamf.EncodeError: AMF0 type is not recognized. """ if type not in ACTIONSCRIPT_TYPES: raise pyamf.EncodeError("Unknown AMF0 type 0x%02x at %d" % ( type, self.stream.tell() - 1)) self.stream.write_uchar(type) def writeUndefined(self, data): """ Writes the L{undefined} data type to the stream. @param data: The C{undefined} data to be encoded to the AMF0 data stream. @type data: C{undefined} data """ self.writeType(ASTypes.UNDEFINED) def writeFunc(self, *args, **kwargs): """ Functions cannot be serialised. """ raise pyamf.EncodeError("Callables cannot be serialised") def writeUnsupported(self, data): """ Writes L{unsupported} data type to the stream. @param data: The C{unsupported} data to be encoded to the AMF0 data stream. @type data: C{unsupported} data """ self.writeType(ASTypes.UNSUPPORTED) def _writeElementFunc(self, data): """ Gets a function based on the type of data. @see: L{pyamf.BaseEncoder._writeElementFunc} """ # There is a very specific use case that we must check for. # In the context there is an array of amf3_objs that contain # references to objects that are to be encoded in amf3. try: self.context.getAMF3ObjectReference(data) return self.writeAMF3 except pyamf.ReferenceError: pass return pyamf.BaseEncoder._writeElementFunc(self, data) def writeElement(self, data): """ Writes the data. @type data: C{mixed} @param data: The data to be encoded to the AMF0 data stream. @raise EncodeError: Cannot find encoder func. """ func = self._writeElementFunc(data) if func is None: raise pyamf.EncodeError("Cannot find encoder func for %r" % (data,)) else: try: func(data) except (KeyboardInterrupt, SystemExit): raise except pyamf.EncodeError: raise except: #raise pyamf.EncodeError("Unable to encode '%r'" % (data,)) raise def writeNull(self, n): """ Write null type to data stream. @type n: C{None} @param n: Is ignored. """ self.writeType(ASTypes.NULL) def writeArray(self, a): """ Write array to the stream. @type a: L{BufferedByteStream} @param a: The array data to be encoded to the AMF0 data stream. """ alias = self.context.getClassAlias(a.__class__) if alias is not None and 'external' in alias.metadata: # a is a subclassed list with a registered alias - push to the # correct method self.writeObject(a) return try: self.writeReference(a) return except pyamf.ReferenceError: self.context.addObject(a) self.writeType(ASTypes.ARRAY) self.stream.write_ulong(len(a)) for data in a: self.writeElement(data) def writeNumber(self, n): """ Write number to the data stream. @type n: L{BufferedByteStream} @param n: The number data to be encoded to the AMF0 data stream. """ self.writeType(ASTypes.NUMBER) self.stream.write_double(float(n)) def writeBoolean(self, b): """ Write boolean to the data stream. @type b: L{BufferedByteStream} @param b: The boolean data to be encoded to the AMF0 data stream. """ self.writeType(ASTypes.BOOL) if b: self.stream.write_uchar(1) else: self.stream.write_uchar(0) def _writeString(self, s): if not isinstance(s, basestring): s = unicode(s).encode('utf8') if len(s) > 0xffff: self.stream.write_ulong(len(s)) else: self.stream.write_ushort(len(s)) self.stream.write(s) def writeString(self, s, writeType=True): """ Write string to the data stream. @type s: L{BufferedByteStream} @param s: The string data to be encoded to the AMF0 data stream. @type writeType: C{bool} @param writeType: Write data type. """ if isinstance(s, unicode): s = s.encode('utf8') elif not isinstance(s, basestring): s = unicode(s).encode('utf8') if len(s) > 0xffff: if writeType: self.writeType(ASTypes.LONGSTRING) else: if writeType: self.stream.write_uchar(ASTypes.STRING) self._writeString(s) def writeReference(self, o): """ Write reference to the data stream. @type o: L{BufferedByteStream} @param o: The reference data to be encoded to the AMF0 data stream. """ idx = self.context.getObjectReference(o) self.writeType(ASTypes.REFERENCE) self.stream.write_ushort(idx) def _writeDict(self, o): """ Write C{dict} to the data stream. @type o: C{iterable} @param o: The C{dict} data to be encoded to the AMF0 data stream. """ for key, val in o.iteritems(): self.writeString(key, False) self.writeElement(val) def writeMixedArray(self, o): """ Write mixed array to the data stream. @type o: L{BufferedByteStream} @param o: The mixed array data to be encoded to the AMF0 data stream. """ try: self.writeReference(o) return except pyamf.ReferenceError: self.context.addObject(o) self.writeType(ASTypes.MIXEDARRAY) # TODO: optimise this # work out the highest integer index try: # list comprehensions to save the day max_index = max([y[0] for y in o.items() if isinstance(y[0], (int, long))]) if max_index < 0: max_index = 0 except ValueError: max_index = 0 self.stream.write_ulong(max_index) self._writeDict(o) self._writeEndObject() def _writeEndObject(self): # Write a null string, this is an optimisation so that we don't # have to waste precious cycles by encoding the string etc. self.stream.write('\x00\x00') self.writeType(ASTypes.OBJECTTERM) def _getObjectAttrs(self, o, alias): """ @raise pyamf.EncodeError: Unable to determine object attributes. """ obj_attrs = None if alias is not None: obj_attrs = {} for attrs in alias.getAttributes(o, codec=self): obj_attrs.update(attrs) if obj_attrs is None: obj_attrs = util.get_attrs(o) if obj_attrs is None: raise pyamf.EncodeError('Unable to determine object attributes') return obj_attrs def writeObject(self, o): """ Write object to the stream. @type o: L{BufferedByteStream} @param o: The object data to be encoded to the AMF0 data stream. """ if self.use_amf3 is True: self.writeAMF3(o) return try: self.writeReference(o) return except pyamf.ReferenceError: self.context.addObject(o) alias = self.context.getClassAlias(o.__class__) if alias is None: self.writeType(ASTypes.OBJECT) else: if 'amf3' in alias.metadata: self.writeAMF3(o) return if 'anonymous' in alias.metadata: self.writeType(ASTypes.OBJECT) else: self.writeType(ASTypes.TYPEDOBJECT) self.writeString(alias.alias, False) obj_attrs = self._getObjectAttrs(o, alias) for key, value in obj_attrs.iteritems(): self.writeString(key, False) self.writeElement(value) self._writeEndObject() def writeDate(self, d): """ Writes a date to the data stream. @type d: Instance of C{datetime.datetime} @param d: The date to be encoded to the AMF0 data stream. """ # According to the Red5 implementation of AMF0, dates references are # created, but not used. secs = util.get_timestamp(d) tz = 0 self.writeType(ASTypes.DATE) self.stream.write_double(secs * 1000.0) self.stream.write_short(tz) def writeXML(self, e): """ Write XML to the data stream. @type e: L{BufferedByteStream} @param e: The XML data to be encoded to the AMF0 data stream. """ if self.use_amf3 is True: self.writeAMF3(e) return self.writeType(ASTypes.XML) data = util.ET.tostring(e, 'utf-8') self.stream.write_ulong(len(data)) self.stream.write(data) def writeAMF3(self, data): """ Writes an element to the datastream in L{AMF3} format. @type data: C{mixed} @param data: The data to be encoded to the AMF0 data stream. """ if not hasattr(self.context, 'amf3_context'): from pyamf import amf3 self.context.amf3_context = amf3.Context() self.context.addAMF3Object(data) encoder = pyamf._get_encoder_class(pyamf.AMF3)(self.stream, self.context.amf3_context) self.writeType(ASTypes.AMF3) encoder.writeElement(data) def decode(stream, context=None, strict=False): """ A helper function to decode an AMF0 datastream. @type stream: L{BufferedByteStream} @param stream: AMF0 datastream. @type context: L{Context} @param context: AMF0 Context. """ decoder = Decoder(stream, context, strict=strict) while 1: try: yield decoder.readElement() except pyamf.EOStream: break def encode(*args, **kwargs): """ A helper function to encode an element into the AMF0 format. @type element: C{mixed} @keyword element: The element to encode @type context: L{Context} @keyword context: AMF0 C{Context} to use for the encoding. This holds previously referenced objects etc. @rtype: C{StringIO} @return: The encoded stream. """ context = kwargs.get('context', None) buf = util.BufferedByteStream() encoder = Encoder(buf, context) for element in args: encoder.writeElement(element) return buf class RecordSet(object): """ I represent the C{RecordSet} class used in Flash Remoting to hold (amongst other things) SQL records. @ivar columns: The columns to send. @type columns: List of strings. @ivar items: The C{RecordSet} data. @type items: List of lists, the order of the data corresponds to the order of the columns. @ivar service: Service linked to the C{RecordSet}. @type service: @ivar id: The id of the C{RecordSet}. @type id: C{str} @see: U{RecordSet on OSFlash (external) } """ def __init__(self, columns=[], items=[], service=None, id=None): self.columns = columns self.items = items self.service = service self.id = id def _get_server_info(self): ret = pyamf.ASObject(totalCount=len(self.items), cursor=1, version=1, initialData=self.items, columnNames=self.columns) if self.service is not None: ret.update({'serviceName': str(self.service['name'])}) if self.id is not None: ret.update({'id':str(self.id)}) return ret def _set_server_info(self, val): self.columns = val['columnNames'] self.items = val['initialData'] try: # TODO nick: find relevant service and link in here. self.service = dict(name=val['serviceName']) except KeyError: self.service = None try: self.id = val['id'] except KeyError: self.id = None serverInfo = property(_get_server_info, _set_server_info) def __repr__(self): ret = '<%s.%s object' % (self.__module__, self.__class__.__name__) if self.id is not None: ret += ' id=%s' % self.id if self.service is not None: ret += ' service=%s' % self.service ret += ' at 0x%x>' % id(self) return ret pyamf.register_class(RecordSet, 'RecordSet', attrs=['serverInfo'], metadata=['amf0']) def _check_for_int(x): """ This is a compatibility function that takes a C{float} and converts it to an C{int} if the values are equal. """ try: y = int(x) except (OverflowError, ValueError): pass else: # There is no way in AMF0 to distinguish between integers and floats if x == x and y == x: return y return x # check for some Python 2.3 problems with floats try: float('nan') except ValueError: pass else: if float('nan') == 0: def check_nan(func): def f2(x): if str(x).lower().find('nan') >= 0: return x return f2.func(x) f2.func = func return f2 _check_for_int = check_nan(_check_for_int) PKp:ޝqq pyamf/amf3.py# -*- coding: utf-8 -*- # # Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ AMF3 implementation. C{AMF3} is the default serialization for U{ActionScript} 3.0 and provides various advantages over L{AMF0}, which is used for ActionScript 1.0 and 2.0. It adds support for sending C{int} and C{uint} objects as integers and supports data types that are available only in ActionScript 3.0, such as L{ByteArray} and L{ArrayCollection}. @see: U{Official AMF3 Specification in English (external) } @see: U{Official AMF3 Specification in Japanese (external) } @see: U{AMF3 documentation on OSFlash (external) } @since: 0.1.0 """ import types, datetime, zlib import pyamf from pyamf import util from pyamf.flex import ObjectProxy, ArrayCollection #: If True encode/decode lists/tuples to ArrayCollections #: and dicts to ObjectProxy use_proxies_default = False try: set() except NameError: from sets import Set as set class ASTypes: """ All AMF3 data types used in ActionScript 3.0. AMF represents ActionScript objects by a single byte representing type, and then by a type-specific byte array that may be of fixed length, may contain length information, or may come with its own end code. @see: U{AMF3 data types on OSFlash (external) } """ #: The undefined type is represented by the undefined type marker. #: No further information is encoded for this value. UNDEFINED = 0x00 #: The undefined type is represented by the undefined type marker. #: No further information is encoded for this value. NULL = 0x01 #: The false type is represented by the false type marker and is #: used to encode a Boolean value of C{false}. No further information #: is encoded for this value. #: @note: In ActionScript 3.0 the concept of a primitive and Object #: form of Boolean does not exist. BOOL_FALSE = 0x02 #: The true type is represented by the true type marker and is #: used to encode a Boolean value of C{true}. No further information #: is encoded for this value. #: @note: In ActionScript 3.0 the concept of a primitive and Object #: form of Boolean does not exist. BOOL_TRUE = 0x03 #: In AMF 3 integers are serialized using a variable length unsigned #: 29-bit integer. #: @see: U{Parsing Integers on OSFlash (external) #: } INTEGER = 0x04 #: This type is used to encode an ActionScript Number #: or an ActionScript C{int} of value greater than or equal to 2^28 #: or an ActionScript uint of value greater than or equal to 2^29. #: The encoded value is is always an 8 byte IEEE-754 double precision #: floating point value in network byte order (sign bit in low memory). #: The AMF 3 number type is encoded in the same manner as the #: AMF 0 L{Number} type. NUMBER = 0x05 #: ActionScript String values are represented using a single string #: type in AMF 3 - the concept of string and long string types from #: AMF 0 is not used. Strings can be sent as a reference to a previously #: occurring String by using an index to the implicit string reference #: table. #: Strings are encoding using UTF-8 - however the header may either #: describe a string literal or a string reference. STRING = 0x06 #: ActionScript 3.0 introduced a new XML type however the legacy #: C{XMLDocument} type from ActionScript 1.0 and 2.0.is retained #: in the language as C{flash.xml.XMLDocument}. Similar to AMF 0, the #: structure of an C{XMLDocument} needs to be flattened into a string #: representation for serialization. As with other strings in AMF, #: the content is encoded in UTF-8. XMLDocuments can be sent as a reference #: to a previously occurring C{XMLDocument} instance by using an index to #: the implicit object reference table. #: @see: U{OSFlash documentation (external) #: } XML = 0x07 #: In AMF 3 an ActionScript Date is serialized simply as the number of #: milliseconds elapsed since the epoch of midnight, 1st Jan 1970 in the #: UTC time zone. Local time zone information is not sent. DATE = 0x08 #: ActionScript Arrays are described based on the nature of their indices, #: i.e. their type and how they are positioned in the Array. ARRAY = 0x09 #: A single AMF 3 type handles ActionScript Objects and custom user classes. OBJECT = 0x0a #: ActionScript 3.0 introduces a new top-level XML class that supports #: U{E4X} syntax. #: For serialization purposes the XML type needs to be flattened into a #: string representation. As with other strings in AMF, the content is #: encoded using UTF-8. XMLSTRING = 0x0b #: ActionScript 3.0 introduces the L{ByteArray} type to hold an Array #: of bytes. AMF 3 serializes this type using a variable length encoding #: 29-bit integer for the byte-length prefix followed by the raw bytes #: of the L{ByteArray}. #: @see: U{Parsing ByteArrays on OSFlash (external) #: } BYTEARRAY = 0x0c #: List of available ActionScript types in AMF3. ACTIONSCRIPT_TYPES = [] for x in ASTypes.__dict__: if not x.startswith('_'): ACTIONSCRIPT_TYPES.append(ASTypes.__dict__[x]) del x #: Reference bit. REFERENCE_BIT = 0x01 class ObjectEncoding: """ AMF object encodings. """ #: Property list encoding. #: The remaining integer-data represents the number of class members that #: exist. The property names are read as string-data. The values are then #: read as AMF3-data. STATIC = 0x00 #: Externalizable object. #: What follows is the value of the "inner" object, including type code. #: This value appears for objects that implement IExternalizable, such as #: L{ArrayCollection} and L{ObjectProxy}. EXTERNAL = 0x01 #: Name-value encoding. #: The property names and values are encoded as string-data followed by #: AMF3-data until there is an empty string property name. If there is a #: class-def reference there are no property names and the number of values #: is equal to the number of properties in the class-def. DYNAMIC = 0x02 #: Proxy object. PROXY = 0x03 class DataOutput(object): """ I am a C{StringIO} type object containing byte data from the AMF stream. ActionScript 3.0 introduced the C{flash.utils.ByteArray} class to support the manipulation of raw data in the form of an Array of bytes. I provide a set of methods for writing binary data with ActionScript 3.0. This class is the I/O counterpart to the L{DataInput} class, which reads binary data. @see: U{IDataOutput on Livedocs (external) } """ def __init__(self, encoder): """ @param encoder: Encoder containing the stream. @type encoder: L{amf3.Encoder} """ assert isinstance(encoder, Encoder) self.encoder = encoder self.stream = encoder.stream def writeBoolean(self, value): """ Writes a Boolean value. @type value: C{bool} @param value: A C{Boolean} value determining which byte is written. If the parameter is C{True}, C{1} is written; if C{False}, C{0} is written. @raise ValueError: Non-boolean value found. """ if isinstance(value, bool): if value is True: self.stream.write_uchar(1) else: self.stream.write_uchar(0) else: raise ValueError("Non-boolean value found") def writeByte(self, value): """ Writes a byte. @type value: C{int} """ self.stream.write_char(value) def writeDouble(self, value): """ Writes an IEEE 754 double-precision (64-bit) floating point number. @type value: C{number} """ self.stream.write_double(value) def writeFloat(self, value): """ Writes an IEEE 754 single-precision (32-bit) floating point number. @type value: C{float} """ self.stream.write_float(value) def writeInt(self, value): """ Writes a 32-bit signed integer. @type value: C{int} """ self.stream.write_long(value) def writeMultiByte(self, value, charset): """ Writes a multibyte string to the datastream using the specified character set. @type value: C{str} @param value: The string value to be written. @type charset: C{str} @param charset: The string denoting the character set to use. Possible character set strings include C{shift-jis}, C{cn-gb}, C{iso-8859-1} and others. @see: U{Supported character sets on Livedocs (external) } """ self.stream.write(unicode(value).encode(charset)) def writeObject(self, value, use_references=True): """ Writes an object to data stream in AMF serialized format. @param value: The object to be serialized. @type use_references: C{bool} @param use_references: """ self.encoder.writeElement(value, use_references) def writeShort(self, value): """ Writes a 16-bit integer. @type value: C{int} @param value: A byte value as an integer. """ self.stream.write_short(value) def writeUnsignedInt(self, value): """ Writes a 32-bit unsigned integer. @type value: C{int} @param value: A byte value as an unsigned integer. """ self.stream.write_ulong(value) def writeUTF(self, value): """ Writes a UTF-8 string to the data stream. The length of the UTF-8 string in bytes is written first, as a 16-bit integer, followed by the bytes representing the characters of the string. @type value: C{str} @param value: The string value to be written. """ if not isinstance(value, unicode): value = unicode(value, 'utf8') buf = util.BufferedByteStream() buf.write_utf8_string(value) bytes = buf.getvalue() self.stream.write_ushort(len(bytes)) self.stream.write(bytes) def writeUTFBytes(self, value): """ Writes a UTF-8 string. Similar to L{writeUTF}, but does not prefix the string with a 16-bit length word. @type value: C{str} @param value: The string value to be written. """ val = None if isinstance(value, unicode): val = value else: val = unicode(value, 'utf8') self.stream.write_utf8_string(val) class DataInput(object): """ I provide a set of methods for reading binary data with ActionScript 3.0. This class is the I/O counterpart to the L{DataOutput} class, which writes binary data. @see: U{IDataInput on Livedocs (external) } """ def __init__(self, decoder): """ @param decoder: AMF3 decoder containing the stream. @type decoder: L{amf3.Decoder} """ assert isinstance(decoder, Decoder) self.decoder = decoder self.stream = decoder.stream def readBoolean(self): """ Read C{Boolean}. @raise ValueError: Error reading Boolean. @rtype: C{bool} @return: A Boolean value, C{True} if the byte is nonzero, C{False} otherwise. """ byte = self.stream.read(1) if byte == '\x00': return False elif byte == '\x01': return True else: raise ValueError("Error reading boolean") def readByte(self): """ Reads a signed byte. @rtype: C{int} @return: The returned value is in the range -128 to 127. """ return self.stream.read_char() def readDouble(self): """ Reads an IEEE 754 double-precision floating point number from the data stream. @rtype: C{number} @return: An IEEE 754 double-precision floating point number. """ return self.stream.read_double() def readFloat(self): """ Reads an IEEE 754 single-precision floating point number from the data stream. @rtype: C{number} @return: An IEEE 754 single-precision floating point number. """ return self.stream.read_float() def readInt(self): """ Reads a signed 32-bit integer from the data stream. @rtype: C{int} @return: The returned value is in the range -2147483648 to 2147483647. """ return self.stream.read_long() def readMultiByte(self, length, charset): """ Reads a multibyte string of specified length from the data stream using the specified character set. @type length: C{int} @param length: The number of bytes from the data stream to read. @type charset: C{str} @param charset: The string denoting the character set to use. @rtype: C{str} @return: UTF-8 encoded string. """ #FIXME nick: how to work out the code point byte size (on the fly)? bytes = self.stream.read(length) return unicode(bytes, charset) def readObject(self): """ Reads an object from the data stream. @return: The deserialized object. """ return self.decoder.readElement() def readShort(self): """ Reads a signed 16-bit integer from the data stream. @rtype: C{uint} @return: The returned value is in the range -32768 to 32767. """ return self.stream.read_short() def readUnsignedByte(self): """ Reads an unsigned byte from the data stream. @rtype: C{uint} @return: The returned value is in the range 0 to 255. """ return self.stream.read_uchar() def readUnsignedInt(self): """ Reads an unsigned 32-bit integer from the data stream. @rtype: C{uint} @return: The returned value is in the range 0 to 4294967295. """ return self.stream.read_ulong() def readUnsignedShort(self): """ Reads an unsigned 16-bit integer from the data stream. @rtype: C{uint} @return: The returned value is in the range 0 to 65535. """ return self.stream.read_ushort() def readUTF(self): """ Reads a UTF-8 string from the data stream. The string is assumed to be prefixed with an unsigned short indicating the length in bytes. @rtype: C{str} @return: A UTF-8 string produced by the byte representation of characters. """ length = self.stream.read_ushort() return self.stream.read_utf8_string(length) def readUTFBytes(self, length): """ Reads a sequence of C{length} UTF-8 bytes from the data stream and returns a string. @type length: C{int} @param length: The number of bytes from the data stream to read. @rtype: C{str} @return: A UTF-8 string produced by the byte representation of characters of specified C{length}. """ return self.readMultiByte(length, 'utf-8') class ByteArray(util.BufferedByteStream, DataInput, DataOutput): """ I am a C{StringIO} type object containing byte data from the AMF stream. ActionScript 3.0 introduced the C{flash.utils.ByteArray} class to support the manipulation of raw data in the form of an Array of bytes. Supports C{zlib} compression. Possible uses of the C{ByteArray} class: - Creating a custom protocol to connect to a client. - Writing your own AMF/Remoting packet. - Optimizing the size of your data by using custom data types. @see: U{ByteArray on Livedocs (external) } """ def __init__(self, *args, **kwargs): self.context = kwargs.pop('context', Context()) util.BufferedByteStream.__init__(self, *args, **kwargs) DataInput.__init__(self, Decoder(self, self.context)) DataOutput.__init__(self, Encoder(self, self.context)) self.compressed = False def __cmp__(self, other): if isinstance(other, ByteArray): return cmp(self.getvalue(), other.getvalue()) return cmp(self.getvalue(), other) def __str__(self): buf = self.getvalue() if self.compressed: buf = zlib.compress(buf) #FIXME nick: hacked buf = buf[0] + '\xda' + buf[2:] return buf def compress(self): """ Forces compression of the underlying stream. """ self.compressed = True pyamf.register_class(ByteArray, metadata=['amf3']) class ClassDefinition(object): """ I contain meta relating to the class definition. @ivar alias: The alias to this class definition. If this value is C{None}, or an empty string, the class is considered to be anonymous. @type alias: L{ClassAlias} @ivar encoding: The type of encoding to use when serializing the object. @type encoding: C{int} """ def __init__(self, alias, encoding=ObjectEncoding.DYNAMIC): if alias in (None, ''): self.alias = None elif isinstance(alias, pyamf.ClassAlias): self.alias = alias else: self.alias = pyamf.get_class_alias(alias) self.encoding = encoding def _get_name(self): if self.alias is None: # anonymous class return '' if 'anonymous' in self.alias.metadata: return '' return str(self.alias) name = property(_get_name) def _getClass(self): """ If C{alias} is C{None}, an L{anonymous class} is returned, otherwise the class is loaded externally. """ if self.alias in (None, ''): # anonymous class return pyamf.ASObject return self.getClassAlias().klass def getClassAlias(self): """ Gets the class alias that is held by this definition. @see: L{get_class_alias}. @rtype: L{ClassAlias} @return: Class alias. """ if not isinstance(self.alias, pyamf.ClassAlias): self.alias = pyamf.get_class_alias(self.alias) return self.alias def getClass(self): """ Gets the referenced class that is held by this definition. """ if hasattr(self, '_klass'): return self._klass self._klass = self._getClass() return self._klass klass = property(getClass) def getStaticAttrs(self, obj, codec=None): """ Returns a list of static attributes based on C{obj}. Once built, this list is immutable. @param obj: The object to determine the static attributes from. @type obj: C{mixed}. @since: 0.4 """ if hasattr(self, 'static_attrs'): return self.static_attrs if not self.alias: if hasattr(obj, '__slots__'): return obj.__slots__ return [] static_attrs, dynamic_attrs = self.alias.getAttrs(obj, codec=self) if static_attrs is None: self.static_attrs = [] else: self.static_attrs = static_attrs return self.static_attrs def getAttrs(self, obj, codec=None): """ Returns a C{tuple} containing a dict of static and dynamic attributes for C{obj}. """ if self.alias is not None: return self.alias.getAttributes(obj, codec=codec) dynamic_attrs = util.get_attrs(obj) static_attrs = {} for a in self.getStaticAttrs(obj, codec=codec): static_attrs[a] = dynamic_attrs[a] del dynamic_attrs[a] return static_attrs, dynamic_attrs def createInstance(self, codec=None): """ Creates a new instance. """ if self.alias: obj = self.alias.createInstance(codec=codec) else: klass = self.getClass() obj = klass() return obj def applyAttributes(self, obj, attrs, codec=None): """ Applies a collection of attributes C{attrs} to object C{obj} """ if self.alias: self.alias.applyAttributes(obj, attrs, codec=codec) else: util.set_attrs(obj, attrs) class Context(pyamf.BaseContext): """ I hold the AMF3 context for en/decoding streams. @ivar strings: A list of string references. @type strings: C{list} @ivar classes: A list of L{ClassDefinition}. @type classes: C{list} @ivar legacy_xml: A list of legacy encoded XML documents. @type legacy_xml: C{list} """ def __init__(self): self.strings = util.IndexedCollection(use_hash=True) self.classes = util.IndexedCollection() self.class_defs = util.IndexedCollection() self.legacy_xml = util.IndexedCollection() self.object_aliases = util.IndexedMap() # Maps one object to another pyamf.BaseContext.__init__(self) def clear(self): """ Clears the context. """ pyamf.BaseContext.clear(self) self.strings.clear() self.classes.clear() self.class_defs.clear() self.legacy_xml.clear() self.object_aliases.clear() def reset(self): """ Resets the context. @see: L{pyamf.BaseContext.reset} """ pyamf.BaseContext.reset(self) self.strings.clear() self.classes.clear() self.class_defs.clear() self.legacy_xml.clear() self.object_aliases.clear() def setObjectAlias(self, obj, alias): """ Maps an object to an aliased object. @since: 0.4 """ self.object_aliases.map(obj, alias) def getObjectAlias(self, obj): """ Get an alias of an object. @since: 0.4 """ ref = self.object_aliases.getReferenceTo(obj) return self.object_aliases.getMappedByReference(ref) def getString(self, ref): """ Gets a string based on a reference C{ref}. @param ref: The reference index. @type ref: C{str} @raise ReferenceError: The referenced string could not be found. @rtype: C{str} @return: The referenced string. """ try: return self.strings.getByReference(ref) except pyamf.ReferenceError: raise pyamf.ReferenceError("String reference %r not found" % (ref,)) def getStringReference(self, s): """ Return string reference. @type s: C{str} @param s: The referenced string. @raise ReferenceError: The string reference could not be found. @return: The reference index to the string. @rtype: C{int} """ try: return self.strings.getReferenceTo(s) except ValueError: raise pyamf.ReferenceError("Reference for string %r not found" % (s,)) def addString(self, s): """ Creates a reference to C{s}. If the reference already exists, that reference is returned. @type s: C{str} @param s: The string to be referenced. @rtype: C{int} @return: The reference index. @raise TypeError: The parameter C{s} is not of C{basestring} type. @raise ValueError: Trying to store a reference to an empty string. """ if not isinstance(s, basestring): raise TypeError if len(s) == 0: # do not store empty string references raise ValueError("Cannot store a reference to an empty string") return self.strings.append(s) def getClassDefinition(self, ref): """ Return class reference. @raise ReferenceError: The class reference could not be found. @return: Class reference. """ try: return self.class_defs.getByReference(ref) except IndexError: raise pyamf.ReferenceError("Class reference %r not found" % (ref,)) def getClassDefinitionReference(self, class_def): """ Return class definition reference. @type class_def: L{ClassDefinition} or C{instance} or C{class} @param class_def: The class definition reference to be found. @raise ReferenceError: The reference could not be found. @raise TypeError: Unable to determine class. @return: The reference to C{class_def}. @rtype: C{int} """ if isinstance(class_def, ClassDefinition): try: return self.class_defs.getReferenceTo(class_def) except KeyError: raise pyamf.ReferenceError("Reference for class %s not found" % (class_def.klass,)) if isinstance(class_def, (type, types.ClassType)): try: return self.classes.getReferenceTo(class_def) except pyamf.ReferenceError: raise pyamf.ReferenceError("Reference for class definition for %s not found" % (class_def,)) elif isinstance(class_def, (types.InstanceType, types.ObjectType)): try: return self.classes.getReferenceTo(class_def.__class__) except pyamf.ReferenceError: raise pyamf.ReferenceError("Reference for class definition for %s not found" % (class_def.__class__,)) raise TypeError('Unable to determine class for %r' % (class_def,)) def addClassDefinition(self, class_def): """ Creates a reference to C{class_def}. @param class_def: C{ClassDefinition} instance. """ try: return self.class_defs.getReferenceTo(class_def) except pyamf.ReferenceError: try: self.classes.append(class_def.klass) except pyamf.UnknownClassAlias: pass return self.class_defs.append(class_def) def removeClassDefinition(self, class_def): """ Removes a C{ClassDefinition} reference from this context. """ idx = self.rev_classes[id(class_def)] del self.rev_classes[id(class_def)] del self.classes[idx] def getLegacyXML(self, ref): """ Return the legacy XML reference. This is the C{flash.xml.XMLDocument} class in ActionScript 3.0 and the top-level C{XML} class in ActionScript 1.0 and 2.0. @type ref: C{int} @param ref: The reference index. @raise ReferenceError: The legacy XML reference could not be found. @return: Instance of L{ET} """ try: return self.legacy_xml.getByReference(ref) except pyamf.ReferenceError: raise pyamf.ReferenceError("Legacy XML reference %r not found" % (ref,)) def getLegacyXMLReference(self, doc): """ Return legacy XML reference. @type doc: L{ET} @param doc: The XML document to reference. @raise ReferenceError: The reference could not be found. @return: The reference to C{doc}. @rtype: C{int} """ try: return self.legacy_xml.getReferenceTo(doc) except pyamf.ReferenceError: raise pyamf.ReferenceError("Reference for document %r not found" % (doc,)) def addLegacyXML(self, doc): """ Creates a reference to C{doc}. If C{doc} is already referenced that index will be returned. Otherwise a new index will be created. @type doc: L{ET} @param doc: The XML document to reference. @rtype: C{int} @return: The reference to C{doc}. """ return self.legacy_xml.append(doc) def __copy__(self): return self.__class__() class Decoder(pyamf.BaseDecoder): """ Decodes an AMF3 data stream. """ context_class = Context type_map = { ASTypes.UNDEFINED: 'readUndefined', ASTypes.NULL: 'readNull', ASTypes.BOOL_FALSE: 'readBoolFalse', ASTypes.BOOL_TRUE: 'readBoolTrue', ASTypes.INTEGER: 'readSignedInteger', ASTypes.NUMBER: 'readNumber', ASTypes.STRING: 'readString', ASTypes.XML: 'readXML', ASTypes.DATE: 'readDate', ASTypes.ARRAY: 'readArray', ASTypes.OBJECT: 'readObject', ASTypes.XMLSTRING: 'readXMLString', ASTypes.BYTEARRAY: 'readByteArray', } def __init__(self, data=None, context=None, strict=False, use_proxies=None): pyamf.BaseDecoder.__init__(self, data, context, strict) if use_proxies is None: self.use_proxies = use_proxies_default else: self.use_proxies = use_proxies def readType(self): """ Read and returns the next byte in the stream and determine its type. @raise DecodeError: AMF3 type not recognized. @return: AMF3 type. @rtype: C{int} """ type = self.stream.read_uchar() if type not in ACTIONSCRIPT_TYPES: raise pyamf.DecodeError("Unknown AMF3 type 0x%02x at %d" % (type, self.stream.tell() - 1)) return type def readUndefined(self): """ Read undefined. """ return pyamf.Undefined def readNull(self): """ Read null. @return: C{None} @rtype: C{None} """ return None def readBoolFalse(self): """ Returns C{False}. @return: C{False} @rtype: C{bool} """ return False def readBoolTrue(self): """ Returns C{True}. @return: C{True} @rtype: C{bool} """ return True def readNumber(self): """ Read number. """ return self.stream.read_double() def readUnsignedInteger(self): """ Reads and returns an unsigned integer from the stream. """ return self.readInteger(False) def readSignedInteger(self): """ Reads and returns a signed integer from the stream. """ return self.readInteger(True) def readInteger(self, signed=False): """ Reads and returns an integer from the stream. @type signed: C{bool} @see: U{Parsing integers on OSFlash } for the AMF3 integer data format. """ return decode_int(self.stream, signed) def readString(self, use_references=True): """ Reads and returns a string from the stream. @type use_references: C{bool} """ def readLength(): x = self.readUnsignedInteger() return (x >> 1, x & REFERENCE_BIT == 0) length, is_reference = readLength() if use_references and is_reference: return self.context.getString(length) buf = self.stream.read(length) result = unicode(buf, "utf8") if len(result) != 0 and use_references: self.context.addString(result) return result def readDate(self): """ Read date from the stream. The timezone is ignored as the date is always in UTC. """ ref = self.readUnsignedInteger() if ref & REFERENCE_BIT == 0: return self.context.getObject(ref >> 1) ms = self.stream.read_double() result = util.get_datetime(ms / 1000.0) self.context.addObject(result) return result def readArray(self): """ Reads an array from the stream. @warning: There is a very specific problem with AMF3 where the first three bytes of an encoded empty C{dict} will mirror that of an encoded C{{'': 1, '2': 2}} @see: U{Docuverse blog (external) } """ size = self.readUnsignedInteger() if size & REFERENCE_BIT == 0: return self.context.getObject(size >> 1) size >>= 1 key = self.readString().encode('utf8') if key == "": # integer indexes only -> python list result = [] self.context.addObject(result) for i in xrange(size): result.append(self.readElement()) else: result = pyamf.MixedArray() self.context.addObject(result) while key != "": el = self.readElement() try: result[str(key)] = el except UnicodeError: result[key] = el key = self.readString().encode('utf8') for i in xrange(size): el = self.readElement() result[i] = el return result def _getClassDefinition(self, ref): """ Reads class definition from the stream. """ class_ref = ref & REFERENCE_BIT == 0 ref >>= 1 if class_ref: class_def = self.context.getClassDefinition(ref) else: class_name = self.readString() if class_name == '': class_alias = None else: try: class_alias = pyamf.get_class_alias(class_name) except pyamf.UnknownClassAlias: if self.strict: raise class_alias = pyamf.TypedObjectClassAlias(pyamf.TypedObject, class_name) class_def = ClassDefinition(class_alias, encoding=ref & 0x03) self.context.addClassDefinition(class_def) return class_ref, class_def, ref >> 2 def readObject(self, _use_proxies=None): """ Reads an object from the stream. @raise pyamf.EncodeError: Decoding an object in amf3 tagged as amf0 only is not allowed. @raise pyamf.DecodeError: Unknown object encoding. """ if _use_proxies is None: _use_proxies = self.use_proxies def readStatic(is_ref, class_def, obj, num_attrs): if not is_ref: class_def.static_attrs = [] for i in range(num_attrs): key = self.readString().encode('utf8') class_def.static_attrs.append(key) for attr in class_def.static_attrs: obj[attr] = self.readElement() def readDynamic(is_ref, class_def, obj): attr = self.readString().encode('utf8') while attr != '': obj[attr] = self.readElement() attr = self.readString().encode('utf8') ref = self.readUnsignedInteger() if ref & REFERENCE_BIT == 0: obj = self.context.getObject(ref >> 1) if _use_proxies is True: obj = self.readProxyObject(obj) return obj ref >>= 1 class_ref, class_def, num_attrs = self._getClassDefinition(ref) if class_def.alias and 'amf0' in class_def.alias.metadata: raise pyamf.EncodeError("Decoding an object in amf3 tagged as amf0 only is not allowed") obj = class_def.createInstance(codec=self) obj_attrs = dict() self.context.addObject(obj) if class_def.encoding in (ObjectEncoding.EXTERNAL, ObjectEncoding.PROXY): obj.__readamf__(DataInput(self)) elif class_def.encoding == ObjectEncoding.DYNAMIC: readStatic(class_ref, class_def, obj_attrs, num_attrs) readDynamic(class_ref, class_def, obj_attrs) elif class_def.encoding == ObjectEncoding.STATIC: readStatic(class_ref, class_def, obj_attrs, num_attrs) else: raise pyamf.DecodeError("Unknown object encoding") class_def.applyAttributes(obj, obj_attrs, codec=self) if _use_proxies is True: obj = self.readProxyObject(obj) return obj def readProxyObject(self, proxy): """ Return the source object of a proxied object. @since: 0.4 """ if isinstance(proxy, ArrayCollection): return list(proxy) elif isinstance(proxy, ObjectProxy): return proxy._amf_object else: return proxy def _readXML(self, legacy=False): """ Reads an object from the stream. @type legacy: C{bool} @param legacy: The read XML is in 'legacy' format. """ ref = self.readUnsignedInteger() if ref & REFERENCE_BIT == 0: return self.context.getObject(ref >> 1) xmlstring = self.stream.read(ref >> 1) x = util.ET.fromstring(xmlstring) self.context.addObject(x) if legacy is True: self.context.addLegacyXML(x) return x def readXMLString(self): """ Reads a string from the data stream and converts it into an XML Tree. @return: The XML Document. @rtype: L{ET} """ return self._readXML() def readXML(self): """ Read a legacy XML Document from the stream. @return: The XML Document. @rtype: L{ET} """ return self._readXML(True) def readByteArray(self): """ Reads a string of data from the stream. Detects if the L{ByteArray} was compressed using C{zlib}. @see: L{ByteArray} @note: This is not supported in ActionScript 1.0 and 2.0. """ ref = self.readUnsignedInteger() if ref & REFERENCE_BIT == 0: return self.context.getObject(ref >> 1) buffer = self.stream.read(ref >> 1) try: buffer = zlib.decompress(buffer) compressed = True except zlib.error: compressed = False obj = ByteArray(buffer, context=self.context) obj.compressed = compressed self.context.addObject(obj) return obj class Encoder(pyamf.BaseEncoder): """ Encodes an AMF3 data stream. """ context_class = Context type_map = [ ((types.BuiltinFunctionType, types.BuiltinMethodType, types.FunctionType, types.GeneratorType, types.ModuleType, types.LambdaType, types.MethodType), "writeFunc"), ((bool,), "writeBoolean"), ((types.NoneType,), "writeNull"), ((int,long), "writeInteger"), ((float,), "writeNumber"), ((types.StringTypes,), "writeString"), ((ByteArray,), "writeByteArray"), ((datetime.date, datetime.datetime), "writeDate"), ((util.is_ET_element,), "writeXML"), ((lambda x: x is pyamf.Undefined,), "writeUndefined"), ((types.InstanceType, types.ObjectType,), "writeInstance"), ] def __init__(self, data=None, context=None, strict=False, use_proxies=None): pyamf.BaseEncoder.__init__(self, data, context, strict) if use_proxies is None: self.use_proxies = use_proxies_default else: self.use_proxies = use_proxies def writeElement(self, data, use_references=True): """ Writes the data. @type data: C{mixed} @param data: The data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. @raise EncodeError: Cannot find encoder func for C{data}. """ func = self._writeElementFunc(data) if func is None: raise pyamf.EncodeError("Cannot find encoder func for %r" % (data,)) else: try: if isinstance(func, pyamf.CustomTypeFunc): func(data) else: func(data, use_references=use_references) except (KeyboardInterrupt, SystemExit): raise except: raise def writeType(self, type): """ Writes the data type to the stream. @param type: ActionScript type. @raise EncodeError: AMF3 type is not recognized. @see: L{ACTIONSCRIPT_TYPES} """ if type not in ACTIONSCRIPT_TYPES: raise pyamf.EncodeError("Unknown AMF3 type 0x%02x at %d" % ( type, self.stream.tell() - 1)) self.stream.write_uchar(type) def writeFunc(self, *args, **kwargs): """ Functions cannot be serialised. """ raise pyamf.EncodeError("Callables cannot be serialised") def writeUndefined(self, d, use_references=True): """ Writes an C{pyamf.Undefined} value to the stream. @param d: The C{undefined} data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. """ self.writeType(ASTypes.UNDEFINED) def writeNull(self, n, use_references=True): """ Writes a C{null} value to the stream. @param n: The C{null} data to be encoded to the AMF3 data stream. @type n: C{null} data. @type use_references: C{bool} @param use_references: Default is C{True}. """ self.writeType(ASTypes.NULL) def writeBoolean(self, n, use_references=True): """ Writes a Boolean to the stream. @param n: The C{boolean} data to be encoded to the AMF3 data stream. @type n: C{bool} @type use_references: C{bool} @param use_references: Default is C{True}. """ if n: self.writeType(ASTypes.BOOL_TRUE) else: self.writeType(ASTypes.BOOL_FALSE) def _writeInteger(self, n): """ AMF3 integers are encoded. @param n: The integer data to be encoded to the AMF3 data stream. @type n: integer data @see: U{Parsing Integers on OSFlash } for more info. """ self.stream.write(encode_int(n)) def writeInteger(self, n, use_references=True): """ Writes an integer to the stream. @type n: integer data @param n: The integer data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. """ if n & 0xf0000000 not in [0, 0xf0000000]: self.writeNumber(n) return self.writeType(ASTypes.INTEGER) self.stream.write(encode_int(n)) def writeNumber(self, n, use_references=True): """ Writes a non integer to the stream. @type n: number data @param n: The number data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True} """ self.writeType(ASTypes.NUMBER) self.stream.write_double(n) def _writeString(self, n, use_references=True): """ Writes a raw string to the stream. @type n: C{str} or C{unicode} @param n: The string data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. """ if not isinstance(n, basestring): bytes = unicode(n).encode('utf8') n = bytes elif isinstance(n, unicode): bytes = n.encode('utf8') else: bytes = n if len(bytes) == 0: self._writeInteger(REFERENCE_BIT) return if use_references: try: ref = self.context.getStringReference(n) self._writeInteger(ref << 1) return except pyamf.ReferenceError: self.context.addString(n) self._writeInteger((len(bytes) << 1) | REFERENCE_BIT) self.stream.write(bytes) def writeString(self, n, use_references=True): """ Writes a string to the stream. If C{n} is not a unicode string, an attempt will be made to convert it. @type n: C{basestring} @param n: The string data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. """ self.writeType(ASTypes.STRING) self._writeString(n, use_references) def writeDate(self, n, use_references=True): """ Writes a C{datetime} instance to the stream. @type n: L{datetime} @param n: The C{Date} data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. """ self.writeType(ASTypes.DATE) if use_references is True: try: ref = self.context.getObjectReference(n) self._writeInteger(ref << 1) return except pyamf.ReferenceError: self.context.addObject(n) self._writeInteger(REFERENCE_BIT) ms = util.get_timestamp(n) self.stream.write_double(ms * 1000.0) def writeList(self, n, use_references=True, _use_proxies=None): """ Writes a C{tuple}, C{set} or C{list} to the stream. @type n: One of C{__builtin__.tuple}, C{__builtin__.set} or C{__builtin__.list} @param n: The C{list} data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. """ # Encode lists as ArrayCollections if _use_proxies is None: _use_proxies = self.use_proxies if _use_proxies is True: try: ref_obj = self.context.getObjectAlias(n) except pyamf.ReferenceError: proxy = ArrayCollection(n) self.context.setObjectAlias(n, proxy) ref_obj = proxy self.writeObject(ref_obj, use_references) return self.writeType(ASTypes.ARRAY) if use_references is True: try: ref = self.context.getObjectReference(n) self._writeInteger(ref << 1) return except pyamf.ReferenceError: self.context.addObject(n) self._writeInteger(len(n) << 1 | REFERENCE_BIT) self.stream.write_uchar(0x01) for x in n: self.writeElement(x) def writeDict(self, n, use_references=True, _use_proxies=None): """ Writes a C{dict} to the stream. @type n: C{__builtin__.dict} @param n: The C{dict} data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. @raise ValueError: Non C{int}/C{str} key value found in the C{dict} @raise EncodeError: C{dict} contains empty string keys. """ # Design bug in AMF3 that cannot read/write empty key strings # http://www.docuverse.com/blog/donpark/2007/05/14/flash-9-amf3-bug # for more info if n.has_key(''): raise pyamf.EncodeError("dicts cannot contain empty string keys") if _use_proxies is None: _use_proxies = self.use_proxies if _use_proxies is True: try: ref_obj = self.context.getObjectAlias(n) except pyamf.ReferenceError: dictObj = pyamf.ASObject(n) proxy = ObjectProxy(dictObj) self.context.setObjectAlias(n, proxy) ref_obj = proxy self.writeObject(ref_obj, use_references) return self.writeType(ASTypes.ARRAY) if use_references: try: ref = self.context.getObjectReference(n) self._writeInteger(ref << 1) return except pyamf.ReferenceError: self.context.addObject(n) # The AMF3 spec demands that all str based indicies be listed first keys = n.keys() int_keys = [] str_keys = [] for x in keys: if isinstance(x, (int, long)): int_keys.append(x) elif isinstance(x, (str, unicode)): str_keys.append(x) else: raise ValueError("Non int/str key value found in dict") # Make sure the integer keys are within range l = len(int_keys) for x in int_keys: if l < x <= 0: # treat as a string key str_keys.append(x) del int_keys[int_keys.index(x)] int_keys.sort() # If integer keys don't start at 0, they will be treated as strings if len(int_keys) > 0 and int_keys[0] != 0: for x in int_keys: str_keys.append(str(x)) del int_keys[int_keys.index(x)] self._writeInteger(len(int_keys) << 1 | REFERENCE_BIT) for x in str_keys: self._writeString(x) self.writeElement(n[x]) self.stream.write_uchar(0x01) for k in int_keys: self.writeElement(n[k]) def _getClassDefinition(self, obj): """ Builds a class definition based on the C{obj}. """ encoding = ObjectEncoding.DYNAMIC alias = self.context.getClassAlias(obj.__class__) if alias: if 'dynamic' in alias.metadata: encoding = ObjectEncoding.DYNAMIC elif 'static' in alias.metadata: encoding = ObjectEncoding.STATIC elif 'external' in alias.metadata: encoding = ObjectEncoding.EXTERNAL class_def = ClassDefinition(alias, encoding) return class_def def writeInstance(self, obj, use_references=True): """ Read class definition. @param obj: The class instance data to be encoded to the AMF3 data stream. @type obj: instance data @type use_references: C{bool} @param use_references: Default is C{True}. """ if obj.__class__ in (pyamf.MixedArray,): self.writeDict(obj, use_references) elif obj.__class__ in (list, set, tuple): self.writeList(obj, use_references) else: self.writeObject(obj, use_references) def writeObject(self, obj, use_references=True, _use_proxies=None): """ Writes an object to the stream. @param obj: The object data to be encoded to the AMF3 data stream. @type obj: object data @param use_references: Default is C{True}. @type use_references: C{bool} @raise EncodeError: Encoding an object in amf3 tagged as amf0 only. """ if _use_proxies is None: _use_proxies = self.use_proxies if _use_proxies is True and obj.__class__ is dict: try: ref_obj = self.context.getObjectAlias(obj) except pyamf.ReferenceError: dictObj = pyamf.ASObject(obj) proxy = ObjectProxy(dictObj) self.context.setObjectAlias(obj, proxy) ref_obj = proxy self.writeObject(ref_obj, use_references) return self.writeType(ASTypes.OBJECT) if use_references is True: try: ref = self.context.getObjectReference(obj) self._writeInteger(ref << 1) return except pyamf.ReferenceError: self.context.addObject(obj) try: ref = self.context.getClassDefinitionReference(obj) class_ref = True self._writeInteger(ref << 2 | REFERENCE_BIT) except pyamf.ReferenceError: class_def = self._getClassDefinition(obj) if class_def.alias and 'amf0' in class_def.alias.metadata: raise pyamf.EncodeError("Encoding an object in amf3 tagged as amf0 only") self.context.addClassDefinition(class_def) class_ref = False ref = 0 if class_def.encoding != ObjectEncoding.EXTERNAL: ref += len(class_def.getStaticAttrs(obj)) << 4 self._writeInteger(ref | class_def.encoding << 2 | REFERENCE_BIT << 1 | REFERENCE_BIT) self._writeString(class_def.name) else: class_def = self._getClassDefinition(obj) if class_def.encoding in (ObjectEncoding.EXTERNAL, ObjectEncoding.PROXY): obj.__writeamf__(DataOutput(self)) else: static_attrs, dynamic_attrs = class_def.getAttrs(obj, codec=self) if static_attrs is not None: attrs = class_def.getStaticAttrs(obj) if not class_ref: [self._writeString(attr) for attr in attrs] [self.writeElement(static_attrs[attr]) for attr in attrs] if class_def.encoding is ObjectEncoding.DYNAMIC and dynamic_attrs is not None: for attr, value in dynamic_attrs.iteritems(): self._writeString(attr) self.writeElement(value) self._writeString('') def writeByteArray(self, n, use_references=True): """ Writes a L{ByteArray} to the data stream. @type n: L{ByteArray} @param n: The L{ByteArray} data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. """ self.writeType(ASTypes.BYTEARRAY) if use_references: try: ref = self.context.getObjectReference(n) self._writeInteger(ref << 1) return except pyamf.ReferenceError: self.context.addObject(n) buf = str(n) l = len(buf) self._writeInteger(l << 1 | REFERENCE_BIT) self.stream.write(buf) def writeXML(self, n, use_references=True): """ Writes a XML string to the data stream. @type n: L{ET} @param n: The XML Document to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. """ try: self.context.getLegacyXMLReference(n) is_legacy = True except pyamf.ReferenceError: is_legacy = False if is_legacy is True: self.writeType(ASTypes.XML) else: self.writeType(ASTypes.XMLSTRING) if use_references: try: ref = self.context.getObjectReference(n) self._writeInteger(ref << 1) return except pyamf.ReferenceError: self.context.addObject(n) self._writeString(util.ET.tostring(n, 'utf-8'), False) def decode(stream, context=None, strict=False): """ A helper function to decode an AMF3 datastream. @type stream: L{BufferedByteStream} @param stream: AMF3 data. @type context: L{Context} @param context: Context. """ decoder = Decoder(stream, context, strict) while 1: try: yield decoder.readElement() except pyamf.EOStream: break def encode(*args, **kwargs): """ A helper function to encode an element into AMF3 format. @type args: List of args to encode. @keyword context: Any initial context to use. @type context: L{Context} @return: C{StringIO} type object containing the encoded AMF3 data. @rtype: L{BufferedByteStream} """ context = kwargs.get('context', None) buf = util.BufferedByteStream() encoder = Encoder(buf, context) for element in args: encoder.writeElement(element) return buf def _encode_int(n): """ @raise OverflowError: Out of range. """ if n & 0xf0000000 not in [0, 0xf0000000]: raise OverflowError("Out of range") bytes = '' real_value = None if n < 0: n += 0x20000000 if n > 0x1fffff: real_value = n n >>= 1 bytes += chr(0x80 | ((n >> 21) & 0xff)) if n > 0x3fff: bytes += chr(0x80 | ((n >> 14) & 0xff)) if n > 0x7f: bytes += chr(0x80 | ((n >> 7) & 0xff)) if real_value is not None: n = real_value if n > 0x1fffff: bytes += chr(n & 0xff) else: bytes += chr(n & 0x7f) return bytes def _decode_int(stream, signed=False): n = result = 0 b = stream.read_uchar() while b & 0x80 != 0 and n < 3: result <<= 7 result |= b & 0x7f b = stream.read_uchar() n += 1 if n < 3: result <<= 7 result |= b else: result <<= 8 result |= b if result & 0x10000000 != 0: if signed: result -= 0x20000000 else: result <<= 1 result += 1 return result try: from cpyamf.amf3 import encode_int except ImportError: encode_int = _encode_int try: from cpyamf.amf3 import decode_int except ImportError: decode_int = _decode_int PK":w?8pyamf/logging.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Logging utilities. @since: 0.2.0 """ logging = __import__('logging') def _get_instance_name(obj): return "%s.%s.0x%x" % ( obj.__class__.__module__, obj.__class__.__name__, id(obj)) def class_logger(cls): return logging.getLogger('%s.%s' % (cls.__module__, cls.__name__)) def instance_logger(instance): return logging.getLogger(_get_instance_name(instance)) PKĩ:x~~ pyamf/sol.pyc; La^Ic@sdZdkZdklZdZdZdZedZeeidZ dZ eid Z d e fd YZ e ZdS( s Local Shared Object implementation. Local Shared Object (LSO), sometimes known as flash cookies, is a cookie-like data entity used by the Flash Player and Gnash. The players allow web content to read and write LSO data to the computer's local drive on a per-domain basis. @see: U{Local Shared Object on WikiPedia (external) } @see: U{Local Shared Object envelope (external) } @since: 0.1.0 N(sutilss TCSOsc Cst|ti oti|}n|id}|tjotidn|i }|o|i |jotidn|id} | tjotidn|i}|i|}|idtdjotidnti|i}||_h}xinoa|ioPn|i}|i}|idtjotid n|||} iiiN(spyamfs get_encodersencodingsencodersutilsBufferedByteStreamsstreamswritesHEADER_VERSIONsstrictsTruestells length_poss write_ulongsHEADER_SIGNATUREs isinstancesnamesunicodes write_ushortslenswrite_utf8_strings PADDING_BYTEs write_ucharsvaluess iteritemssnsvs _writeStrings writeElementsseeks remaining( snamesvaluessstrictsencodingsstreamsencodersns length_possv((s)build/bdist.linux-x86_64/egg/pyamf/sol.pysencode`s0            cCs|}t}t|tot|d}t}n"t|d ot dnt |i \}}t|}x$|iD]\}}|||(sselfs __class__s__name__snamesdicts__repr__sid(sself((s)build/bdist.linux-x86_64/egg/pyamf/sol.pys__repr__s(s__name__s __module__s__doc__s__init__spyamfsAMF0ssaves__repr__(((s)build/bdist.linux-x86_64/egg/pyamf/sol.pysSOLs  (s__doc__spyamfsutilsHEADER_VERSIONsHEADER_SIGNATUREs PADDING_BYTEsTruesdecodesAMF0sencodesloadssavesdictsSOLsLSO( s PADDING_BYTEsdecodesLSOspyamfsHEADER_SIGNATUREsSOLsloadsutilsencodesHEADER_VERSIONssave((s)build/bdist.linux-x86_64/egg/pyamf/sol.pys?s   A5 PKũ:vpyamf/__init__.pyc; 2Ic@svdZdkZdklZdklZdddddgZd d d fZhZgZ hZ hZ hZ d Z d Ze efZd fdYZgZx:eiD]/Zeid oeieieqqW[defdYZeZdefdYZdefdYZdefdYZdefdYZdefdYZdefdYZdefdYZ d e!fd!YZ"d"e!fd#YZ#d$e$fd%YZ%d&efd'YZ&d(e!fd)YZ'd*e&fd+YZ(d,efd-YZ)d.efd/YZ*d0efd1YZ+e,e,e,gd2Z-d3Z.d4Z/d5Z0d6Z1d7Z2d8Z3d9Z4e e,e5d:Z6d;Z7e,e,e5d<Z8d=Z9e,e,e5d>Z:d?Z;d@Z<dAZ=dBZ>e,dCZ?dDZ@dEZAdFZBdGZCdHZDe/e>eeDe(e'dS(Is B{PyAMF} provides B{A}ction B{M}essage B{F}ormat (U{AMF}) support for Python that is compatible with the U{Flash Player}. @copyright: Copyright (c) 2007-2009 The PyAMF Project. All Rights Reserved. @contact: U{dev@pyamf.org} @see: U{http://pyamf.org} @since: October 2007 @version: 0.4.2 @status: Production/Stable N(sutil(sregister_adapterssregister_classsregister_class_loadersencodesdecodes __version__iiiis ClientTypescBs tZdZdZdZdZRS(s Typecodes used to identify AMF clients and servers. @see: U{Flash Player on WikiPedia (external) } @see: U{Flash Media Server on WikiPedia (external) } iii(s__name__s __module__s__doc__sFlash6sFlashComsFlash9(((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys ClientTypes5s s_s UndefinedTypecBstZdZRS(NcCsdSdS(Nspyamf.Undefined((sself((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys__repr__Ns(s__name__s __module__s__repr__(((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys UndefinedTypeMss BaseErrorcBstZdZRS(s[ Base AMF Error. All AMF related errors should be subclassed from this class. (s__name__s __module__s__doc__(((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys BaseErrorTs s DecodeErrorcBstZdZRS(sE Raised if there is an error in decoding an AMF data stream. (s__name__s __module__s__doc__(((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys DecodeError[s sEOStreamcBstZdZRS(s> Raised if the data stream has come to a natural end. (s__name__s __module__s__doc__(((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pysEOStream`s sReferenceErrorcBstZdZRS(s_ Raised if an AMF data stream refers to a non-existent object or string reference. (s__name__s __module__s__doc__(((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pysReferenceErrores s EncodeErrorcBstZdZRS(s Raised if the element could not be encoded to the stream. @bug: See U{Docuverse blog (external) } for more info about the empty key string array bug. (s__name__s __module__s__doc__(((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys EncodeErrorks sUnknownClassAliascBstZdZRS(sr Raised if the AMF stream specifies a class that does not have an alias. @see: L{register_class} (s__name__s __module__s__doc__(((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pysUnknownClassAliasts s BaseContextcBsVtZdZdZdZdZdZdZdZdZ dZ RS( s9 I hold the AMF context for en/decoding streams. cCsti|_|idS(N(sutilsIndexedCollectionsselfsobjectssclear(sself((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys__init__scCs|iih|_dS(s0 Completely clears the context. N(sselfsobjectssclears class_aliases(sself((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pysclears cCs|iih|_dS(s Resets the context. This is subtly different to the L{BaseContext.clear} method, which is a hard delete of the context. This method is mainly used by the L{remoting api} to handle context clearing between requests. N(sselfsobjectssclears class_aliases(sself((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pysresets cCsAy|ii|SWn&tj otd|fnXdS(sp Gets an object based on a reference. @raise ReferenceError: Unknown object reference. sUnknown object reference %rN(sselfsobjectssgetByReferencesrefsReferenceError(sselfsref((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys getObjects cCsAy|ii|SWn&tj otd|fnXdS(sw Gets a reference for an object. @raise ReferenceError: Object not a valid reference, sObject %r not a valid referenceN(sselfsobjectssgetReferenceTosobjsReferenceError(sselfsobj((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pysgetObjectReferences cCs|ii|SdS(s Adds a reference to C{obj}. @type obj: C{mixed} @param obj: The object to add to the context. @rtype: C{int} @return: Reference to C{obj}. N(sselfsobjectssappendsobj(sselfsobj((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys addObjectscCs||iijotyt||i|s6       cCs |iSdS(N(sselfsalias(sself((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys__str__scCs!d|i|it|fSdS(Ns#(sselfsaliassklasssid(sself((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys__repr__scCszt|to|i|jSnVt||io|i|ijSn/t|tti fo|i|jSnt SdS(N( s isinstancesothers basestringsselfsaliass __class__sklassstypestypess ClassTypesFalse(sselfsother((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys__eq__scCst|SdS(N(sidsself(sself((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys__hash__scCs<t|dot|id odSn|ii}t|do$|iit|ipgdjot |ii }t |ipg}| o d|i di|f}nft|t|t||}d|i di|d t| ditd |f}td |ndS( s$ This function is used to check the class being aliased to fits certain criteria. The default is to check that the __init__ constructor does not pass in arguments. @since: 0.4 @raise TypeError: C{__init__} doesn't support additional arguments s__init__sim_funcNs func_codeis%s.__init__(%s)s, s%s.__init__(%s, %s)icCs d|fS(Ns%s=%s(sx(sx((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pysss1__init__ doesn't support additional arguments: %s(shasattrsklasss__init__sim_funcs klass_funcs func_codes co_argcountslens func_defaultsslists co_varnamessargssvaluess__name__sjoinssignszips named_argssmaps TypeError(sklssklasss named_argssargsssignsvaluess klass_func((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys checkClasss$ 7 #BcCsM|tjo g}n|tjo g}nt}|itj ot}|i|in8|tjo t |dot}|i|i n|i tj oXt}|i |}|igi} |D]!} | |jo| | qq~ n|tjoxti|iD]}yt|} Wntj o qnX| i|||t\} } | tj o|i| t}n| tj o|i| t}qqWn|tjottfSng}g}x,|D]$} | |jo|i| qqWx,|D]$} | |jo|i| qqW||fSdS(Ns __slots__(s static_attrssNones dynamic_attrssFalsesmodified_attrssselfsattrssTruesextendstraverseshasattrsobjs __slots__s attr_funcs extra_attrssappends_[1]skeysutilsget_mros __class__sbasesget_class_aliassaliassUnknownClassAliass _getAttrssxsyssasda(sselfsobjs static_attrss dynamic_attrsstraverses extra_attrssmodified_attrssdasbaseskeys_[1]saliassysxssa((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys _getAttrssT    C         cCs|i|SdS(s Returns a tuple of lists, static and dynamic attrs to encode. @param codec: An optional argument that will contain the en/decoder instance calling this function. N(sselfs _getAttrssobj(sselfsobjscodec((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pysgetAttrsscCsh}h}|i|d|\}}|tjo |tjot i |}n|tj oFxC|D]7}t ||ot ||||} @ivar strict: Defines how strict the decoding should be. For the time being this relates to typed objects in the stream that do not have a registered alias. Introduced in 0.4. @type strict: C{bool} cCst|tio ||_nti||_|tjo|i|_nCt||io ||_n#t d|ii |ii f||_ dS(s< @type data: L{BufferedByteStream} @param data: Data stream. @type context: L{Context} @param context: Context. @raise TypeError: The C{context} parameter must be of type L{Context}. scontext must be of type %s.%sN( s isinstancesdatasutilsBufferedByteStreamsselfsstreamscontextsNones context_classs TypeErrors __module__s__name__sstrict(sselfsdatascontextsstrict((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys__init__us   "cCs tdS(sE @raise NotImplementedError: Override in a subclass. N(sNotImplementedError(sself((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pysreadTypescCszy|i}Wntj o tnXyt||i|}Wn&tj ot d|fnX|SdS(s Reads an AMF3 element from the data stream. @raise DecodeError: The ActionScript type is unsupported. @raise EOStream: No more data left to decode. s$Unsupported ActionScript type 0x%02xN( sselfsreadTypestypesEOFErrorsEOStreamsgetattrstype_mapsfuncsKeyErrors DecodeError(sselfsfuncstype((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys readElements ccs=yxno|iVq WWntj o tnXdS(s' @raise StopIteration: iN(sselfs readElementsEOFErrors StopIteration(sself((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys__iter__s( s__name__s __module__s__doc__s BaseContexts context_classstype_mapsNonesFalses__init__sreadTypes readElements__iter__(((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys BaseDecoderbs   sCustomTypeFunccBs tZdZdZdZRS(s Custom type mappings. cCs||_||_dS(N(sencodersselfsfunc(sselfsencodersfunc((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys__init__s cCs&|ii|i|d|idS(Nsencoder(sselfsencoders writeElementsfuncsdata(sselfsdata((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys__call__s(s__name__s __module__s__doc__s__init__s__call__(((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pysCustomTypeFuncs  s BaseEncodercBsPtZdZeZgZeeedZdZ dZ dZ dZ RS(sy Base AMF encoder. @ivar type_map: A list of types -> functions. The types is a list of possible instances or functions to call (that return a C{bool}) to determine the correct function to call to encode the data. @type type_map: C{list} @ivar context_class: Holds the class that will create context objects for the implementing C{Encoder}. @type context_class: C{type} or C{types.ClassType} @ivar stream: The underlying data stream. @type stream: L{BufferedByteStream} @ivar context: The context for the encoding. @type context: An instance of C{BaseEncoder.context_class} @ivar strict: Whether the encoder should operate in 'strict' mode. Nothing is really affected by this for the time being - its just here for flexibility. @type strict: C{bool}, default is False. cCst|tio ||_nti||_|tjo|i|_nCt||io ||_n#t d|ii |ii fh|_ ||_ dS(s@ @type data: L{BufferedByteStream} @param data: Data stream. @type context: L{Context} @param context: Context. @raise TypeError: The C{context} parameter must be of type L{Context}. scontext must be of type %s.%sN(s isinstancesdatasutilsBufferedByteStreamsselfsstreamscontextsNones context_classs TypeErrors __module__s__name__s_write_elem_func_cachesstrict(sselfsdatascontextsstrict((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys__init__s   " cCstddS(ss Not possible to encode functions. @raise EncodeError: Unable to encode function/methods. s!Unable to encode function/methodsN(s EncodeError(sselfsobj((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys writeFuncscCsxtiD]r\}}y%t||ot||SnWq tj o2t |o ||ot||Sqq Xq Wx|i D]\}}xt|D]l}y%t||ot||SnWqtj o2t |o ||ot||Sq qXqWqWtSdS(s Gets a function used to encode the data. @type data: C{mixed} @param data: Python data. @rtype: callable or C{None}. @return: The function used to encode data to the stream. N(sTYPE_MAPs iteritemsstype_sfuncs isinstancesdatasCustomTypeFuncsselfs TypeErrorscallablestype_mapstlistsmethodstsgetattrsNone(sselfsdatastype_stsfuncstlistsmethod((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys_getWriteElementFuncs(  cCsiy |i}Wn tj o|i|SnX||ijo|i||i|} @param stream: AMF data. @type encoding: C{int} @param encoding: AMF encoding type. @type context: L{AMF0 Context} or L{AMF3 Context} @param context: Context. @return: Each element in the stream. iN(s_get_decoder_classsencodingsstreamscontextsstrictsdecoders readElementsEOStream(sstreamsencodingscontextsstrictsdecoder((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pysdecode s cOs|idt}|idt}|idt}ti }t ||||}x|D]}|i|qaW|id|SdS(so A helper function to encode an element. @type element: C{mixed} @keyword element: Python data. @type encoding: C{int} @keyword encoding: AMF encoding type. @type context: L{amf0.Context} or L{amf3.Context} @keyword context: Context. @rtype: C{StringIO} @return: File-like object. sencodingscontextsstrictiN(skwargssgetsAMF0sencodingsNonescontextsFalsesstrictsutilsBufferedByteStreamsstreams_get_encoder_classsencodersargssels writeElementsseek(sargsskwargssstreamsencodingsencodersstrictscontextsel((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pysencodes  cCs#t|d|d|d|SdS(Nsdatascontextsstrict(s_get_decoder_classsencodingsdatascontextsstrict(sencodingsdatascontextsstrict((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys get_decoder;scCsa|tjodkl}|iSn&|tjodkl}|iSntd|fdS(s Get compatible decoder. @type encoding: C{int} @param encoding: AMF encoding version. @raise ValueError: AMF encoding version is unknown. @rtype: L{amf0.Decoder} or L{amf3.Decoder} @return: AMF0 or AMF3 decoder. (samf0(samf3sUnknown encoding %sN(sencodingsAMF0spyamfsamf0sDecodersAMF3samf3s ValueError(sencodingsamf0samf3((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys_get_decoder_class>s       cCs#t|d|d|d|SdS(sU Returns a subclassed instance of L{pyamf.BaseEncoder}, based on C{encoding} sdatascontextsstrictN(s_get_encoder_classsencodingsdatascontextsstrict(sencodingsdatascontextsstrict((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys get_encoderUscCsa|tjodkl}|iSn&|tjodkl}|iSntd|fdS(s Get compatible encoder. @type encoding: C{int} @param encoding: AMF encoding version. @raise ValueError: AMF encoding version is unknown. @rtype: L{amf0.Encoder} or L{amf3.Encoder} @return: AMF0 or AMF3 encoder. (samf0(samf3sUnknown encoding %sN(sencodingsAMF0spyamfsamf0sEncodersAMF3samf3s ValueError(sencodingsamf0samf3((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys_get_encoder_class\s       cCst|SdS(N(s_get_context_classsencoding(sencoding((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys get_contextsscCsa|tjodkl}|iSn&|tjodkl}|iSntd|fdS(s. Gets a compatible context class. @type encoding: C{int} @param encoding: AMF encoding version. @raise ValueError: AMF encoding version is unknown. @rtype: L{amf0.Context} or L{amf3.Context} @return: AMF0 or AMF3 context class. (samf0(samf3sUnknown encoding %sN(sencodingsAMF0spyamfsamf0sContextsAMF3samf3s ValueError(sencodingsamf0samf3((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys_get_context_classvs       cCs|id odSnyc|ido dk}n;|ido dk}n|ido dk}nt|SWntj ot|nXdS(s Loader for L{Flex} framework compatibility classes. @raise UnknownClassAlias: Trying to load unknown Flex compatibility class. sflex.Nsflex.messaging.messagessflex.messaging.iosflex.data.messages( saliass startswithspyamf.flex.messagingspyamfs pyamf.flexspyamf.flex.datas CLASS_CACHEsKeyErrorsUnknownClassAlias(saliasspyamf((s.build/bdist.linux-x86_64/egg/pyamf/__init__.pys flex_loaders    cCsd}t|tot|}n|tjotd|fnt|tiox&|D]}||qgWn |||t|           !  2 PKũ: 늂pyamf/amf0.pyc; HڝIc@sdZdkZdkZdkZdkZdklZdfdYZgZx:eiD]/Z e i d oei eie qZqZW[ dei fdYZ deifd YZd eifd YZeed Zd ZdefdYZeiedddgddgdZyedWnej on.XeddjodZeeZndS(s6 AMF0 implementation. C{AMF0} supports the basic data types used for the NetConnection, NetStream, LocalConnection, SharedObjects and other classes in the Flash Player. @see: U{Official AMF0 Specification in English (external) } @see: U{Official AMF0 Specification in Japanese (external) } @see: U{AMF documentation on OSFlash (external) } @since: 0.1.0 N(sutilsASTypescBsztZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZRS(s The AMF/RTMP data encoding format constants. @see: U{Data types on OSFlash (external) } iiiiiiiiii i i i i iiii(s__name__s __module__s__doc__sNUMBERsBOOLsSTRINGsOBJECTs MOVIECLIPsNULLs UNDEFINEDs REFERENCEs MIXEDARRAYs OBJECTTERMsARRAYsDATEs LONGSTRINGs UNSUPPORTEDs RECORDSETsXMLs TYPEDOBJECTsAMF3(((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysASTypess& s_sContextcBsDtZdZdZdZdZdZdZdZRS(s I hold the AMF0 context for en/decoding streams. AMF0 object references start at index 1. @ivar amf3_objs: A list of objects that have been decoded in L{AMF3}. @type amf3_objs: L{util.IndexedCollection} cCs#ti|_tii|dS(N(sutilsIndexedCollectionsselfs amf3_objsspyamfs BaseContexts__init__(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys__init__xscCsBtii||iit|do|iindS(s% Clears the context. s amf3_contextN(spyamfs BaseContextsclearsselfs amf3_objsshasattrs amf3_context(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysclear}s  cCs5tii|t|do|iindS(sO Resets the context. @see: L{pyamf.BaseContext.reset} s amf3_contextN(spyamfs BaseContextsresetsselfshasattrs amf3_context(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysresetscCs4y|ii|SWntj o tnXdS(sv Gets a reference for an object. @raise ReferenceError: Object reference could not be found. N(sselfs amf3_objssgetReferenceTosobjsKeyErrorsReferenceError(sselfsobj((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysgetAMF3ObjectReferences cCs|ii|SdS(s Adds an AMF3 reference to C{obj}. @type obj: C{mixed} @param obj: The object to add to the context. @rtype: C{int} @return: Reference to C{obj}. N(sselfs amf3_objssappendsobj(sselfsobj((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys addAMF3ObjectscCs)|i}ti|i|_|SdS(N(sselfs __class__scpyscopys amf3_objs(sselfscpy((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys__copy__s ( s__name__s __module__s__doc__s__init__sclearsresetsgetAMF3ObjectReferences addAMF3Objects__copy__(((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysContextns   sDecodercBsatZdZeZheid<eid<eid<ei d<ei d<ei d<ei d<ei d<eid <eid <eid <eid<eid <eid <eid} N(spyamfs Undefined(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys readUndefinedscCs|ii}ti}|ii||i |g}xb|i D]T}y8t |}|i||f||||<||=WqKtj oqKXqKW|i|SdS(sj Read mixed array. @rtype: C{dict} @return: C{dict} read from the stream N(sselfsstreams read_ulongslenspyamfs MixedArraysobjscontexts addObjects _readObjectsikeysskeysskeysintsikeysappends ValueErrorssort(sselfsikeysikeysslenskeysobj((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysreadMixedArrays"       cCsWg}|ii||ii}x't|D]}|i |i q2W|SdS(sh Read a C{list} from the data stream. @rtype: C{list} @return: C{list} N( sobjsselfscontexts addObjectsstreams read_ulongslensxrangesisappends readElement(sselfsisobjslen((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysreadLists cCs|i}t}y%ti|}|id|}Wn6ti j o'|i onti |}nX|i i ||i|||SdS(s Reads an ActionScript object from the stream and attempts to 'cast' it. @see: L{load_class} scodecN(sselfs readStrings classnamesNonesaliasspyamfs load_classscreateInstancesretsUnknownClassAliassstricts TypedObjectscontexts addObjects _readObject(sselfsrets classnamesalias((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysreadTypedObject)s  cCst|id o#dkl}|i|i_ntiti|i |iid|i }|i }|ii||SdS(s Read AMF3 elements from the data stream. @rtype: C{mixed} @return: The AMF3 element read from the stream s amf3_context(samf3sstrictN(shasattrsselfscontextspyamfsamf3sContexts amf3_contexts_get_decoder_classsAMF3sstreamsstrictsdecoders readElementselements addAMF3Object(sselfselementsamf3sdecoder((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysreadAMF3Bs - cCs#|ii}|ii|SdS(sf Reads a string from the data stream. @rtype: C{str} @return: string N(sselfsstreams read_ushortslensread_utf8_string(sselfslen((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys readStringUscCstti}t}|iid}x@|i i |jo)|i ||<|iid}q0W|i i t||o|i||d|nti||dS(Nsutf8scodec(schrsASTypess OBJECTTERMsotsdicts obj_attrssselfs readStringsencodeskeysstreamspeeks readElementsreadslensaliassapplyAttributessobjsutils set_attrs(sselfsobjsaliass obj_attrsskeysot((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys _readObject_s cCs1ti}|ii||i||SdS(sd Reads an object from the data stream. @rtype: L{ASObject} N(spyamfsASObjectsobjsselfscontexts addObjects _readObject(sselfsobj((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys readObjectqs   cCs#|ii}|ii|SdS(s9 Reads a reference from the data stream. N(sselfsstreams read_ushortsidxscontexts getObject(sselfsidx((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys readReference~scCsI|iid}|ii}ti|}|i i ||SdS(s Reads a UTC date from the data stream. Client and servers are responsible for applying their own timezones. Date: C{0x0B T7 T6} .. C{T0 Z1 Z2 T7} to C{T0} form a 64 bit Big Endian number that specifies the number of nanoseconds that have passed since 1/1/1970 0:00 to the specified time. This format is UTC 1970. C{Z1} and C{Z0} for a 16 bit Big Endian number indicating the indicated time's timezone in minutes. f1000.0N( sselfsstreams read_doublesmss read_shortstzsutils get_datetimesdscontexts addObject(sselfstzsdsms((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysreadDates cCs#|ii}|ii|SdS(s# Read UTF8 string. N(sselfsstreams read_ulongslensread_utf8_string(sselfslen((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysreadLongStringscCs6|i}tii|}|ii||SdS(s Read XML. N( sselfsreadLongStringsdatasutilsETs fromstringsxmlscontexts addObject(sselfsxmlsdata((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysreadXMLs  ('s__name__s __module__s__doc__sContexts context_classsASTypessNUMBERsBOOLsSTRINGsOBJECTsNULLs UNDEFINEDs REFERENCEs MIXEDARRAYsARRAYsDATEs LONGSTRINGs UNSUPPORTEDsXMLs TYPEDOBJECTsAMF3stype_mapsreadTypes readNumbers readBooleansreadNulls readUndefinedsreadMixedArraysreadListsreadTypedObjectsreadAMF3s readStringsNones _readObjects readObjects readReferencesreadDatesreadLongStringsreadXML(((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysDecoders&           sEncoderc BstZdZeZeieieiei ei ei ei fdfei fdfefdfeeefdfeifdfeifdfeifdfeieifdfeieifd feifd fd fd feieifdfg Zd ZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*e+dZ,dZ-dZ.dZ/dZ0dZ1dZ2d Z3d!Z4d"Z5RS(#s Encodes an AMF0 stream. @ivar use_amf3: A flag to determine whether this encoder knows about AMF3. @type use_amf3: C{bool} s writeFuncs writeNulls writeBooleans writeNumbers writeStrings writeObjectswriteMixedArrays writeArrays writeDateswriteXMLcCs |tijS(N(sxspyamfs Undefined(sx((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pyssswriteUndefinedcOs/|idt|_tii|||dS(Nsuse_amf3( skwargsspopsFalsesselfsuse_amf3spyamfs BaseEncoders__init__sargs(sselfsargsskwargs((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys__init__scCsK|tjo*tid||iidfn|ii|dS(s Writes the type to the stream. @type type: C{int} @param type: ActionScript type. @raise pyamf.EncodeError: AMF0 type is not recognized. sUnknown AMF0 type 0x%02x at %diN(stypesACTIONSCRIPT_TYPESspyamfs EncodeErrorsselfsstreamstells write_uchar(sselfstype((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys writeTypes *cCs|itidS(s Writes the L{undefined} data type to the stream. @param data: The C{undefined} data to be encoded to the AMF0 data stream. @type data: C{undefined} data N(sselfs writeTypesASTypess UNDEFINED(sselfsdata((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pyswriteUndefinedscOstiddS(s1 Functions cannot be serialised. sCallables cannot be serialisedN(spyamfs EncodeError(sselfsargsskwargs((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys writeFuncscCs|itidS(s Writes L{unsupported} data type to the stream. @param data: The C{unsupported} data to be encoded to the AMF0 data stream. @type data: C{unsupported} data N(sselfs writeTypesASTypess UNSUPPORTED(sselfsdata((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pyswriteUnsupportedscCsKy|ii||iSWntij onXtii||SdS(sr Gets a function based on the type of data. @see: L{pyamf.BaseEncoder._writeElementFunc} N( sselfscontextsgetAMF3ObjectReferencesdatas writeAMF3spyamfsReferenceErrors BaseEncoders_writeElementFunc(sselfsdata((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys_writeElementFuncs cCs|i|}|tjotid|fnOy||Wn=ttfj o n#tij o n nXdS(s Writes the data. @type data: C{mixed} @param data: The data to be encoded to the AMF0 data stream. @raise EncodeError: Cannot find encoder func. sCannot find encoder func for %rN( sselfs_writeElementFuncsdatasfuncsNonespyamfs EncodeErrorsKeyboardInterrupts SystemExit(sselfsdatasfunc((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys writeElements cCs|itidS(sl Write null type to data stream. @type n: C{None} @param n: Is ignored. N(sselfs writeTypesASTypessNULL(sselfsn((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys writeNullscCs|ii|i}|tj o d|ijo|i|dSny|i |dSWn&t i j o|ii |nX|i ti|iit|x|D]}|i|qWdS(s Write array to the stream. @type a: L{BufferedByteStream} @param a: The array data to be encoded to the AMF0 data stream. sexternalN(sselfscontexts getClassAliassas __class__saliassNonesmetadatas writeObjectswriteReferencespyamfsReferenceErrors addObjects writeTypesASTypessARRAYsstreams write_ulongslensdatas writeElement(sselfsasaliassdata((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys writeArray(s  cCs*|iti|iit|dS(s Write number to the data stream. @type n: L{BufferedByteStream} @param n: The number data to be encoded to the AMF0 data stream. N(sselfs writeTypesASTypessNUMBERsstreams write_doublesfloatsn(sselfsn((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys writeNumberDscCs?|iti|o|iidn|iiddS(s Write boolean to the data stream. @type b: L{BufferedByteStream} @param b: The boolean data to be encoded to the AMF0 data stream. iiN(sselfs writeTypesASTypessBOOLsbsstreams write_uchar(sselfsb((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys writeBooleanNs cCst|t ot|id}nt|djo|iit|n|ii t||ii |dS(Nsutf8i( s isinstancesss basestringsunicodesencodeslensselfsstreams write_ulongs write_ushortswrite(sselfss((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys _writeString\s cCst|to|id}n+t|t ot|id}nt|djo|o|iti qn|o|i i ti n|i |dS(s Write string to the data stream. @type s: L{BufferedByteStream} @param s: The string data to be encoded to the AMF0 data stream. @type writeType: C{bool} @param writeType: Write data type. sutf8iN(s isinstancesssunicodesencodes basestringslens writeTypesselfsASTypess LONGSTRINGsstreams write_ucharsSTRINGs _writeString(sselfsss writeType((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys writeStringgscCs6|ii|}|iti|ii |dS(s Write reference to the data stream. @type o: L{BufferedByteStream} @param o: The reference data to be encoded to the AMF0 data stream. N( sselfscontextsgetObjectReferencesosidxs writeTypesASTypess REFERENCEsstreams write_ushort(sselfsosidx((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pyswriteReference~scCs>x7|iD])\}}|i|t|i|q WdS(s Write C{dict} to the data stream. @type o: C{iterable} @param o: The C{dict} data to be encoded to the AMF0 data stream. N(sos iteritemsskeysvalsselfs writeStringsFalses writeElement(sselfsosvalskey((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys _writeDicts  cCsy|i|dSWn&tij o|ii|nX|iti ypt gi }|i D]2}t|dttfo||dqhqh~}|djo d}nWntj o d}nX|ii||i||idS(s Write mixed array to the data stream. @type o: L{BufferedByteStream} @param o: The mixed array data to be encoded to the AMF0 data stream. Ni(sselfswriteReferencesospyamfsReferenceErrorscontexts addObjects writeTypesASTypess MIXEDARRAYsmaxsappends_[1]sitemssys isinstancesintslongs max_indexs ValueErrorsstreams write_ulongs _writeDicts_writeEndObject(sselfsos_[1]sys max_index((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pyswriteMixedArrays  U   cCs$|iid|itidS(Ns(sselfsstreamswrites writeTypesASTypess OBJECTTERM(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys_writeEndObjectscCst}|tj o7h}x.|i|d|D]}|i|q/Wn|tjoti |}n|tjot i dn|SdS(sR @raise pyamf.EncodeError: Unable to determine object attributes. scodecs%Unable to determine object attributesN( sNones obj_attrssaliass getAttributessosselfsattrssupdatesutils get_attrsspyamfs EncodeError(sselfsosaliass obj_attrssattrs((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys_getObjectAttrss   cCs_|itjo|i|dSny|i|dSWn&tij o|ii |nX|ii |i }|t jo|itinmd|ijo|i|dSnd|ijo|itin$|iti|i|i t|i||}x7|iD])\}}|i|t|i|q$W|idS(s Write object to the stream. @type o: L{BufferedByteStream} @param o: The object data to be encoded to the AMF0 data stream. Nsamf3s anonymous(sselfsuse_amf3sTrues writeAMF3soswriteReferencespyamfsReferenceErrorscontexts addObjects getClassAliass __class__saliassNones writeTypesASTypessOBJECTsmetadatas TYPEDOBJECTs writeStringsFalses_getObjectAttrss obj_attrss iteritemsskeysvalues writeElements_writeEndObject(sselfsos obj_attrssaliassvalueskey((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys writeObjects2     cCsMti|}d}|iti|i i |d|i i |dS(s Writes a date to the data stream. @type d: Instance of C{datetime.datetime} @param d: The date to be encoded to the AMF0 data stream. if1000.0N( sutils get_timestampsdssecsstzsselfs writeTypesASTypessDATEsstreams write_doubles write_short(sselfsdstzssecs((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys writeDates cCst|itjo|i|dSn|ititi i |d}|i i t||i i|dS(s Write XML to the data stream. @type e: L{BufferedByteStream} @param e: The XML data to be encoded to the AMF0 data stream. Nsutf-8(sselfsuse_amf3sTrues writeAMF3ses writeTypesASTypessXMLsutilsETstostringsdatasstreams write_ulongslenswrite(sselfsesdata((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pyswriteXML s cCst|id o#dkl}|i|i_n|ii|ti ti |i |ii}|i ti |i|dS(s Writes an element to the datastream in L{AMF3} format. @type data: C{mixed} @param data: The data to be encoded to the AMF0 data stream. s amf3_context(samf3N(shasattrsselfscontextspyamfsamf3sContexts amf3_contexts addAMF3Objectsdatas_get_encoder_classsAMF3sstreamsencoders writeTypesASTypess writeElement(sselfsdatasencodersamf3((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys writeAMF3s $(6s__name__s __module__s__doc__sContexts context_classstypessBuiltinFunctionTypesBuiltinMethodTypes FunctionTypes GeneratorTypes ModuleTypes LambdaTypes MethodTypesNoneTypesboolsintslongsfloats StringTypesspyamfsASObjects MixedArraysListTypes TupleTypesdatetimesdatesutils is_ET_elements InstanceTypes ObjectTypestype_maps__init__s writeTypeswriteUndefineds writeFuncswriteUnsupporteds_writeElementFuncs writeElements writeNulls writeArrays writeNumbers writeBooleans _writeStringsTrues writeStringswriteReferences _writeDictswriteMixedArrays_writeEndObjects_getObjectAttrss writeObjects writeDateswriteXMLs writeAMF3(((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysEncoders2          !   *  ccsPt||d|}x4no,y|iVWqtij oPqXqWdS(s A helper function to decode an AMF0 datastream. @type stream: L{BufferedByteStream} @param stream: AMF0 datastream. @type context: L{Context} @param context: AMF0 Context. sstrictiN(sDecodersstreamscontextsstrictsdecoders readElementspyamfsEOStream(sstreamscontextsstrictsdecoder((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysdecode0scOsS|idt}ti}t||}x|D]}|i |q4W|SdS(so A helper function to encode an element into the AMF0 format. @type element: C{mixed} @keyword element: The element to encode @type context: L{Context} @keyword context: AMF0 C{Context} to use for the encoding. This holds previously referenced objects etc. @rtype: C{StringIO} @return: The encoded stream. scontextN( skwargssgetsNonescontextsutilsBufferedByteStreamsbufsEncodersencodersargsselements writeElement(sargsskwargssencoderscontextselementsbuf((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysencodeAs  s RecordSetcBsMtZdZggeedZdZdZeeeZdZ RS(s; I represent the C{RecordSet} class used in Flash Remoting to hold (amongst other things) SQL records. @ivar columns: The columns to send. @type columns: List of strings. @ivar items: The C{RecordSet} data. @type items: List of lists, the order of the data corresponds to the order of the columns. @ivar service: Service linked to the C{RecordSet}. @type service: @ivar id: The id of the C{RecordSet}. @type id: C{str} @see: U{RecordSet on OSFlash (external) } cCs(||_||_||_||_dS(N(scolumnssselfsitemssservicesid(sselfscolumnssitemssservicesid((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys__init__is   c Cstidt|iddddd|id|i}|itj o'|i hdt |id<n|i tj o#|i hd t |i <n|SdS( Ns totalCountscursorisversions initialDatas columnNamess serviceNamesnamesid( spyamfsASObjectslensselfsitemsscolumnssretsservicesNonesupdatesstrsid(sselfsret((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys_get_server_infoos!'#cCs|d|_|d|_ytd|d|_Wntj ot|_nXy|d|_Wntj ot|_nXdS(Ns columnNamess initialDatasnames serviceNamesid( svalsselfscolumnssitemssdictsservicesKeyErrorsNonesid(sselfsval((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys_set_server_info{s  cCsd|i|iif}|itj o|d|i7}n|itj o|d|i7}n|dt|7}|SdS(Ns <%s.%s objects id=%ss service=%ss at 0x%x>(sselfs __module__s __class__s__name__sretsidsNonesservice(sselfsret((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys__repr__s( s__name__s __module__s__doc__sNones__init__s_get_server_infos_set_server_infospropertys serverInfos__repr__(((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys RecordSetVs  sattrss serverInfosmetadatasamf0cCsVyt|}Wnttfj on$X||jo ||jo|Sn|SdS(sz This is a compatibility function that takes a C{float} and converts it to an C{int} if the values are equal. N(sintsxsys OverflowErrors ValueError(sxsy((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys_check_for_intssnanicsd|_SdS(Ncs;t|iiddjo|Sni|SdS(Nsnani(sstrsxslowersfindsf2sfunc(sx(sf2(s*build/bdist.linux-x86_64/egg/pyamf/amf0.pysf2s"(sf2sfunc(sfuncsf2((sf2s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys check_nans  (s__doc__sdatetimestypesscopyspyamfsutilsASTypessACTIONSCRIPT_TYPESs__dict__sxs startswithsappends BaseContextsContexts BaseDecodersDecoders BaseEncodersEncodersNonesFalsesdecodesencodesobjects RecordSetsregister_classs_check_for_intsfloats ValueErrors check_nan(sdecodes_check_for_ints check_nans RecordSetsEncoderspyamfsACTIONSCRIPT_TYPESsASTypessdatetimesutilsContextsDecodersencodesxscopystypes((s*build/bdist.linux-x86_64/egg/pyamf/amf0.pys?s6   K A C"  PKũ:6= = pyamf/amf3.pyc; Ic@s=dZdkZdkZdkZdkZdklZdklZlZe Z y e Wn e j odk lZ nXdfdYZgZx:eiD]/Zeid oeieieqqW[dZd fd YZd efd YZd efdYZdeieefdYZeieddgdefdYZdeifdYZdei fdYZ!dei"fdYZ#e$e dZ%dZ&dZ'e dZ(ydk)l*Z*Wne+j o e'Z*nXyd k)l,Z,Wne+j o e(Z,nXdS(!s* AMF3 implementation. C{AMF3} is the default serialization for U{ActionScript} 3.0 and provides various advantages over L{AMF0}, which is used for ActionScript 1.0 and 2.0. It adds support for sending C{int} and C{uint} objects as integers and supports data types that are available only in ActionScript 3.0, such as L{ByteArray} and L{ArrayCollection}. @see: U{Official AMF3 Specification in English (external) } @see: U{Official AMF3 Specification in Japanese (external) } @see: U{AMF3 documentation on OSFlash (external) } @since: 0.1.0 N(sutil(s ObjectProxysArrayCollection(sSetsASTypescBs\tZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZRS(s~ All AMF3 data types used in ActionScript 3.0. AMF represents ActionScript objects by a single byte representing type, and then by a type-specific byte array that may be of fixed length, may contain length information, or may come with its own end code. @see: U{AMF3 data types on OSFlash (external) } iiiiiiiiii i i i (s__name__s __module__s__doc__s UNDEFINEDsNULLs BOOL_FALSEs BOOL_TRUEsINTEGERsNUMBERsSTRINGsXMLsDATEsARRAYsOBJECTs XMLSTRINGs BYTEARRAY(((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysASTypes)s  s_isObjectEncodingcBs&tZdZdZdZdZdZRS(s AMF object encodings. iiii(s__name__s __module__s__doc__sSTATICsEXTERNALsDYNAMICsPROXY(((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysObjectEncodings s DataOutputcBs}tZdZdZdZdZdZdZdZdZ e dZ d Z d Z d Zd ZRS( s I am a C{StringIO} type object containing byte data from the AMF stream. ActionScript 3.0 introduced the C{flash.utils.ByteArray} class to support the manipulation of raw data in the form of an Array of bytes. I provide a set of methods for writing binary data with ActionScript 3.0. This class is the I/O counterpart to the L{DataInput} class, which reads binary data. @see: U{IDataOutput on Livedocs (external) } cCs0t|tpt||_|i|_dS(s{ @param encoder: Encoder containing the stream. @type encoder: L{amf3.Encoder} N(s isinstancesencodersEncodersAssertionErrorsselfsstream(sselfsencoder((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys__init__s cCsUt|to5|tjo|iidqQ|iidn tddS(s$ Writes a Boolean value. @type value: C{bool} @param value: A C{Boolean} value determining which byte is written. If the parameter is C{True}, C{1} is written; if C{False}, C{0} is written. @raise ValueError: Non-boolean value found. iisNon-boolean value foundN(s isinstancesvaluesboolsTruesselfsstreams write_uchars ValueError(sselfsvalue((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeBooleans  cCs|ii|dS(s= Writes a byte. @type value: C{int} N(sselfsstreams write_charsvalue(sselfsvalue((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeBytescCs|ii|dS(s} Writes an IEEE 754 double-precision (64-bit) floating point number. @type value: C{number} N(sselfsstreams write_doublesvalue(sselfsvalue((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeDoublescCs|ii|dS(s| Writes an IEEE 754 single-precision (32-bit) floating point number. @type value: C{float} N(sselfsstreams write_floatsvalue(sselfsvalue((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeFloatscCs|ii|dS(sN Writes a 32-bit signed integer. @type value: C{int} N(sselfsstreams write_longsvalue(sselfsvalue((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pyswriteIntscCs#|iit|i|dS(s Writes a multibyte string to the datastream using the specified character set. @type value: C{str} @param value: The string value to be written. @type charset: C{str} @param charset: The string denoting the character set to use. Possible character set strings include C{shift-jis}, C{cn-gb}, C{iso-8859-1} and others. @see: U{Supported character sets on Livedocs (external) } N(sselfsstreamswritesunicodesvaluesencodescharset(sselfsvaluescharset((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pyswriteMultiBytes cCs|ii||dS(s Writes an object to data stream in AMF serialized format. @param value: The object to be serialized. @type use_references: C{bool} @param use_references: N(sselfsencoders writeElementsvaluesuse_references(sselfsvaluesuse_references((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeObjectscCs|ii|dS(sy Writes a 16-bit integer. @type value: C{int} @param value: A byte value as an integer. N(sselfsstreams write_shortsvalue(sselfsvalue((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeShortscCs|ii|dS(s Writes a 32-bit unsigned integer. @type value: C{int} @param value: A byte value as an unsigned integer. N(sselfsstreams write_ulongsvalue(sselfsvalue((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pyswriteUnsignedIntscCsst|t ot|d}nti}|i||i}|i i t ||i i |dS(s7 Writes a UTF-8 string to the data stream. The length of the UTF-8 string in bytes is written first, as a 16-bit integer, followed by the bytes representing the characters of the string. @type value: C{str} @param value: The string value to be written. sutf8N(s isinstancesvaluesunicodesutilsBufferedByteStreamsbufswrite_utf8_stringsgetvaluesbytessselfsstreams write_ushortslenswrite(sselfsvaluesbytessbuf((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pyswriteUTFs    cCsCt}t|to |}nt|d}|ii|dS(s Writes a UTF-8 string. Similar to L{writeUTF}, but does not prefix the string with a 16-bit length word. @type value: C{str} @param value: The string value to be written. sutf8N(sNonesvals isinstancesvaluesunicodesselfsstreamswrite_utf8_string(sselfsvaluesval((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeUTFBytes/s  (s__name__s __module__s__doc__s__init__s writeBooleans writeBytes writeDoubles writeFloatswriteIntswriteMultiBytesTrues writeObjects writeShortswriteUnsignedIntswriteUTFs writeUTFBytes(((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys DataOutputs      s DataInputcBstZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZRS(s1 I provide a set of methods for reading binary data with ActionScript 3.0. This class is the I/O counterpart to the L{DataOutput} class, which writes binary data. @see: U{IDataInput on Livedocs (external) } cCs0t|tpt||_|i|_dS(s @param decoder: AMF3 decoder containing the stream. @type decoder: L{amf3.Decoder} N(s isinstancesdecodersDecodersAssertionErrorsselfsstream(sselfsdecoder((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys__init__Js cCsL|iid}|djotSn"|djotSn tddS(s Read C{Boolean}. @raise ValueError: Error reading Boolean. @rtype: C{bool} @return: A Boolean value, C{True} if the byte is nonzero, C{False} otherwise. isssError reading booleanN(sselfsstreamsreadsbytesFalsesTrues ValueError(sselfsbyte((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys readBooleanTs  cCs|iiSdS(s Reads a signed byte. @rtype: C{int} @return: The returned value is in the range -128 to 127. N(sselfsstreams read_char(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysreadBytefscCs|iiSdS(s Reads an IEEE 754 double-precision floating point number from the data stream. @rtype: C{number} @return: An IEEE 754 double-precision floating point number. N(sselfsstreams read_double(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys readDoubleoscCs|iiSdS(s Reads an IEEE 754 single-precision floating point number from the data stream. @rtype: C{number} @return: An IEEE 754 single-precision floating point number. N(sselfsstreams read_float(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys readFloatyscCs|iiSdS(s Reads a signed 32-bit integer from the data stream. @rtype: C{int} @return: The returned value is in the range -2147483648 to 2147483647. N(sselfsstreams read_long(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysreadIntscCs#|ii|}t||SdS(s Reads a multibyte string of specified length from the data stream using the specified character set. @type length: C{int} @param length: The number of bytes from the data stream to read. @type charset: C{str} @param charset: The string denoting the character set to use. @rtype: C{str} @return: UTF-8 encoded string. N(sselfsstreamsreadslengthsbytessunicodescharset(sselfslengthscharsetsbytes((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys readMultiBytes cCs|iiSdS(sb Reads an object from the data stream. @return: The deserialized object. N(sselfsdecoders readElement(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys readObjectscCs|iiSdS(s Reads a signed 16-bit integer from the data stream. @rtype: C{uint} @return: The returned value is in the range -32768 to 32767. N(sselfsstreams read_short(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys readShortscCs|iiSdS(s Reads an unsigned byte from the data stream. @rtype: C{uint} @return: The returned value is in the range 0 to 255. N(sselfsstreams read_uchar(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysreadUnsignedBytescCs|iiSdS(s Reads an unsigned 32-bit integer from the data stream. @rtype: C{uint} @return: The returned value is in the range 0 to 4294967295. N(sselfsstreams read_ulong(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysreadUnsignedIntscCs|iiSdS(s Reads an unsigned 16-bit integer from the data stream. @rtype: C{uint} @return: The returned value is in the range 0 to 65535. N(sselfsstreams read_ushort(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysreadUnsignedShortscCs#|ii}|ii|SdS(s Reads a UTF-8 string from the data stream. The string is assumed to be prefixed with an unsigned short indicating the length in bytes. @rtype: C{str} @return: A UTF-8 string produced by the byte representation of characters. N(sselfsstreams read_ushortslengthsread_utf8_string(sselfslength((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysreadUTFs cCs|i|dSdS(s^ Reads a sequence of C{length} UTF-8 bytes from the data stream and returns a string. @type length: C{int} @param length: The number of bytes from the data stream to read. @rtype: C{str} @return: A UTF-8 string produced by the byte representation of characters of specified C{length}. sutf-8N(sselfs readMultiByteslength(sselfslength((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys readUTFBytess (s__name__s __module__s__doc__s__init__s readBooleansreadBytes readDoubles readFloatsreadInts readMultiBytes readObjects readShortsreadUnsignedBytesreadUnsignedIntsreadUnsignedShortsreadUTFs readUTFBytes(((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys DataInput@s     s ByteArraycBs2tZdZdZdZdZdZRS(sZ I am a C{StringIO} type object containing byte data from the AMF stream. ActionScript 3.0 introduced the C{flash.utils.ByteArray} class to support the manipulation of raw data in the form of an Array of bytes. Supports C{zlib} compression. Possible uses of the C{ByteArray} class: - Creating a custom protocol to connect to a client. - Writing your own AMF/Remoting packet. - Optimizing the size of your data by using custom data types. @see: U{ByteArray on Livedocs (external) } cOss|idt|_tii|||t i|t ||it i|t ||it |_dS(Nscontext(skwargsspopsContextsselfscontextsutilsBufferedByteStreams__init__sargss DataInputsDecoders DataOutputsEncodersFalses compressed(sselfsargsskwargs((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys__init__s cCsDt|tot|i|iSnt|i|SdS(N(s isinstancesothers ByteArrayscmpsselfsgetvalue(sselfsother((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys__cmp__scCsG|i}|io)ti|}|dd|d}n|SdS(Nisi(sselfsgetvaluesbufs compressedszlibscompress(sselfsbuf((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys__str__s   cCs t|_dS(s> Forces compression of the underlying stream. N(sTruesselfs compressed(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pyscompresss(s__name__s __module__s__doc__s__init__s__cmp__s__str__scompress(((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys ByteArrays   smetadatasamf3sClassDefinitioncBstZdZeidZdZeeZdZ dZ dZ ee Z e dZe dZe dZe d ZRS( sh I contain meta relating to the class definition. @ivar alias: The alias to this class definition. If this value is C{None}, or an empty string, the class is considered to be anonymous. @type alias: L{ClassAlias} @ivar encoding: The type of encoding to use when serializing the object. @type encoding: C{int} cCs_|tdfjo t|_n3t|tio ||_nti||_||_dS(Ns(saliassNonesselfs isinstancespyamfs ClassAliassget_class_aliassencoding(sselfsaliassencoding((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys__init__ s   cCsD|itjodSnd|iijodSnt|iSdS(Nss anonymous(sselfsaliassNonesmetadatasstr(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys _get_name*s cCs2|itdfjo tiSn|iiSdS(s If C{alias} is C{None}, an L{anonymous class} is returned, otherwise the class is loaded externally. sN(sselfsaliassNonespyamfsASObjects getClassAliassklass(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys _getClass6s cCs;t|iti oti|i|_n|iSdS(s Gets the class alias that is held by this definition. @see: L{get_class_alias}. @rtype: L{ClassAlias} @return: Class alias. N(s isinstancesselfsaliasspyamfs ClassAliassget_class_alias(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys getClassAliasAscCs5t|do |iSn|i|_|iSdS(sL Gets the referenced class that is held by this definition. s_klassN(shasattrsselfs_klasss _getClass(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysgetClassNs  cCst|do |iSn|i o#t|do |iSngSn|ii|d|\}}|tjo g|_n ||_|iSdS(s Returns a list of static attributes based on C{obj}. Once built, this list is immutable. @param obj: The object to determine the static attributes from. @type obj: C{mixed}. @since: 0.4 s static_attrss __slots__scodecN( shasattrsselfs static_attrssaliassobjs __slots__sgetAttrss dynamic_attrssNone(sselfsobjscodecs static_attrss dynamic_attrs((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysgetStaticAttrs[s      cCs|itj o|ii|d|Snti|}h}x2|i |d|D]}||||<||=qUW||fSdS(sk Returns a C{tuple} containing a dict of static and dynamic attributes for C{obj}. scodecN( sselfsaliassNones getAttributessobjscodecsutils get_attrss dynamic_attrss static_attrssgetStaticAttrssa(sselfsobjscodecsas static_attrss dynamic_attrs((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysgetAttrsvs cCs@|io|iid|}n|i}|}|SdS(s) Creates a new instance. scodecN(sselfsaliasscreateInstancescodecsobjsgetClasssklass(sselfscodecsobjsklass((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pyscreateInstances    cCs;|io|ii||d|nti||dS(sN Applies a collection of attributes C{attrs} to object C{obj} scodecN(sselfsaliassapplyAttributessobjsattrsscodecsutils set_attrs(sselfsobjsattrsscodec((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysapplyAttributess (s__name__s __module__s__doc__sObjectEncodingsDYNAMICs__init__s _get_namespropertysnames _getClasss getClassAliassgetClasssklasssNonesgetStaticAttrssgetAttrsscreateInstancesapplyAttributes(((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysClassDefinitions      sContextcBstZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZRS(s. I hold the AMF3 context for en/decoding streams. @ivar strings: A list of string references. @type strings: C{list} @ivar classes: A list of L{ClassDefinition}. @type classes: C{list} @ivar legacy_xml: A list of legacy encoded XML documents. @type legacy_xml: C{list} cCsetidt|_ti|_ti|_ti|_ti|_ t i i |dS(Nsuse_hash( sutilsIndexedCollectionsTruesselfsstringssclassess class_defss legacy_xmls IndexedMapsobject_aliasesspyamfs BaseContexts__init__(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys__init__s cCsUtii||ii|ii|ii|ii|iidS(s% Clears the context. N( spyamfs BaseContextsclearsselfsstringssclassess class_defss legacy_xmlsobject_aliases(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysclears    cCsUtii||ii|ii|ii|ii|i idS(sO Resets the context. @see: L{pyamf.BaseContext.reset} N( spyamfs BaseContextsresetsselfsstringssclearsclassess class_defss legacy_xmlsobject_aliases(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysresets    cCs|ii||dS(sK Maps an object to an aliased object. @since: 0.4 N(sselfsobject_aliasessmapsobjsalias(sselfsobjsalias((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pyssetObjectAliasscCs&|ii|}|ii|SdS(sA Get an alias of an object. @since: 0.4 N(sselfsobject_aliasessgetReferenceTosobjsrefsgetMappedByReference(sselfsobjsref((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysgetObjectAliasscCsGy|ii|SWn,tij otid|fnXdS(s  Gets a string based on a reference C{ref}. @param ref: The reference index. @type ref: C{str} @raise ReferenceError: The referenced string could not be found. @rtype: C{str} @return: The referenced string. sString reference %r not foundN(sselfsstringssgetByReferencesrefspyamfsReferenceError(sselfsref((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys getStrings cCsDy|ii|SWn)tj otid|fnXdS(s Return string reference. @type s: C{str} @param s: The referenced string. @raise ReferenceError: The string reference could not be found. @return: The reference index to the string. @rtype: C{int} s!Reference for string %r not foundN(sselfsstringssgetReferenceTosss ValueErrorspyamfsReferenceError(sselfss((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysgetStringReferences cCsRt|t o tnt|djotdn|ii|SdS(s Creates a reference to C{s}. If the reference already exists, that reference is returned. @type s: C{str} @param s: The string to be referenced. @rtype: C{int} @return: The reference index. @raise TypeError: The parameter C{s} is not of C{basestring} type. @raise ValueError: Trying to store a reference to an empty string. is+Cannot store a reference to an empty stringN( s isinstancesss basestrings TypeErrorslens ValueErrorsselfsstringssappend(sselfss((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys addStrings  cCsDy|ii|SWn)tj otid|fnXdS(s Return class reference. @raise ReferenceError: The class reference could not be found. @return: Class reference. sClass reference %r not foundN(sselfs class_defssgetByReferencesrefs IndexErrorspyamfsReferenceError(sselfsref((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysgetClassDefinitions cCs7t|toGy|ii|SWqWtj o tid|i fqWXnt|t t i foGy|i i|SWq tij otid|fq Xnjt|t it ifoMy|i i|iSWq tij o tid|ifq Xntd|fdS(s Return class definition reference. @type class_def: L{ClassDefinition} or C{instance} or C{class} @param class_def: The class definition reference to be found. @raise ReferenceError: The reference could not be found. @raise TypeError: Unable to determine class. @return: The reference to C{class_def}. @rtype: C{int} s Reference for class %s not founds/Reference for class definition for %s not founds Unable to determine class for %rN(s isinstances class_defsClassDefinitionsselfs class_defssgetReferenceTosKeyErrorspyamfsReferenceErrorsklassstypestypess ClassTypesclassess InstanceTypes ObjectTypes __class__s TypeError(sselfs class_def((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysgetClassDefinitionReferences" ""cCsqy|ii|SWnVtij oGy|ii|iWnti j onX|ii|SnXdS(sn Creates a reference to C{class_def}. @param class_def: C{ClassDefinition} instance. N( sselfs class_defssgetReferenceTos class_defspyamfsReferenceErrorsclassessappendsklasssUnknownClassAlias(sselfs class_def((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysaddClassDefinition;scCs1|it|}|it|=|i|=dS(sK Removes a C{ClassDefinition} reference from this context. N(sselfs rev_classessids class_defsidxsclasses(sselfs class_defsidx((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysremoveClassDefinitionKscCsGy|ii|SWn,tij otid|fnXdS(sy Return the legacy XML reference. This is the C{flash.xml.XMLDocument} class in ActionScript 3.0 and the top-level C{XML} class in ActionScript 1.0 and 2.0. @type ref: C{int} @param ref: The reference index. @raise ReferenceError: The legacy XML reference could not be found. @return: Instance of L{ET} s!Legacy XML reference %r not foundN(sselfs legacy_xmlsgetByReferencesrefspyamfsReferenceError(sselfsref((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys getLegacyXMLTs cCsGy|ii|SWn,tij otid|fnXdS(s Return legacy XML reference. @type doc: L{ET} @param doc: The XML document to reference. @raise ReferenceError: The reference could not be found. @return: The reference to C{doc}. @rtype: C{int} s#Reference for document %r not foundN(sselfs legacy_xmlsgetReferenceTosdocspyamfsReferenceError(sselfsdoc((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysgetLegacyXMLReferenceds cCs|ii|SdS(s< Creates a reference to C{doc}. If C{doc} is already referenced that index will be returned. Otherwise a new index will be created. @type doc: L{ET} @param doc: The XML document to reference. @rtype: C{int} @return: The reference to C{doc}. N(sselfs legacy_xmlsappendsdoc(sselfsdoc((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys addLegacyXMLss cCs|iSdS(N(sselfs __class__(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys__copy__s(s__name__s __module__s__doc__s__init__sclearsresetssetObjectAliassgetObjectAliass getStringsgetStringReferences addStringsgetClassDefinitionsgetClassDefinitionReferencesaddClassDefinitionsremoveClassDefinitions getLegacyXMLsgetLegacyXMLReferences addLegacyXMLs__copy__(((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysContexts"           sDecodercBstZdZeZheid<eid<eid<ei d<ei d<ei d<ei d<ei d<eid <eid <eid <eid <eid } for the AMF3 integer data format. N(s decode_intsselfsstreamssigned(sselfssigned((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys readIntegerscsd}|\}}|o|oii|Snii|}t |d}t |djo|oii |n|SdS(sd Reads and returns a string from the stream. @type use_references: C{bool} cs(i}|d?|t@djfSdS(Nii(sselfsreadUnsignedIntegersxs REFERENCE_BIT(sx(sself(s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys readLengths sutf8iN(s readLengthslengths is_referencesuse_referencessselfscontexts getStringsstreamsreadsbufsunicodesresultslens addString(sselfsuse_referencess is_references readLengthslengthsresultsbuf((sselfs*build/bdist.linux-x86_64/egg/pyamf/amf3.pys readStrings cCso|i}|t@djo|ii|d?Sn|ii}t i |d}|ii ||SdS(sk Read date from the stream. The timezone is ignored as the date is always in UTC. iif1000.0N( sselfsreadUnsignedIntegersrefs REFERENCE_BITscontexts getObjectsstreams read_doublesmssutils get_datetimesresults addObject(sselfsresultsmssref((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysreadDates cCs`|i}|t@djo|ii|d?Sn|dL}|iid}|djoDg}|ii |xt |D]}|i |iqWnti}|ii |xg|djoY|i}y||t|} iisutf8sN(sselfsreadUnsignedIntegerssizes REFERENCE_BITscontexts getObjects readStringsencodeskeysresults addObjectsxrangesisappends readElementspyamfs MixedArrayselsstrs UnicodeError(sselfselsisresultskeyssize((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys readArrays6          cCs|t@dj}|dL}|o|ii|}n|i}|djo t }nSyt i |}Wn<t i j o-|iont it i|}nXt|d|d@}|ii||||d?fSdS(s9 Reads class definition from the stream. iissencodingiiN(srefs REFERENCE_BITs class_refsselfscontextsgetClassDefinitions class_defs readStrings class_namesNones class_aliasspyamfsget_class_aliassUnknownClassAliassstrictsTypedObjectClassAliass TypedObjectsClassDefinitionsaddClassDefinition(sselfsrefs class_names class_refs class_aliass class_def((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys_getClassDefinitionIs"     c s|tjo i}nd}d}i}|t@djo>i i |d?}|t joi |}n|Sn|dL}i|\}} }| iod| iijotidn| id}t}i i|| ititifjo|itnt| iti jo'||| ||||| |n:| iti!jo||| ||nti"d| i#||d|t joi |}n|Sd S( s Reads an object from the stream. @raise pyamf.EncodeError: Decoding an object in amf3 tagged as amf0 only is not allowed. @raise pyamf.DecodeError: Unknown object encoding. csy| oIg|_x=t|D]+}iid}|ii |qWnx!|iD]}i ||} N(sselfs_readXML(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys readXMLStringscCs|itSdS(s Read a legacy XML Document from the stream. @return: The XML Document. @rtype: L{ET} N(sselfs_readXMLsTrue(sself((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysreadXMLscCs|i}|t@djo|ii|d?Sn|ii|d?}yt i |}t }Wnt i j o t}nXt|d|i}||_ |ii||SdS(s Reads a string of data from the stream. Detects if the L{ByteArray} was compressed using C{zlib}. @see: L{ByteArray} @note: This is not supported in ActionScript 1.0 and 2.0. iiscontextN(sselfsreadUnsignedIntegersrefs REFERENCE_BITscontexts getObjectsstreamsreadsbufferszlibs decompresssTrues compressedserrorsFalses ByteArraysobjs addObject(sselfsbuffers compressedsobjsref((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys readByteArrays    (+s__name__s __module__s__doc__sContexts context_classsASTypess UNDEFINEDsNULLs BOOL_FALSEs BOOL_TRUEsINTEGERsNUMBERsSTRINGsXMLsDATEsARRAYsOBJECTs XMLSTRINGs BYTEARRAYstype_mapsNonesFalses__init__sreadTypes readUndefinedsreadNulls readBoolFalses readBoolTrues readNumbersreadUnsignedIntegersreadSignedIntegers readIntegersTrues readStringsreadDates readArrays_getClassDefinitions readObjectsreadProxyObjects_readXMLs readXMLStringsreadXMLs readByteArray(((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysDecoders.         0  E  sEncoderc BstZdZeZeieieiei ei ei ei fdfe fdfeifdfeefdfefdfeifdfefdfeieifdfeifd fd fd feieifd fg Zeeeed ZedZdZ dZ!edZ"edZ#edZ$dZ%edZ&edZ'edZ(edZ)edZ*eedZ+eedZ,dZ-edZ.eedZ/edZ0ed Z1RS(!s& Encodes an AMF3 data stream. s writeFuncs writeBooleans writeNulls writeIntegers writeNumbers writeStringswriteByteArrays writeDateswriteXMLcCs |tijS(N(sxspyamfs Undefined(sx((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pyssswriteUndefineds writeInstancecCs@tii|||||tjo t |_n ||_dS(N( spyamfs BaseEncoders__init__sselfsdatascontextsstricts use_proxiessNonesuse_proxies_default(sselfsdatascontextsstricts use_proxies((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys__init__s  cCs|i|}|tjotid|fn^y5t|tio||n||d|Wn%t t fj o n nXdS(s& Writes the data. @type data: C{mixed} @param data: The data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. @raise EncodeError: Cannot find encoder func for C{data}. sCannot find encoder func for %rsuse_referencesN( sselfs_writeElementFuncsdatasfuncsNonespyamfs EncodeErrors isinstancesCustomTypeFuncsuse_referencessKeyboardInterrupts SystemExit(sselfsdatasuse_referencessfunc((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeElements  cCsK|tjo*tid||iidfn|ii|dS(s Writes the data type to the stream. @param type: ActionScript type. @raise EncodeError: AMF3 type is not recognized. @see: L{ACTIONSCRIPT_TYPES} sUnknown AMF3 type 0x%02x at %diN(stypesACTIONSCRIPT_TYPESspyamfs EncodeErrorsselfsstreamstells write_uchar(sselfstype((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeType5s *cOstiddS(s1 Functions cannot be serialised. sCallables cannot be serialisedN(spyamfs EncodeError(sselfsargsskwargs((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeFuncCscCs|itidS(s Writes an C{pyamf.Undefined} value to the stream. @param d: The C{undefined} data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. N(sselfs writeTypesASTypess UNDEFINED(sselfsdsuse_references((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pyswriteUndefinedIscCs|itidS(s Writes a C{null} value to the stream. @param n: The C{null} data to be encoded to the AMF3 data stream. @type n: C{null} data. @type use_references: C{bool} @param use_references: Default is C{True}. N(sselfs writeTypesASTypessNULL(sselfsnsuse_references((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeNullSscCs/|o|itin|itidS(s Writes a Boolean to the stream. @param n: The C{boolean} data to be encoded to the AMF3 data stream. @type n: C{bool} @type use_references: C{bool} @param use_references: Default is C{True}. N(snsselfs writeTypesASTypess BOOL_TRUEs BOOL_FALSE(sselfsnsuse_references((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeBoolean^scCs|iit|dS(s AMF3 integers are encoded. @param n: The integer data to be encoded to the AMF3 data stream. @type n: integer data @see: U{Parsing Integers on OSFlash } for more info. N(sselfsstreamswrites encode_intsn(sselfsn((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys _writeIntegerls cCsV|d@ddgjo|i|dSn|iti|iit|dS(s Writes an integer to the stream. @type n: integer data @param n: The integer data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. IiN( snsselfs writeNumbers writeTypesASTypessINTEGERsstreamswrites encode_int(sselfsnsuse_references((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeIntegerys  cCs$|iti|ii|dS(s Writes a non integer to the stream. @type n: number data @param n: The number data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True} N(sselfs writeTypesASTypessNUMBERsstreams write_doublesn(sselfsnsuse_references((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeNumberscCst|t ot|id}|}n*t|to|id}n|}t|djo|it dSn|oXy+|i i |}|i|d>dSWqtij o|i i|qXn|it|d>t B|ii|dS(s Writes a raw string to the stream. @type n: C{str} or C{unicode} @param n: The string data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. sutf8iNi(s isinstancesns basestringsunicodesencodesbytesslensselfs _writeIntegers REFERENCE_BITsuse_referencesscontextsgetStringReferencesrefspyamfsReferenceErrors addStringsstreamswrite(sselfsnsuse_referencessbytessref((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys _writeStrings&  cCs$|iti|i||dS(sH Writes a string to the stream. If C{n} is not a unicode string, an attempt will be made to convert it. @type n: C{basestring} @param n: The string data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. N(sselfs writeTypesASTypessSTRINGs _writeStringsnsuse_references(sselfsnsuse_references((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeStrings cCs|iti|tjoXy+|ii|}|i |d>dSWqut i j o|ii |quXn|i tti|}|ii|ddS(s Writes a C{datetime} instance to the stream. @type n: L{datetime} @param n: The C{Date} data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. iNf1000.0(sselfs writeTypesASTypessDATEsuse_referencessTruescontextsgetObjectReferencesnsrefs _writeIntegerspyamfsReferenceErrors addObjects REFERENCE_BITsutils get_timestampsmssstreams write_double(sselfsnsuse_referencessrefsms((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeDates  cCsU|tjo |i}n|tjoly|ii|}Wn;t i j o,t |}|ii |||}nX|i||dSn|iti|tjoXy+|ii|}|i|d>dSWqt i j o|ii|qXn|it|d>tB|iidx|D]}|i|q:WdS(sM Writes a C{tuple}, C{set} or C{list} to the stream. @type n: One of C{__builtin__.tuple}, C{__builtin__.set} or C{__builtin__.list} @param n: The C{list} data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. Ni(s _use_proxiessNonesselfs use_proxiessTruescontextsgetObjectAliassnsref_objspyamfsReferenceErrorsArrayCollectionsproxyssetObjectAliass writeObjectsuse_referencess writeTypesASTypessARRAYsgetObjectReferencesrefs _writeIntegers addObjectslens REFERENCE_BITsstreams write_ucharsxs writeElement(sselfsnsuse_referencess _use_proxiessrefsref_objsproxysx((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeLists2       cCs|idotidn|tjo |i}n|tjo{y|i i |}WnJti j o;ti |}t|} |i i|| | }nX|i||dSn|iti|oXy+|i i|}|i|d>dSWq4ti j o|i i|q4Xn|i}g} g}xh|D]`} t| t t!fo| i"| qSt| t#t$fo|i"| qSt%dqSWt&| } xM| D]E} | | jo djno!|i"| | | i(| =qqW| i)t&| djo| ddjo8x5| D])} |i"t#| | | i(| =qHWn|it&| d>t*Bx,|D]$} |i+| |i,|| qW|i-i.dx| D]} |i,|| qWdS(s Writes a C{dict} to the stream. @type n: C{__builtin__.dict} @param n: The C{dict} data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. @raise ValueError: Non C{int}/C{str} key value found in the C{dict} @raise EncodeError: C{dict} contains empty string keys. ss&dicts cannot contain empty string keysNis#Non int/str key value found in dicti(0snshas_keyspyamfs EncodeErrors _use_proxiessNonesselfs use_proxiessTruescontextsgetObjectAliassref_objsReferenceErrorsASObjectsdictObjs ObjectProxysproxyssetObjectAliass writeObjectsuse_referencess writeTypesASTypessARRAYsgetObjectReferencesrefs _writeIntegers addObjectskeyssint_keyssstr_keyssxs isinstancesintslongsappendsstrsunicodes ValueErrorslenslsindexssorts REFERENCE_BITs _writeStrings writeElementsstreams write_ucharsk(sselfsnsuse_referencess _use_proxiessref_objsdictObjsstr_keyssrefskeyssint_keyssproxyskslsx((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeDict sl          $ cCsti}|ii|i}|o[d|i jo ti}qd|i jo ti }qd|i jo ti }qnt ||}|SdS(s@ Builds a class definition based on the C{obj}. sdynamicsstaticsexternalN(sObjectEncodingsDYNAMICsencodingsselfscontexts getClassAliassobjs __class__saliassmetadatasSTATICsEXTERNALsClassDefinitions class_def(sselfsobjsencodingsaliass class_def((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys_getClassDefinition`s   cCsk|itifjo|i||n>|ittt fjo|i ||n|i ||dS(s Read class definition. @param obj: The class instance data to be encoded to the AMF3 data stream. @type obj: instance data @type use_references: C{bool} @param use_references: Default is C{True}. N( sobjs __class__spyamfs MixedArraysselfs writeDictsuse_referencesslistssetstuples writeLists writeObject(sselfsobjsuse_references((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeInstancets cCs|tjo |i}n|tjo |itjo{y|ii |}WnJt i j o;t i |}t|} |ii|| | }nX|i||dSn|iti|tjoXy+|ii|}|i|d>dSWq't i j o|ii|q'Xny1|ii|}t}|i|d>tBWnt i j o|i|} | i od| i i!jot i"dn|ii#| t$}d}| i%t&i'jo!|t(| i)|d>7}n|i|| i%d>Btd>BtB|i*| i+nX|i|} | i%t&i't&i,fjo|i-t.|n| i/|d|\}} |tj o| i)|}| o2gi3}|D]} ||i*| q~ngi3}|D]} ||i6|| q~n| i%t&i7jo | tj oHx4| i8D]&\} } |i*| |i6| qJW|i*d ndS( sA Writes an object to the stream. @param obj: The object data to be encoded to the AMF3 data stream. @type obj: object data @param use_references: Default is C{True}. @type use_references: C{bool} @raise EncodeError: Encoding an object in amf3 tagged as amf0 only. Niisamf0s.Encoding an object in amf3 tagged as amf0 onlyiiscodecs(:s _use_proxiessNonesselfs use_proxiessTruesobjs __class__sdictscontextsgetObjectAliassref_objspyamfsReferenceErrorsASObjectsdictObjs ObjectProxysproxyssetObjectAliass writeObjectsuse_referencess writeTypesASTypessOBJECTsgetObjectReferencesrefs _writeIntegers addObjectsgetClassDefinitionReferences class_refs REFERENCE_BITs_getClassDefinitions class_defsaliassmetadatas EncodeErrorsaddClassDefinitionsFalsesencodingsObjectEncodingsEXTERNALslensgetStaticAttrss _writeStringsnamesPROXYs __writeamf__s DataOutputsgetAttrss static_attrss dynamic_attrssattrssappends_[1]sattrs writeElementsDYNAMICs iteritemssvalue(sselfsobjsuse_referencess _use_proxiessref_objs static_attrssdictObjsattrssrefs class_defsproxys dynamic_attrssattrsvalues class_refs_[1]((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys writeObjectsf      !$ 26   cCs|iti|oXy+|ii|}|i |d>dSWqot i j o|ii |qoXnt |}t|}|i |d>tB|ii|dS(s Writes a L{ByteArray} to the data stream. @type n: L{ByteArray} @param n: The L{ByteArray} data to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. iN(sselfs writeTypesASTypess BYTEARRAYsuse_referencesscontextsgetObjectReferencesnsrefs _writeIntegerspyamfsReferenceErrors addObjectsstrsbufslensls REFERENCE_BITsstreamswrite(sselfsnsuse_referencessbufslsref((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pyswriteByteArrays  cCsy|ii|t}Wntij o t}nX|tjo|i t i n|i t i |oXy+|ii|}|i|d>dSWqtij o|ii|qXn|itii|dtdS(s Writes a XML string to the data stream. @type n: L{ET} @param n: The XML Document to be encoded to the AMF3 data stream. @type use_references: C{bool} @param use_references: Default is C{True}. iNsutf-8(sselfscontextsgetLegacyXMLReferencesnsTrues is_legacyspyamfsReferenceErrorsFalses writeTypesASTypessXMLs XMLSTRINGsuse_referencessgetObjectReferencesrefs _writeIntegers addObjects _writeStringsutilsETstostring(sselfsnsuse_referencess is_legacysref((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pyswriteXMLs"   (2s__name__s __module__s__doc__sContexts context_classstypessBuiltinFunctionTypesBuiltinMethodTypes FunctionTypes GeneratorTypes ModuleTypes LambdaTypes MethodTypesboolsNoneTypesintslongsfloats StringTypess ByteArraysdatetimesdatesutils is_ET_elements InstanceTypes ObjectTypestype_mapsNonesFalses__init__sTrues writeElements writeTypes writeFuncswriteUndefineds writeNulls writeBooleans _writeIntegers writeIntegers writeNumbers _writeStrings writeStrings writeDates writeLists writeDicts_getClassDefinitions writeInstances writeObjectswriteByteArrayswriteXML(((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysEncoders.       " ,V  R ccsMt|||}x4no,y|iVWqtij oPqXqWdS(s A helper function to decode an AMF3 datastream. @type stream: L{BufferedByteStream} @param stream: AMF3 data. @type context: L{Context} @param context: Context. iN(sDecodersstreamscontextsstrictsdecoders readElementspyamfsEOStream(sstreamscontextsstrictsdecoder((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysdecodescOsS|idt}ti}t||}x|D]}|i |q4W|SdS(sC A helper function to encode an element into AMF3 format. @type args: List of args to encode. @keyword context: Any initial context to use. @type context: L{Context} @return: C{StringIO} type object containing the encoded AMF3 data. @rtype: L{BufferedByteStream} scontextN( skwargssgetsNonescontextsutilsBufferedByteStreamsbufsEncodersencodersargsselements writeElement(sargsskwargssencoderscontextselementsbuf((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pysencode s  cCs=|d@ddgjotdnd}t}|djo|d7}n|djo0|}|dL}|td|d ?d @B7}n|d jo |td|d ?d @B7}n|d jo |td|d?d @B7}n|tj o |}n|djo|t|d @7}n|t|d @7}|SdS(s- @raise OverflowError: Out of range. Iis Out of rangesi iiiiii?iiiN(sns OverflowErrorsbytessNones real_valueschr(sns real_valuesbytes((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys _encode_int3s*           cCsd}}|i}xQ|d@djo |djo2|dK}||d@O}|i}|d7}qW|djo|dK}||O}nS|dK}||O}|d@djo-|o|d 8}q|dK}|d7}n|SdS( Niiiiiiiii (snsresultsstreams read_ucharsbssigned(sstreamssignedsresultsbsn((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys _decode_intUs&         (s encode_int(s decode_int(-s__doc__stypessdatetimeszlibspyamfsutils pyamf.flexs ObjectProxysArrayCollectionsFalsesuse_proxies_defaultssets NameErrorssetssSetsASTypessACTIONSCRIPT_TYPESs__dict__sxs startswithsappends REFERENCE_BITsObjectEncodingsobjects DataOutputs DataInputsBufferedByteStreams ByteArraysregister_classsClassDefinitions BaseContextsContexts BaseDecodersDecoders BaseEncodersEncodersNonesdecodesencodes _encode_ints _decode_ints cpyamf.amf3s encode_ints ImportErrors decode_int(s ObjectProxys ByteArrayssetspyamfsdatetimes _encode_intsdecodes decode_ints REFERENCE_BITs DataInputsEncodersDecodersencodeszlibs encode_intsClassDefinitionsObjectEncodingsutils _decode_intsContextsArrayCollectionstypessuse_proxies_defaultsACTIONSCRIPT_TYPESsASTypess DataOutputsx((s*build/bdist.linux-x86_64/egg/pyamf/amf3.pys?sR   U /{  "  PKũ:E^^pyamf/logging.pyc; La^Ic@s1dZedZdZdZdZdS(s# Logging utilities. @since: 0.2.0 sloggingcCs'd|ii|iit|fSdS(Ns %s.%s.0x%x(sobjs __class__s __module__s__name__sid(sobj((s-build/bdist.linux-x86_64/egg/pyamf/logging.pys_get_instance_name scCs!tid|i|ifSdS(Ns%s.%s(sloggings getLoggersclss __module__s__name__(scls((s-build/bdist.linux-x86_64/egg/pyamf/logging.pys class_loggerscCstit|SdS(N(sloggings getLoggers_get_instance_namesinstance(sinstance((s-build/bdist.linux-x86_64/egg/pyamf/logging.pysinstance_loggersN(s__doc__s __import__sloggings_get_instance_names class_loggersinstance_logger(sinstance_loggers class_loggersloggings_get_instance_name((s-build/bdist.linux-x86_64/egg/pyamf/logging.pys?s   PKxK:o@  pyamf/adapters/_decimal.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Adapter for the C{decimal} module. @since: 0.4 """ import decimal import pyamf def convert_Decimal(x, encoder): """ Called when an instance of L{decimal.Decimal} is about to be encoded to an AMF stream. @param x: The L{decimal.Decimal} instance to encode. @param encoder: The L{pyamf.BaseEncoder} instance about to perform the operation. @return: If the encoder is in 'strict' mode then C{x} will be converted to a float. Otherwise an L{pyamf.EncodeError} with a friendly message is raised. """ if encoder is not None and isinstance(encoder, pyamf.BaseEncoder): if encoder.strict is False: return float(x) raise pyamf.EncodeError('Unable to encode decimal.Decimal instances as ' 'there is no way to guarantee exact conversion. Use strict=False to ' 'convert to a float.') if hasattr(decimal, 'Decimal'): pyamf.add_type(decimal.Decimal, convert_Decimal) PK":0^^pyamf/adapters/_sets.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Adapter for the stdlib C{sets} module. @since: 0.4 """ import sets import pyamf from pyamf.adapters import util if hasattr(sets, 'ImmutableSet'): pyamf.add_type(sets.ImmutableSet, util.to_tuple) if hasattr(sets, 'Set'): pyamf.add_type(sets.Set, util.to_tuple) PKxK:ppyamf/adapters/util.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Useful helpers for adapters. @since: 0.4 """ import __builtin__ if not hasattr(__builtin__, 'set'): from sets import Set as set def to_list(obj, encoder): """ Converts an arbitrary object C{obj} to a list. @rtype: L{list} """ return list(obj) def to_dict(obj, encoder): """ Converts an arbitrary object C{obj} to a dict. @rtype: L{dict} """ return dict(obj) def to_set(obj, encoder): """ Converts an arbitrary object C{obj} to a set. @rtype: L{set} """ return set(obj) def to_tuple(x, encoder): """ Converts an arbitrary object C{obj} to a tuple. @rtype: L{tuple} """ return tuple(x) PKS:C(vv)pyamf/adapters/_django_db_models_query.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Django query adapter module. Sets up basic type mapping and class mappings for a Django models. @see: U{Django Project} @since: 0.1b """ from django.db.models import query import pyamf from pyamf.adapters import util pyamf.add_type(query.QuerySet, util.to_list) PK[K:6Qفpyamf/adapters/__init__.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ The adapter package provides additional functionality for other Python packages. This includes registering classes, setting up type maps etc. @since: 0.1.0 """ import os.path, glob from pyamf.util import imports class PackageImporter(object): """ Package importer used for lazy module loading. """ def __init__(self, name): self.name = name def __call__(self, mod): __import__('%s.%s' % ('pyamf.adapters', self.name)) adapters_registered = False def register_adapters(): global adapters_registered if adapters_registered is True: return try: import pkg_resources packageDir = pkg_resources.resource_filename('pyamf', 'adapters') except: packageDir = os.path.dirname(__file__) for f in glob.glob(os.path.join(packageDir, '*.py')): mod = os.path.basename(f).split(os.path.extsep, 1)[0] if mod == '__init__' or not mod.startswith('_'): continue try: register_adapter(mod[1:].replace('_', '.'), PackageImporter(mod)) except ImportError: pass adapters_registered = True def register_adapter(mod, func): """ Registers a callable to be executed when a module is imported. If the module already exists then the callable will be executed immediately. You can register the same module multiple times, the callables will be executed in the order they were registered. The root module must exist (i.e. be importable) otherwise an C{ImportError} will be thrown. @param mod: The fully qualified module string, as used in the imports statement. E.g. 'foo.bar.baz'. The string must map to a module otherwise the callable will not fire. @type mod: C{str} @param func: The function to call when C{mod} is imported. This function must take one arg, the newly imported C{module} object. @type func: callable @raise TypeError: C{func} must be callable """ if not callable(func): raise TypeError('func must be callable') imports.whenImported(str(mod), func) PK[K:p*pyamf/adapters/_django_db_models_fields.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ C{django.db.models.fields} adapter module. @see: U{Django Project} @since: 0.4 """ from django.db.models import fields import pyamf def convert_NOT_PROVIDED(x, encoder): """ @rtype: L{Undefined} """ return pyamf.Undefined pyamf.add_type(lambda x: x is fields.NOT_PROVIDED, convert_NOT_PROVIDED) PK,j: >((+pyamf/adapters/_django_utils_translation.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ C{django.utils.translation} adapter module. @see: U{Django Project} @since: 0.5 """ from django.utils.translation import ugettext_lazy import pyamf def convert_lazy(l, encoder=None): if l.__class__._delegate_unicode: return unicode(l) if l.__class__._delegate_str: return str(l) raise ValueError('Don\'t know how to convert lazy value %s' % (repr(l),)) pyamf.add_type(type(ugettext_lazy('foo')), convert_lazy) PKi:kWRRpyamf/adapters/_sqlalchemy.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ SQLAlchemy adapter module. @see: U{SQLAlchemy homepage (external)} @since: 0.4 """ import sqlalchemy from sqlalchemy.orm import collections try: from sqlalchemy.orm import class_mapper, object_mapper except ImportError: from sqlalchemy.orm.util import class_mapper, object_mapper import pyamf from pyamf.adapters import util UnmappedInstanceError = None try: class_mapper(dict) except Exception, e: UnmappedInstanceError = e.__class__ class SaMappedClassAlias(pyamf.ClassAlias): KEY_ATTR = 'sa_key' LAZY_ATTR = 'sa_lazy' EXCLUDED_ATTRS = [ '_sa_instance_state', '_sa_session_id', '_state', '_entity_name', '_instance_key', '_sa_class_manager', '_sa_adapter', '_sa_appender', '_sa_instrumented', '_sa_iterator', '_sa_remover', '_sa_initiator', ] def _getMapper(self, obj): """ Returns C{sqlalchemy.orm.mapper.Mapper} object. """ if hasattr(self, 'primary_mapper'): return self.primary_mapper try: self.primary_mapper = object_mapper(obj) except UnmappedInstanceError: self.primary_mapper = None return self.primary_mapper def getAttrs(self, obj, *args, **kwargs): """ Returns a C{tuple} containing 2 lists. The 1st is a list of allowed static attribute names, and the 2nd is a list of allowed dynamic attribute names. """ mapper = self._getMapper(obj) if mapper is None: return pyamf.ClassAlias.getAttrs(self, obj, *args, **kwargs) if not hasattr(self, 'static_attrs'): self.static_attrs = [self.KEY_ATTR, self.LAZY_ATTR] self.properties = [] for prop in mapper.iterate_properties: self.static_attrs.append(prop.key) for key, prop in self.klass.__dict__.iteritems(): if isinstance(prop, property): self.properties.append(key) self.static_attrs.append(key) dynamic_attrs = [] for key in obj.__dict__.keys(): if key in self.EXCLUDED_ATTRS: continue if key not in self.static_attrs: dynamic_attrs.append(key) return self.static_attrs, dynamic_attrs def getAttributes(self, obj, *args, **kwargs): """ Returns a C{tuple} containing a dict of static and dynamic attributes for C{obj}. """ mapper = self._getMapper(obj) if mapper is None: return pyamf.ClassAlias.getAttributes(self, obj, *args, **kwargs) static_attrs = {} dynamic_attrs = {} lazy_attrs = [] static_attr_names, dynamic_attr_names = self.getAttrs(obj) # primary_key_from_instance actually changes obj.__dict__ if # primary key properties do not already exist in obj.__dict__ static_attrs[self.KEY_ATTR] = mapper.primary_key_from_instance(obj) for attr in static_attr_names: if attr in obj.__dict__ or attr in self.properties: static_attrs[attr] = getattr(obj, attr) continue if attr in [self.KEY_ATTR, self.LAZY_ATTR]: continue # attrs here are lazy but have not been loaded from the db yet .. lazy_attrs.append(attr) static_attrs[attr] = pyamf.Undefined for attr in dynamic_attr_names: if attr in obj.__dict__: dynamic_attrs[attr] = getattr(obj, attr) static_attrs[self.LAZY_ATTR] = lazy_attrs return static_attrs, dynamic_attrs def applyAttributes(self, obj, attrs, *args, **kwargs): """ Add decoded attributes to instance. """ mapper = self._getMapper(obj) if mapper is None: pyamf.ClassAlias.applyAttributes(self, obj, attrs, *args, **kwargs) return # Delete lazy-loaded attrs. # # Doing it this way ensures that lazy-loaded attributes are not # attached to the object, even if there is a default value specified # in the __init__ method. # # This is the correct behavior, because SQLAlchemy ignores __init__. # So, an object retreived from a DB with SQLAlchemy will not have a # lazy-loaded value, even if __init__ specifies a default value. if self.LAZY_ATTR in attrs: obj_state = None if hasattr(sqlalchemy.orm.attributes, 'instance_state'): obj_state = sqlalchemy.orm.attributes.instance_state(obj) for lazy_attr in attrs[self.LAZY_ATTR]: if lazy_attr in obj.__dict__: # Delete directly from the dict, so # SA callbacks are not triggered. del obj.__dict__[lazy_attr] # Delete from committed_state so # SA thinks this attribute was never modified. # # If the attribute was set in the __init__ method, # SA will think it is modified and will try to update # it in the database. if obj_state is not None: if lazy_attr in obj_state.committed_state: del obj_state.committed_state[lazy_attr] if lazy_attr in obj_state.dict: del obj_state.dict[lazy_attr] if lazy_attr in attrs: del attrs[lazy_attr] del attrs[self.LAZY_ATTR] if self.KEY_ATTR in attrs: del attrs[self.KEY_ATTR] for key, prop in self.klass.__dict__.iteritems(): if isinstance(prop, property) and key in attrs.keys(): if prop.fset is None: del attrs[key] pyamf.util.set_attrs(obj, attrs) def is_class_sa_mapped(klass): """ @rtype: C{bool} """ if not isinstance(klass, type): klass = type(klass) try: class_mapper(klass) except UnmappedInstanceError: return False return True pyamf.register_alias_type(SaMappedClassAlias, is_class_sa_mapped) pyamf.add_type(collections.InstrumentedList, util.to_list) pyamf.add_type(collections.InstrumentedDict, util.to_dict) pyamf.add_type(collections.InstrumentedSet, util.to_set) PK,j: (pyamf/adapters/_django_db_models_base.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ C{django.db.models} adapter module. @see: U{Django Project} @since: 0.4.1 """ from django.db.models.base import Model from django.db.models import fields from django.db.models.fields import related import datetime import pyamf class DjangoClassAlias(pyamf.ClassAlias): def getAttrs(self, obj, codec=None): static_attrs, dynamic_attrs = [], [] if hasattr(self, 'static_attrs'): static_attrs = self.static_attrs else: static_attrs = self.static_attrs = [] self.fields = {} for x in obj._meta.fields: if x.name not in static_attrs: self.fields[x.name] = x static_attrs.append(x.name) for k, v in self.klass.__dict__.iteritems(): if isinstance(v, property): static_attrs.append(k) elif isinstance(v, related.ReverseManyRelatedObjectsDescriptor): if k not in static_attrs: self.fields[k] = v.field static_attrs.append(k) return static_attrs, dynamic_attrs def _encodeValue(self, field, value): if value is fields.NOT_PROVIDED: return pyamf.Undefined # deal with dates .. if isinstance(field, fields.DateTimeField): return value elif isinstance(field, fields.DateField): return datetime.datetime(value.year, value.month, value.day, 0, 0, 0) elif isinstance(field, fields.TimeField): return datetime.datetime(1970, 1, 1, value.hour, value.minute, value.second, value.microsecond) return value def _decodeValue(self, field, value): if value is pyamf.Undefined: return fields.NOT_PROVIDED # deal with dates if isinstance(field, fields.DateTimeField): return value elif isinstance(field, fields.DateField): return datetime.date(value.year, value.month, value.day) elif isinstance(field, fields.TimeField): return datetime.time(value.hour, value.minute, value.second, value.microsecond) return value def getAttributes(self, obj, codec=None): from django.db import models san, dan = self.getAttrs(obj) static_attrs, dynamic_attrs = {}, {} for name in san: if name not in self.fields.keys(): static_attrs[name] = getattr(obj, name) else: prop = self.fields[name] if isinstance(prop, related.ManyToManyField): static_attrs[name] = [x for x in getattr(obj, name).all()] elif isinstance(prop, models.ForeignKey): if '_%s_cache' % name in obj.__dict__: static_attrs[name] = getattr(obj, name) else: static_attrs[name] = None else: static_attrs[name] = self._encodeValue(prop, getattr(obj, name)) return static_attrs, dynamic_attrs def applyAttributes(self, obj, attrs, codec=None): if not hasattr(self, 'static_attrs'): self.getAttrs(obj) for n, f in self.fields.iteritems(): attrs[f.attname] = self._decodeValue(f, attrs[n]) for f in self.klass.__dict__: prop = self.klass.__dict__[f] if isinstance(prop, property) and f in attrs.keys(): if prop.fset is None: del attrs[f] return pyamf.ClassAlias.applyAttributes(self, obj, attrs) pyamf.register_alias_type(DjangoClassAlias, Model) PK,j:ӶQ/Q/*pyamf/adapters/_google_appengine_ext_db.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Google App Engine adapter module. Sets up basic type mapping and class mappings for using the Datastore API in Google App Engine. @see: U{Datastore API on Google App Engine (external) } @since: 0.3.1 """ from google.appengine.ext import db import datetime import pyamf from pyamf.util import imports from pyamf.adapters import util class ModelStub(object): """ This class represents a L{db.Model} or L{db.Expando} class as the typed object is being read from the AMF stream. Once the attributes have been read from the stream and through the magic of Python, the instance of this class will be converted into the correct type. @ivar klass: The referenced class either L{db.Model} or L{db.Expando}. This is used so we can proxy some of the method calls during decoding. @type klass: L{db.Model} or L{db.Expando} @see: L{DataStoreClassAlias.applyAttributes} """ def __init__(self, klass): self.klass = klass def properties(self): return self.klass.properties() def dynamic_properties(self): return [] class GAEReferenceCollection(dict): """ This helper class holds a dict of klass to key/objects loaded from the Datastore. @since: 0.4.1 """ def _getClass(self, klass): if not issubclass(klass, (db.Model, db.Expando)): raise TypeError('expected db.Model/db.Expando class, got %s' % (klass,)) if klass not in self.keys(): self[klass] = {} return self[klass] def getClassKey(self, klass, key): """ Return an instance based on klass/key. If an instance cannot be found then L{KeyError} is raised. @param klass: The class of the instance. @param key: The key of the instance. @return: The instance linked to the C{klass}/C{key}. @rtype: Instance of L{klass}. """ if not isinstance(key, basestring): raise TypeError('basestring type expected for test, got %s' % (repr(key),)) d = self._getClass(klass) return d[key] def addClassKey(self, klass, key, obj): """ Adds an object to the collection, based on klass and key. @param klass: The class of the object. @param key: The datastore key of the object. @param obj: The loaded instance from the datastore. """ if not isinstance(key, basestring): raise TypeError('basestring type expected for test, got %s' % (repr(key),)) d = self._getClass(klass) d[key] = obj class DataStoreClassAlias(pyamf.ClassAlias): """ This class contains all the business logic to interact with Google's Datastore API's. Any L{db.Model} or L{db.Expando} classes will use this class alias for encoding/decoding. We also add a number of indexes to the encoder context to aggressively decrease the number of Datastore API's that we need to complete. """ # The name of the attribute used to represent the key KEY_ATTR = '_key' def getAttrs(self, obj, codec=None): """ @since: 0.4 """ if not hasattr(self, 'static_attrs'): self.static_attrs = obj.properties().keys() self.static_attrs.insert(0, DataStoreClassAlias.KEY_ATTR) for k, v in self.klass.__dict__.iteritems(): if isinstance(v, property): self.static_attrs.append(k) dynamic_attrs = obj.dynamic_properties() for k, v in obj.__dict__.iteritems(): if k.startswith('_'): continue if k not in self.static_attrs: dynamic_attrs.append(k) return self.static_attrs, dynamic_attrs def getAttributes(self, obj, codec=None): static_attrs = {} dynamic_attrs = {} static_attrs_names, dynamic_attrs_names = self.getAttrs(obj, codec=codec) gae_objects = None if codec is not None: gae_objects = getGAEObjects(codec.context) key = str(obj.key()) if obj.is_saved() else None static_attrs[DataStoreClassAlias.KEY_ATTR] = key kd = self.klass.__dict__ for a in static_attrs_names: if a == DataStoreClassAlias.KEY_ATTR: continue try: prop = kd[a] except KeyError: prop = None if isinstance(prop, db.ReferenceProperty): if gae_objects is not None: klass = prop.reference_class key = prop.get_value_for_datastore(obj) if key is not None: key = str(key) try: static_attrs[a] = gae_objects.getClassKey(klass, key) except KeyError: ref_obj = getattr(obj, a) gae_objects.addClassKey(klass, key, ref_obj) static_attrs[a] = ref_obj continue static_attrs[a] = getattr(obj, a) for a in dynamic_attrs_names: dynamic_attrs[a] = getattr(obj, a) return static_attrs, dynamic_attrs def createInstance(self, codec=None): return ModelStub(self.klass) def applyAttributes(self, obj, attrs, codec=None): new_obj = None # attempt to load the object from the datastore if KEY_ATTR exists. if DataStoreClassAlias.KEY_ATTR in attrs.keys(): if attrs[DataStoreClassAlias.KEY_ATTR] is not None: key = attrs[DataStoreClassAlias.KEY_ATTR] new_obj = loadInstanceFromDatastore(self.klass, key, codec) del attrs[DataStoreClassAlias.KEY_ATTR] properties = self.klass.properties() p_keys = properties.keys() apply_init = True sa, da = self.getAttrs(obj) # clean up the stub if isinstance(obj, ModelStub) and hasattr(obj, 'klass'): del obj.klass if new_obj is not None: obj.__dict__ = new_obj.__dict__.copy() obj.__class__ = self.klass kd = self.klass.__dict__ for k, v in attrs.copy().iteritems(): if k in p_keys: prop = properties[k] if k not in sa: del attrs[k] continue if isinstance(prop, db.ListProperty) and v is None: attrs[k] = [] elif isinstance(v, datetime.datetime): # Date/Time Property fields expect specific types of data # whereas PyAMF only decodes into datetime.datetime objects. if isinstance(prop, db.DateProperty): attrs[k] = v.date() elif isinstance(prop, db.TimeProperty): attrs[k] = v.time() if new_obj is None and isinstance(v, ModelStub) and (k in kd and isinstance(kd[k], db.ReferenceProperty) and kd[k].required is True): apply_init = False del attrs[k] continue elif k in kd: kp = kd[k] # check if the property is a defined as a collection_name. # These types of properties are read-only and the datastore # freaks out if you attempt to meddle with it. We delete the # attribute entirely .. if isinstance(kp, db._ReverseReferenceProperty): del attrs[k] elif isinstance(kp, property): if kp.fset is None: del attrs[k] # If the object does not exist in the datastore, we must fire the # class constructor. This sets internal attributes that pyamf has # no business messing with .. if new_obj is None and apply_init is True: obj.__init__(**attrs) for k, v in attrs.iteritems(): setattr(obj, k, v) def getGAEObjects(context): """ Returns a reference to the C{gae_objects} on the context. If it doesn't exist then it is created. @param context: The context to load the C{gae_objects} index from. @type context: Instance of L{pyamf.BaseContext} @return: The C{gae_objects} index reference. @rtype: Instance of L{GAEReferenceCollection} @since: 0.4.1 """ if not hasattr(context, 'gae_objects'): context.gae_objects = GAEReferenceCollection() return context.gae_objects def loadInstanceFromDatastore(klass, key, codec=None): """ Attempt to load an instance from the datastore, based on C{klass} and C{key}. We create an index on the codec's context (if it exists) so we can check that first before accessing the datastore. @param klass: The class that will be loaded from the datastore. @type klass: Sub-class of L{db.Model} or L{db.Expando} @param key: The key which is used to uniquely identify the instance in the datastore. @type key: C{str} @param codec: The codec to reference the C{gae_objects} index. If supplied,The codec must have have a context attribute. @type codec: Instance of L{pyamf.BaseEncoder} or L{pyamf.BaseDecoder} @return: The loaded instance from the datastore. @rtype: Instance of C{klass}. @since: 0.4.1 """ if not issubclass(klass, (db.Model, db.Expando)): raise TypeError('expected db.Model/db.Expando class, got %s' % (klass,)) if not isinstance(key, basestring): raise TypeError('string expected for key, got %s', (repr(key),)) key = str(key) if codec is None: return klass.get(key) gae_objects = getGAEObjects(codec.context) try: return gae_objects.getClassKey(klass, key) except KeyError: pass obj = klass.get(key) gae_objects.addClassKey(klass, key, obj) return obj def writeGAEObject(self, object, *args, **kwargs): """ The GAE Datastore creates new instances of objects for each get request. This is a problem for PyAMF as it uses the id(obj) of the object to do reference checking. We could just ignore the problem, but the objects are conceptually the same so the effort should be made to attempt to resolve references for a given object graph. We create a new map on the encoder context object which contains a dict of C{object.__class__: {key1: object1, key2: object2, .., keyn: objectn}}. We use the datastore key to do the reference checking. @since: 0.4.1 """ if not (isinstance(object, db.Model) and object.is_saved()): self.writeNonGAEObject(object, *args, **kwargs) return context = self.context kls = object.__class__ s = str(object.key()) gae_objects = getGAEObjects(context) referenced_object = None try: referenced_object = gae_objects.getClassKey(kls, s) except KeyError: gae_objects.addClassKey(kls, s, object) self.writeNonGAEObject(object, *args, **kwargs) return self.writeNonGAEObject(referenced_object, *args, **kwargs) def install_gae_reference_model_hook(mod): """ Called when L{pyamf.amf0} or L{pyamf.amf3} are imported. Attaches the L{writeGAEObject} method to the C{Encoder} class in that module. @param mod: The module imported. @since: 0.4.1 """ if not hasattr(mod.Encoder, 'writeNonGAEObject'): mod.Encoder.writeNonGAEObject = mod.Encoder.writeObject mod.Encoder.writeObject = writeGAEObject # initialise the module here: hook into pyamf pyamf.add_type(db.Query, util.to_list) pyamf.register_alias_type(DataStoreClassAlias, db.Model, db.Expando) # hook the L{writeGAEObject} method to the Encoder class on import imports.whenImported('pyamf.amf0', install_gae_reference_model_hook) imports.whenImported('pyamf.amf3', install_gae_reference_model_hook) PKũ:/DDpyamf/adapters/_decimal.pyc; Ic@sLdZdkZdkZdZeedoeieiendS(s1 Adapter for the C{decimal} module. @since: 0.4 NcCsU|tj ot|tio"|itjot|SqBnti ddS(s Called when an instance of L{decimal.Decimal} is about to be encoded to an AMF stream. @param x: The L{decimal.Decimal} instance to encode. @param encoder: The L{pyamf.BaseEncoder} instance about to perform the operation. @return: If the encoder is in 'strict' mode then C{x} will be converted to a float. Otherwise an L{pyamf.EncodeError} with a friendly message is raised. sUnable to encode decimal.Decimal instances as there is no way to guarantee exact conversion. Use strict=False to convert to a float.N( sencodersNones isinstancespyamfs BaseEncodersstrictsFalsesfloatsxs EncodeError(sxsencoder((s7build/bdist.linux-x86_64/egg/pyamf/adapters/_decimal.pysconvert_Decimals  sDecimal(s__doc__sdecimalspyamfsconvert_Decimalshasattrsadd_typesDecimal(sconvert_Decimalsdecimalspyamf((s7build/bdist.linux-x86_64/egg/pyamf/adapters/_decimal.pys?s    PKũ:_7]pyamf/adapters/_sets.pyc; La^Ic@s}dZdkZdkZdklZeedoeieieineedoeiei eindS(s5 Adapter for the stdlib C{sets} module. @since: 0.4 N(sutils ImmutableSetsSet( s__doc__ssetsspyamfspyamf.adapterssutilshasattrsadd_types ImmutableSetsto_tuplesSet(sutilspyamfssets((s4build/bdist.linux-x86_64/egg/pyamf/adapters/_sets.pys?s   PKũ:npyamf/adapters/util.pyc; Ic@sYdZdkZeed odklZndZdZdZdZ dS(s+ Useful helpers for adapters. @since: 0.4 Nsset(sSetcCst|SdS(sM Converts an arbitrary object C{obj} to a list. @rtype: L{list} N(slistsobj(sobjsencoder((s3build/bdist.linux-x86_64/egg/pyamf/adapters/util.pysto_listscCst|SdS(sM Converts an arbitrary object C{obj} to a dict. @rtype: L{dict} N(sdictsobj(sobjsencoder((s3build/bdist.linux-x86_64/egg/pyamf/adapters/util.pysto_dictscCst|SdS(sK Converts an arbitrary object C{obj} to a set. @rtype: L{set} N(ssetsobj(sobjsencoder((s3build/bdist.linux-x86_64/egg/pyamf/adapters/util.pysto_setscCst|SdS(sO Converts an arbitrary object C{obj} to a tuple. @rtype: L{tuple} N(stuplesx(sxsencoder((s3build/bdist.linux-x86_64/egg/pyamf/adapters/util.pysto_tuple's( s__doc__s __builtin__shasattrssetssSetssetsto_liststo_dictsto_setsto_tuple(sto_setssetsto_tuplesto_lists __builtin__sto_dict((s3build/bdist.linux-x86_64/egg/pyamf/adapters/util.pys?s    PKũ:)%99*pyamf/adapters/_django_db_models_query.pyc; PIc@sCdZdklZdkZdklZeieieidS(s Django query adapter module. Sets up basic type mapping and class mappings for a Django models. @see: U{Django Project} @since: 0.1b (squeryN(sutil( s__doc__sdjango.db.modelssqueryspyamfspyamf.adapterssutilsadd_typesQuerySetsto_list(sutilsqueryspyamf((sFbuild/bdist.linux-x86_64/egg/pyamf/adapters/_django_db_models_query.pys? s   PKũ: ܱ7 7 pyamf/adapters/__init__.pyc; ӶIc@sWdZdkZdkZdklZdefdYZea dZ dZ dS(s The adapter package provides additional functionality for other Python packages. This includes registering classes, setting up type maps etc. @since: 0.1.0 N(simportssPackageImportercBs tZdZdZdZRS(s8 Package importer used for lazy module loading. cCs ||_dS(N(snamesself(sselfsname((s7build/bdist.linux-x86_64/egg/pyamf/adapters/__init__.pys__init__scCstdd|ifdS(Ns%s.%sspyamf.adapters(s __import__sselfsname(sselfsmod((s7build/bdist.linux-x86_64/egg/pyamf/adapters/__init__.pys__call__s(s__name__s __module__s__doc__s__init__s__call__(((s7build/bdist.linux-x86_64/egg/pyamf/adapters/__init__.pysPackageImporters  cCs ttjodSnydk}|idd}Wntiit}nXxt i tii |dD]}tii |i tiidd}|djp|id oqony't|diddt|Wqotj oqoXqoWtadS( Nspyamfsadapterss*.pyiis__init__s_s.(sadapters_registeredsTrues pkg_resourcessresource_filenames packageDirsosspathsdirnames__file__sglobsjoinsfsbasenamessplitsextsepsmods startswithsregister_adaptersreplacesPackageImporters ImportError(sfs pkg_resourcess packageDirsmod((s7build/bdist.linux-x86_64/egg/pyamf/adapters/__init__.pysregister_adapterss$  (' cCs8t| otdntit||dS(s Registers a callable to be executed when a module is imported. If the module already exists then the callable will be executed immediately. You can register the same module multiple times, the callables will be executed in the order they were registered. The root module must exist (i.e. be importable) otherwise an C{ImportError} will be thrown. @param mod: The fully qualified module string, as used in the imports statement. E.g. 'foo.bar.baz'. The string must map to a module otherwise the callable will not fire. @type mod: C{str} @param func: The function to call when C{mod} is imported. This function must take one arg, the newly imported C{module} object. @type func: callable @raise TypeError: C{func} must be callable sfunc must be callableN(scallablesfuncs TypeErrorsimportss whenImportedsstrsmod(smodsfunc((s7build/bdist.linux-x86_64/egg/pyamf/adapters/__init__.pysregister_adapter4s( s__doc__sos.pathsossglobs pyamf.utilsimportssobjectsPackageImportersFalsesadapters_registeredsregister_adapterssregister_adapter(sregister_adapterssimportssglobsPackageImportersregister_adaptersos((s7build/bdist.linux-x86_64/egg/pyamf/adapters/__init__.pys? s    PKũ:++pyamf/adapters/_django_db_models_fields.pyc; ӶIc@s<dZdklZdkZdZeidedS(so C{django.db.models.fields} adapter module. @see: U{Django Project} @since: 0.4 (sfieldsNcCs tiSdS(s/ @rtype: L{Undefined} N(spyamfs Undefined(sxsencoder((sGbuild/bdist.linux-x86_64/egg/pyamf/adapters/_django_db_models_fields.pysconvert_NOT_PROVIDEDscCs |tijS(N(sxsfieldss NOT_PROVIDED(sx((sGbuild/bdist.linux-x86_64/egg/pyamf/adapters/_django_db_models_fields.pyss(s__doc__sdjango.db.modelssfieldsspyamfsconvert_NOT_PROVIDEDsadd_type(sfieldsspyamfsconvert_NOT_PROVIDED((sGbuild/bdist.linux-x86_64/egg/pyamf/adapters/_django_db_models_fields.pys? s   PKũ:=fU,pyamf/adapters/_django_utils_translation.pyc; UIc@sHdZdklZdkZedZeieededS(sp C{django.utils.translation} adapter module. @see: U{Django Project} @since: 0.5 (s ugettext_lazyNcCsS|iiot|Sn|iiot|Sntdt|fdS(Ns'Don't know how to convert lazy value %s(sls __class__s_delegate_unicodesunicodes _delegate_strsstrs ValueErrorsrepr(slsencoder((sHbuild/bdist.linux-x86_64/egg/pyamf/adapters/_django_utils_translation.pys convert_lazys   sfoo(s__doc__sdjango.utils.translations ugettext_lazyspyamfsNones convert_lazysadd_typestype(s ugettext_lazys convert_lazyspyamf((sHbuild/bdist.linux-x86_64/egg/pyamf/adapters/_django_utils_translation.pys? s   PKũ:Nuupyamf/adapters/_sqlalchemy.pyc; qIc@sdZdkZdklZydklZlZWn&ej odklZlZnXdkZdk l Z e Z yee Wnej oZeiZ nXdeifdYZdZeieeeieie ieieie ieieie idS(sm SQLAlchemy adapter module. @see: U{SQLAlchemy homepage (external)} @since: 0.4 N(s collections(s class_mappers object_mapper(sutilsSaMappedClassAliasc BsbtZdZdZddddddd d d d d dg ZdZdZdZdZRS(Nssa_keyssa_lazys_sa_instance_states_sa_session_ids_states _entity_names _instance_keys_sa_class_managers _sa_adapters _sa_appenders_sa_instrumenteds _sa_iterators _sa_removers _sa_initiatorcCsXt|do |iSnyt||_Wntj ot|_nX|iSdS(sA Returns C{sqlalchemy.orm.mapper.Mapper} object. sprimary_mapperN(shasattrsselfsprimary_mappers object_mappersobjsUnmappedInstanceErrorsNone(sselfsobj((s:build/bdist.linux-x86_64/egg/pyamf/adapters/_sqlalchemy.pys _getMapper(s cOsS|i|}|tjotii||||Snt |d o|i |i g|_ g|_x$|iD]}|i i|iqrWxX|iiiD]@\}}t|to$|ii||i i|qqWng}xO|iiD]>}||ijoqn||i jo|i|qqW|i |fSdS(s Returns a C{tuple} containing 2 lists. The 1st is a list of allowed static attribute names, and the 2nd is a list of allowed dynamic attribute names. s static_attrsN(sselfs _getMappersobjsmappersNonespyamfs ClassAliassgetAttrssargsskwargsshasattrsKEY_ATTRs LAZY_ATTRs static_attrss propertiessiterate_propertiesspropsappendskeysklasss__dict__s iteritemss isinstancespropertys dynamic_attrsskeyssEXCLUDED_ATTRS(sselfsobjsargsskwargssmappers dynamic_attrsspropskey((s:build/bdist.linux-x86_64/egg/pyamf/adapters/_sqlalchemy.pysgetAttrs6s.    c OsN|i|}|tjotii||||Snh}h} g} |i |\}}|i|||i} @since: 0.4.1 (sModel(sfields(srelatedNsDjangoClassAliascBs>tZedZdZdZedZedZRS(NcCs'ggf\}}t|do |i}ng}|_h|_xH|iiD]:}|i|jo$||i|i<|i |iqRqRWx|i i i D]r\}}t|to|i |qt|tio2||jo!|i|i|<|i |qqqW||fSdS(Ns static_attrs(s static_attrss dynamic_attrsshasattrsselfsfieldssobjs_metasxsnamesappendsklasss__dict__s iteritemssksvs isinstancespropertysrelateds#ReverseManyRelatedObjectsDescriptorsfield(sselfsobjscodecsvs static_attrss dynamic_attrssxsk((sEbuild/bdist.linux-x86_64/egg/pyamf/adapters/_django_db_models_base.pysgetAttrss&      cCs|tijo tiSnt|tio|Snt|tio)t i |i |i |i dddSnCt|ti o/t i ddd|i|i|i|iSn|SdS(Niii(svaluesfieldss NOT_PROVIDEDspyamfs Undefineds isinstancesfields DateTimeFields DateFieldsdatetimesyearsmonthsdays TimeFieldshoursminutesseconds microsecond(sselfsfieldsvalue((sEbuild/bdist.linux-x86_64/egg/pyamf/adapters/_django_db_models_base.pys _encodeValue-s ) cCs|tijo tiSnt|tio|Snmt|tio t i |i |i |i Sn:t|tio&t i|i|i|i|iSn|SdS(N(svaluespyamfs Undefinedsfieldss NOT_PROVIDEDs isinstancesfields DateTimeFields DateFieldsdatetimesdatesyearsmonthsdays TimeFieldstimeshoursminutesseconds microsecond(sselfsfieldsvalue((sEbuild/bdist.linux-x86_64/egg/pyamf/adapters/_django_db_models_base.pys _decodeValue<s  &c CsIdkl}|i|\}} hhf\}}x|D]} | |i i jot || || gi}t || iD]} || q~|| #cCst|d o|i|nx:|iiD])\}}|i|||||i } @see: U{Remoting Headers on OSFlash (external) } @see: U{Remoting Debug Headers on OSFlash (external) } @since: 0.1.0 """ import copy import pyamf from pyamf import util __all__ = ['Envelope', 'Request', 'Response', 'decode', 'encode'] #: Succesful call. STATUS_OK = 0 #: Reserved for runtime errors. STATUS_ERROR = 1 #: Debug information. STATUS_DEBUG = 2 #: List of available status response codes. STATUS_CODES = { STATUS_OK: '/onResult', STATUS_ERROR: '/onStatus', STATUS_DEBUG: '/onDebugEvents' } #: AMF mimetype. CONTENT_TYPE = 'application/x-amf' ERROR_CALL_FAILED, = range(1) ERROR_CODES = { ERROR_CALL_FAILED: 'Server.Call.Failed' } APPEND_TO_GATEWAY_URL = 'AppendToGatewayUrl' REPLACE_GATEWAY_URL = 'ReplaceGatewayUrl' REQUEST_PERSISTENT_HEADER = 'RequestPersistentHeader' class RemotingError(pyamf.BaseError): """ Generic remoting error class. """ class RemotingCallFailed(RemotingError): """ Raised if C{Server.Call.Failed} received. """ pyamf.add_error_class(RemotingCallFailed, ERROR_CODES[ERROR_CALL_FAILED]) class HeaderCollection(dict): """ Collection of AMF message headers. """ def __init__(self, raw_headers={}): self.required = [] for (k, ig, v) in raw_headers: self[k] = v if ig: self.required.append(k) def is_required(self, idx): """ @raise KeyError: Unknown header found. """ if not idx in self: raise KeyError("Unknown header %s" % str(idx)) return idx in self.required def set_required(self, idx, value=True): """ @raise KeyError: Unknown header found. """ if not idx in self: raise KeyError("Unknown header %s" % str(idx)) if not idx in self.required: self.required.append(idx) def __len__(self): return len(self.keys()) class Envelope(object): """ I wrap an entire request, encapsulating headers and bodies. There can be more than one request in a single transaction. @ivar amfVersion: AMF encoding version. See L{pyamf.ENCODING_TYPES} @type amfVersion: C{int} or C{None} @ivar clientType: Client type. See L{ClientTypes} @type clientType: C{int} or C{None} @ivar headers: AMF headers, a list of name, value pairs. Global to each request. @type headers: L{HeaderCollection} @ivar bodies: A list of requests/response messages @type bodies: L{list} containing tuples of the key of the request and the instance of the L{Message} """ def __init__(self, amfVersion=None, clientType=None): self.amfVersion = amfVersion self.clientType = clientType self.headers = HeaderCollection() self.bodies = [] def __repr__(self): r = "\n" % ( self.amfVersion, self.clientType) for h in self.headers: r += " " + repr(h) + "\n" for request in iter(self): r += " " + repr(request) + "\n" r += "" return r def __setitem__(self, name, value): if not isinstance(value, Message): raise TypeError("Message instance expected") idx = 0 found = False for body in self.bodies: if name == body[0]: self.bodies[idx] = (name, value) found = True idx = idx + 1 if not found: self.bodies.append((name, value)) value.envelope = self def __getitem__(self, name): for body in self.bodies: if name == body[0]: return body[1] raise KeyError("'%r'" % (name,)) def __iter__(self): for body in self.bodies: yield body[0], body[1] raise StopIteration def __len__(self): return len(self.bodies) def iteritems(self): for body in self.bodies: yield body raise StopIteration def keys(self): return [body[0] for body in self.bodies] def items(self): return self.bodies def __contains__(self, name): for body in self.bodies: if name == body[0]: return True return False def __eq__(self, other): if isinstance(other, Envelope): return self.amfVersion == other.amfVersion and \ self.clientType == other.clientType and \ self.headers == other.headers and \ self.bodies == other.bodies if hasattr(other, 'keys') and hasattr(other, 'items'): keys, o_keys = self.keys(), other.keys() if len(o_keys) != len(keys): return False for k in o_keys: if k not in keys: return False keys.remove(k) for k, v in other.items(): if self[k] != v: return False return True class Message(object): """ I represent a singular request/response, containing a collection of headers and one body of data. I am used to iterate over all requests in the L{Envelope}. @ivar envelope: The parent envelope of this AMF Message. @type envelope: L{Envelope} @ivar body: The body of the message. @type body: C{mixed} @ivar headers: The message headers. @type headers: C{dict} """ def __init__(self, envelope, body): self.envelope = envelope self.body = body def _get_headers(self): return self.envelope.headers headers = property(_get_headers) class Request(Message): """ An AMF Request payload. @ivar target: The target of the request @type target: C{basestring} """ def __init__(self, target, body=[], envelope=None): Message.__init__(self, envelope, body) self.target = target def __repr__(self): return "<%s target=%s>%s" % ( type(self).__name__, repr(self.target), repr(self.body), type(self).__name__) class Response(Message): """ An AMF Response. @ivar status: The status of the message. Default is L{STATUS_OK}. @type status: Member of L{STATUS_CODES}. """ def __init__(self, body, status=STATUS_OK, envelope=None): Message.__init__(self, envelope, body) self.status = status def __repr__(self): return "<%s status=%s>%s" % ( type(self).__name__, _get_status(self.status), repr(self.body), type(self).__name__ ) class BaseFault(object): """ I represent a C{Fault} message (C{mx.rpc.Fault}). @ivar level: The level of the fault. @type level: C{str} @ivar code: A simple code describing the fault. @type code: C{str} @ivar details: Any extra details of the fault. @type details: C{str} @ivar description: Text description of the fault. @type description: C{str} @see: U{mx.rpc.Fault on Livedocs (external) } """ level = None def __init__(self, *args, **kwargs): self.code = kwargs.get('code', '') self.type = kwargs.get('type', '') self.details = kwargs.get('details', '') self.description = kwargs.get('description', '') def __repr__(self): x = '%s level=%s' % (self.__class__.__name__, self.level) if self.code not in ('', None): x += ' code=%s' % repr(self.code) if self.type not in ('', None): x += ' type=%s' % repr(self.type) if self.description not in ('', None): x += ' description=%s' % repr(self.description) if self.details not in ('', None): x += '\nTraceback:\n%s' % (repr(self.details),) return x def raiseException(self): """ Raises an exception based on the fault object. There is no traceback available. """ raise get_exception_from_fault(self), self.description, None pyamf.register_class(BaseFault, attrs=['level', 'code', 'type', 'details', 'description']) class ErrorFault(BaseFault): """ I represent an error level fault. """ level = 'error' pyamf.register_class(ErrorFault) def _read_header(stream, decoder, strict=False): """ Read AMF L{Message} header. @type stream: L{BufferedByteStream} @param stream: AMF data. @type decoder: L{amf0.Decoder} @param decoder: AMF decoder instance @type strict: C{bool} @param strict: Use strict decoding policy. Default is C{False}. @raise DecodeError: The data that was read from the stream does not match the header length. @rtype: C{tuple} @return: - Name of the header. - A C{bool} determining if understanding this header is required. - Value of the header. """ name_len = stream.read_ushort() name = stream.read_utf8_string(name_len) required = bool(stream.read_uchar()) data_len = stream.read_ulong() pos = stream.tell() data = decoder.readElement() if strict and pos + data_len != stream.tell(): raise pyamf.DecodeError( "Data read from stream does not match header length") return (name, required, data) def _write_header(name, header, required, stream, encoder, strict=False): """ Write AMF message header. @type name: C{str} @param name: Name of the header. @type header: @param header: Raw header data. @type required: L{bool} @param required: Required header. @type stream: L{BufferedByteStream} @param stream: AMF data. @type encoder: L{amf0.Encoder} or L{amf3.Encoder} @param encoder: AMF encoder instance. @type strict: C{bool} @param strict: Use strict encoding policy. Default is C{False}. """ stream.write_ushort(len(name)) stream.write_utf8_string(name) stream.write_uchar(required) write_pos = stream.tell() stream.write_ulong(0) old_pos = stream.tell() encoder.writeElement(header) new_pos = stream.tell() if strict: stream.seek(write_pos) stream.write_ulong(new_pos - old_pos) stream.seek(new_pos) def _read_body(stream, decoder, strict=False): """ Read AMF message body. @type stream: L{BufferedByteStream} @param stream: AMF data. @type decoder: L{amf0.Decoder} @param decoder: AMF decoder instance. @type strict: C{bool} @param strict: Use strict decoding policy. Default is C{False}. @raise DecodeError: Data read from stream does not match body length. @rtype: C{tuple} @return: A C{tuple} containing: - ID of the request - L{Request} or L{Response} """ def _read_args(): """ @raise pyamf.DecodeError: Array type required for request body. """ if stream.read(1) != '\x0a': raise pyamf.DecodeError("Array type required for request body") x = stream.read_ulong() return [decoder.readElement() for i in xrange(x)] target = stream.read_utf8_string(stream.read_ushort()) response = stream.read_utf8_string(stream.read_ushort()) status = STATUS_OK is_request = True for (code, s) in STATUS_CODES.iteritems(): if target.endswith(s): is_request = False status = code target = target[:0 - len(s)] data_len = stream.read_ulong() pos = stream.tell() if is_request: data = _read_args() else: data = decoder.readElement() if strict and pos + data_len != stream.tell(): raise pyamf.DecodeError("Data read from stream does not match body " "length (%d != %d)" % (pos + data_len, stream.tell(),)) if is_request: return (response, Request(target, body=data)) else: if status == STATUS_ERROR and isinstance(data, pyamf.ASObject): data = get_fault(data) return (target, Response(data, status)) def _write_body(name, message, stream, encoder, strict=False): """ Write AMF message body. @param name: The name of the request. @type name: C{basestring} @param message: The AMF payload. @type message: L{Request} or L{Response} @type stream: L{BufferedByteStream} @type encoder: L{amf0.Encoder} @param encoder: Encoder to use. @type strict: C{bool} @param strict: Use strict encoding policy. Default is C{False}. @raise TypeError: Unknown message type for C{message}. """ def _encode_body(message): if isinstance(message, Response): encoder.writeElement(message.body) return stream.write('\x0a') stream.write_ulong(len(message.body)) for x in message.body: encoder.writeElement(x) if not isinstance(message, (Request, Response)): raise TypeError("Unknown message type") target = None if isinstance(message, Request): target = unicode(message.target) else: target = u"%s%s" % (name, _get_status(message.status)) target = target.encode('utf8') stream.write_ushort(len(target)) stream.write_utf8_string(target) response = 'null' if isinstance(message, Request): response = name stream.write_ushort(len(response)) stream.write_utf8_string(response) if not strict: stream.write_ulong(0) _encode_body(message) else: write_pos = stream.tell() stream.write_ulong(0) old_pos = stream.tell() _encode_body(message) new_pos = stream.tell() stream.seek(write_pos) stream.write_ulong(new_pos - old_pos) stream.seek(new_pos) def _get_status(status): """ Get status code. @type status: C{str} @raise ValueError: The status code is unknown. @return: Status code. @see: L{STATUS_CODES} """ if status not in STATUS_CODES.keys(): # TODO print that status code.. raise ValueError("Unknown status code") return STATUS_CODES[status] def get_fault_class(level, **kwargs): code = kwargs.get('code', '') if level == 'error': return ErrorFault return BaseFault def get_fault(data): try: level = data['level'] del data['level'] except KeyError: level = 'error' e = {} for x, y in data.iteritems(): if isinstance(x, unicode): e[str(x)] = y else: e[x] = y return get_fault_class(level, **e)(**e) def decode(stream, context=None, strict=False): """ Decodes the incoming stream. @type stream: L{BufferedByteStream} @param stream: AMF data. @type context: L{amf0.Context} or L{amf3.Context} @param context: Context. @type strict: C{bool} @param strict: Enforce strict encoding. Default is C{False}. @raise DecodeError: Malformed stream. @raise RuntimeError: Decoder is unable to fully consume the stream buffer. @return: Message envelope. @rtype: L{Envelope} """ if not isinstance(stream, util.BufferedByteStream): stream = util.BufferedByteStream(stream) msg = Envelope() msg.amfVersion = stream.read_uchar() # see http://osflash.org/documentation/amf/envelopes/remoting#preamble # why we are doing this... if msg.amfVersion > 0x09: raise pyamf.DecodeError("Malformed stream (amfVersion=%d)" % msg.amfVersion) if context is None: context = pyamf.get_context(pyamf.AMF0) else: context = copy.copy(context) decoder = pyamf._get_decoder_class(pyamf.AMF0)(stream, context=context, strict=strict) msg.clientType = stream.read_uchar() header_count = stream.read_ushort() for i in xrange(header_count): name, required, data = _read_header(stream, decoder, strict) msg.headers[name] = data if required: msg.headers.set_required(name) body_count = stream.read_short() for i in range(body_count): context.reset() target, payload = _read_body(stream, decoder, strict) msg[target] = payload if strict and stream.remaining() > 0: raise RuntimeError("Unable to fully consume the buffer") return msg def encode(msg, context=None, strict=False): """ Encodes AMF stream and returns file object. @type msg: L{Envelope} @param msg: The message to encode. @type context: L{amf0.Context} or L{amf3.Context} @param context: Context. @type strict: C{bool} @param strict: Determines whether encoding should be strict. Specifically header/body lengths will be written correctly, instead of the default 0. Default is C{False}. Introduced in 0.4. @rtype: C{StringIO} @return: File object. """ def getNewContext(): if context: new_context = copy.copy(context) new_context.reset() return new_context else: return pyamf.get_context(pyamf.AMF0) stream = util.BufferedByteStream() encoder = pyamf._get_encoder_class(pyamf.AMF0)(stream, strict=strict) if msg.clientType == pyamf.ClientTypes.Flash9: encoder.use_amf3 = True stream.write_uchar(msg.amfVersion) stream.write_uchar(msg.clientType) stream.write_short(len(msg.headers)) for name, header in msg.headers.iteritems(): _write_header( name, header, msg.headers.is_required(name), stream, encoder, strict) stream.write_short(len(msg)) for name, message in msg.iteritems(): encoder.context = getNewContext() _write_body(name, message, stream, encoder, strict) return stream def get_exception_from_fault(fault): """ @raise RemotingError: Default exception from fault. """ # XXX nick: threading problems here? try: return pyamf.ERROR_CLASS_MAP[fault.code] except KeyError: # default to RemotingError return RemotingError PK":gspyamf/remoting/amf0.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ AMF0 Remoting support. @since: 0.1.0 """ import traceback, sys from pyamf import remoting from pyamf.remoting import gateway class RequestProcessor(object): def __init__(self, gateway): self.gateway = gateway def authenticateRequest(self, request, service_request, *args, **kwargs): """ Authenticates the request against the service. @param request: The AMF request @type request: L{Request} """ username = password = None if 'Credentials' in request.headers: cred = request.headers['Credentials'] username = cred['userid'] password = cred['password'] return self.gateway.authenticateRequest(service_request, username, password, *args, **kwargs) def buildErrorResponse(self, request, error=None): """ Builds an error response. @param request: The AMF request @type request: L{Request} @return: The AMF response @rtype: L{Response} """ if error is not None: cls, e, tb = error else: cls, e, tb = sys.exc_info() return remoting.Response(build_fault(cls, e, tb), status=remoting.STATUS_ERROR) def _getBody(self, request, response, service_request, **kwargs): if 'DescribeService' in request.headers: return service_request.service.description return self.gateway.callServiceRequest(service_request, *request.body, **kwargs) def __call__(self, request, *args, **kwargs): """ Processes an AMF0 request. @param request: The request to be processed. @type request: L{Request} @return: The response to the request. @rtype: L{Response} """ response = remoting.Response(None) try: service_request = self.gateway.getServiceRequest(request, request.target) except gateway.UnknownServiceError, e: return self.buildErrorResponse(request) # we have a valid service, now attempt authentication try: authd = self.authenticateRequest(request, service_request, *args, **kwargs) except (SystemExit, KeyboardInterrupt): raise except: return self.buildErrorResponse(request) if not authd: # authentication failed response.status = remoting.STATUS_ERROR response.body = remoting.ErrorFault(code='AuthenticationError', description='Authentication failed') return response # authentication succeeded, now fire the preprocessor (if there is one) try: self.gateway.preprocessRequest(service_request, *args, **kwargs) except (SystemExit, KeyboardInterrupt): raise except: return self.buildErrorResponse(request) try: response.body = self._getBody(request, response, service_request, *args, **kwargs) return response except (SystemExit, KeyboardInterrupt): raise except: return self.buildErrorResponse(request) def build_fault(cls, e, tb): """ Builds a L{ErrorFault} object based on the last exception raised. """ if hasattr(cls, '_amf_code'): code = cls._amf_code else: code = cls.__name__ return remoting.ErrorFault(code=code, description=str(e), details=str(traceback.format_exception(cls, e, tb)).replace("\\n", '')) PK::|袻pyamf/remoting/amf3.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ AMF3 RemoteObject support. @see: U{RemoteObject on LiveDocs } @since: 0.1.0 """ import calendar, time, uuid, sys import pyamf from pyamf import remoting from pyamf.flex import messaging error_alias = pyamf.get_class_alias(messaging.ErrorMessage) class BaseServerError(pyamf.BaseError): """ Base server error. """ class ServerCallFailed(BaseServerError): """ A catchall error. """ _amf_code = 'Server.Call.Failed' pyamf.register_class(ServerCallFailed, attrs=error_alias.attrs) del error_alias def generate_random_id(): return str(uuid.uuid4()) def generate_acknowledgement(request=None): ack = messaging.AcknowledgeMessage() ack.messageId = generate_random_id() ack.clientId = generate_random_id() ack.timestamp = calendar.timegm(time.gmtime()) if request: ack.correlationId = request.messageId return ack def generate_error(request, cls, e, tb): """ Builds an L{ErrorMessage} based on the last traceback and the request that was sent. """ import traceback if hasattr(cls, '_amf_code'): code = cls._amf_code else: code = cls.__name__ detail = [] for x in traceback.format_exception(cls, e, tb): detail.append(x.replace("\\n", '')) return messaging.ErrorMessage(messageId=generate_random_id(), clientId=generate_random_id(), timestamp=calendar.timegm(time.gmtime()), correlationId = request.messageId, faultCode=code, faultString=str(e), faultDetail=str(detail), extendedData=detail) class RequestProcessor(object): def __init__(self, gateway): self.gateway = gateway def buildErrorResponse(self, request, error=None): """ Builds an error response. @param request: The AMF request @type request: L{Request} @return: The AMF response @rtype: L{Response} """ if error is not None: cls, e, tb = error else: cls, e, tb = sys.exc_info() return generate_error(request, cls, e, tb) def _getBody(self, amf_request, ro_request, **kwargs): """ @raise ServerCallFailed: Unknown request. """ if isinstance(ro_request, messaging.CommandMessage): return self._processCommandMessage(amf_request, ro_request, **kwargs) elif isinstance(ro_request, messaging.RemotingMessage): return self._processRemotingMessage(amf_request, ro_request, **kwargs) elif isinstance(ro_request, messaging.AsyncMessage): return self._processAsyncMessage(amf_request, ro_request, **kwargs) else: raise ServerCallFailed("Unknown request: %s" % ro_request) def _processCommandMessage(self, amf_request, ro_request, **kwargs): """ @raise ServerCallFailed: Unknown Command operation. @raise ServerCallFailed: Authorization is not supported in RemoteObject. """ ro_response = generate_acknowledgement(ro_request) if ro_request.operation == messaging.CommandMessage.PING_OPERATION: ro_response.body = True return remoting.Response(ro_response) elif ro_request.operation == messaging.CommandMessage.LOGIN_OPERATION: raise ServerCallFailed("Authorization is not supported in RemoteObject") elif ro_request.operation == messaging.CommandMessage.DISCONNECT_OPERATION: return remoting.Response(ro_response) else: raise ServerCallFailed("Unknown Command operation %s" % ro_request.operation) def _processAsyncMessage(self, amf_request, ro_request, **kwargs): ro_response = generate_acknowledgement(ro_request) ro_response.body = True return remoting.Response(ro_response) def _processRemotingMessage(self, amf_request, ro_request, **kwargs): ro_response = generate_acknowledgement(ro_request) service_name = ro_request.operation if hasattr(ro_request, 'destination') and ro_request.destination: service_name = '%s.%s' % (ro_request.destination, service_name) service_request = self.gateway.getServiceRequest(amf_request, service_name) # fire the preprocessor (if there is one) self.gateway.preprocessRequest(service_request, *ro_request.body, **kwargs) ro_response.body = self.gateway.callServiceRequest(service_request, *ro_request.body, **kwargs) return remoting.Response(ro_response) def __call__(self, amf_request, **kwargs): """ Processes an AMF3 Remote Object request. @param amf_request: The request to be processed. @type amf_request: L{Request} @return: The response to the request. @rtype: L{Response} """ ro_request = amf_request.body[0] try: return self._getBody(amf_request, ro_request, **kwargs) except (KeyboardInterrupt, SystemExit): raise except: return remoting.Response(self.buildErrorResponse(ro_request), status=remoting.STATUS_ERROR) PKũ:@mmpyamf/remoting/__init__.pyc; /HIc@s%dZdkZdkZdklZdddddgZdZd Zd Zhed <ed <ed } @see: U{Remoting Headers on OSFlash (external) } @see: U{Remoting Debug Headers on OSFlash (external) } @since: 0.1.0 N(sutilsEnvelopesRequestsResponsesdecodesencodeiiis /onResults /onStatuss/onDebugEventssapplication/x-amfsServer.Call.FailedsAppendToGatewayUrlsReplaceGatewayUrlsRequestPersistentHeaders RemotingErrorcBstZdZRS(s' Generic remoting error class. (s__name__s __module__s__doc__(((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys RemotingError>s sRemotingCallFailedcBstZdZRS(s3 Raised if C{Server.Call.Failed} received. (s__name__s __module__s__doc__(((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pysRemotingCallFailedCs sHeaderCollectioncBs8tZdZhdZdZedZdZRS(s, Collection of AMF message headers. cCsLg|_x<|D]4\}}}|||<|o|ii|qqWdS(N(sselfsrequireds raw_headerssksigsvsappend(sselfs raw_headerssksigsv((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys__init__Ns   cCs9||j otdt|n||ijSdS(s8 @raise KeyError: Unknown header found. sUnknown header %sN(sidxsselfsKeyErrorsstrsrequired(sselfsidx((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys is_requiredVscCsQ||j otdt|n||ij o|ii|ndS(s8 @raise KeyError: Unknown header found. sUnknown header %sN(sidxsselfsKeyErrorsstrsrequiredsappend(sselfsidxsvalue((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys set_required_s cCst|iSdS(N(slensselfskeys(sself((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys__len__is(s__name__s __module__s__doc__s__init__s is_requiredsTrues set_requireds__len__(((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pysHeaderCollectionJs   cBswtZdZeedZdZdZdZdZdZ dZ dZ d Z d Z d ZRS( s I wrap an entire request, encapsulating headers and bodies. There can be more than one request in a single transaction. @ivar amfVersion: AMF encoding version. See L{pyamf.ENCODING_TYPES} @type amfVersion: C{int} or C{None} @ivar clientType: Client type. See L{ClientTypes} @type clientType: C{int} or C{None} @ivar headers: AMF headers, a list of name, value pairs. Global to each request. @type headers: L{HeaderCollection} @ivar bodies: A list of requests/response messages @type bodies: L{list} containing tuples of the key of the request and the instance of the L{Message} cCs+||_||_t|_g|_dS(N(s amfVersionsselfs clientTypesHeaderCollectionsheaderssbodies(sselfs amfVersions clientType((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys__init__}s   cCsd|i|if}x)|iD]}|dt|d7}q Wx,t|D]}|dt|d7}qOW|d7}|SdS(Ns' s s s ( sselfs amfVersions clientTypesrsheadersshsreprsitersrequest(sselfshsrequestsr((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys__repr__s   cCst|t otdnd}t}xI|iD]>}||djo||f|i|%s(stypesselfs__name__sreprstargetsbody(sself((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys__repr__s(s__name__s __module__s__doc__sNones__init__s__repr__(((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pysRequests cBs&tZdZeedZdZRS(s An AMF Response. @ivar status: The status of the message. Default is L{STATUS_OK}. @type status: Member of L{STATUS_CODES}. cCs ti|||||_dS(N(sMessages__init__sselfsenvelopesbodysstatus(sselfsbodysstatussenvelope((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys__init__scCs<dt|it|it|it|ifSdS(Ns<%s status=%s>%s(stypesselfs__name__s _get_statussstatussreprsbody(sself((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys__repr__s(s__name__s __module__s__doc__s STATUS_OKsNones__init__s__repr__(((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pysResponses s BaseFaultcBs/tZdZeZdZdZdZRS(s I represent a C{Fault} message (C{mx.rpc.Fault}). @ivar level: The level of the fault. @type level: C{str} @ivar code: A simple code describing the fault. @type code: C{str} @ivar details: Any extra details of the fault. @type details: C{str} @ivar description: Text description of the fault. @type description: C{str} @see: U{mx.rpc.Fault on Livedocs (external) } cOsX|idd|_|idd|_|idd|_|idd|_dS(Nscodesstypesdetailss description(skwargssgetsselfscodestypesdetailss description(sselfsargsskwargs((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys__init__+scCsd|ii|if}|idtfjo|dt|i7}n|idtfjo|dt|i7}n|i dtfjo|dt|i 7}n|i dtfjo|dt|i f7}n|SdS(Ns %s level=%sss code=%ss type=%ss description=%ss Traceback: %s( sselfs __class__s__name__slevelsxscodesNonesreprstypes descriptionsdetails(sselfsx((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys__repr__1scCst||itdS(si Raises an exception based on the fault object. There is no traceback available. N(sget_exception_from_faultsselfs descriptionsNone(sself((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pysraiseException@s(s__name__s __module__s__doc__sNoneslevels__init__s__repr__sraiseException(((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys BaseFaults   sattrsslevelscodestypesdetailss descriptions ErrorFaultcBstZdZdZRS(s+ I represent an error level fault. serror(s__name__s __module__s__doc__slevel(((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys ErrorFaultJs c Cs|i}|i|}t|i}|i}|i }|i }|o|||i jotidn|||fSdS(sY Read AMF L{Message} header. @type stream: L{BufferedByteStream} @param stream: AMF data. @type decoder: L{amf0.Decoder} @param decoder: AMF decoder instance @type strict: C{bool} @param strict: Use strict decoding policy. Default is C{False}. @raise DecodeError: The data that was read from the stream does not match the header length. @rtype: C{tuple} @return: - Name of the header. - A C{bool} determining if understanding this header is required. - Value of the header. s2Data read from stream does not match header lengthN(sstreams read_ushortsname_lensread_utf8_stringsnamesbools read_ucharsrequireds read_ulongsdata_lenstellspossdecoders readElementsdatasstrictspyamfs DecodeError( sstreamsdecodersstrictsname_lensnamesdatasrequiredspossdata_len((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys _read_headerRs    c Cs|it||i||i||i}|i d|i}|i ||i}|o/|i||i |||i|ndS(s5 Write AMF message header. @type name: C{str} @param name: Name of the header. @type header: @param header: Raw header data. @type required: L{bool} @param required: Required header. @type stream: L{BufferedByteStream} @param stream: AMF data. @type encoder: L{amf0.Encoder} or L{amf3.Encoder} @param encoder: AMF encoder instance. @type strict: C{bool} @param strict: Use strict encoding policy. Default is C{False}. iN(sstreams write_ushortslensnameswrite_utf8_strings write_ucharsrequiredstells write_poss write_ulongsold_possencoders writeElementsheadersnew_possstrictsseek( snamesheadersrequiredsstreamsencodersstricts write_possnew_possold_pos((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys _write_headervs        c s{d}ii} ii} t}t}xNt i D]@\}} | i| o$t}|}| dt|  } qRqRWi} i}|o |}n i}|o|| ijo'tid|| ifn|o| t| d|fSnD|tjot|tiot|}n| t ||fSdS(s Read AMF message body. @type stream: L{BufferedByteStream} @param stream: AMF data. @type decoder: L{amf0.Decoder} @param decoder: AMF decoder instance. @type strict: C{bool} @param strict: Use strict decoding policy. Default is C{False}. @raise DecodeError: Data read from stream does not match body length. @rtype: C{tuple} @return: A C{tuple} containing: - ID of the request - L{Request} or L{Response} csjiddjotidni}gi}t|D]}|i qI~SdS(sQ @raise pyamf.DecodeError: Array type required for request body. is s$Array type required for request bodyN( sstreamsreadspyamfs DecodeErrors read_ulongsxsappends_[1]sxrangesisdecoders readElement(sis_[1]sx(sstreamsdecoder(s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys _read_argss  is;Data read from stream does not match body length (%d != %d)sbodyN(!s _read_argssstreamsread_utf8_strings read_ushortstargetsresponses STATUS_OKsstatussTrues is_requests STATUS_CODESs iteritemsscodesssendswithsFalseslens read_ulongsdata_lenstellspossdatasdecoders readElementsstrictspyamfs DecodeErrorsRequests STATUS_ERRORs isinstancesASObjects get_faultsResponse( sstreamsdecodersstrictscodes is_requestsposs _read_argssstatussdatasresponsestargetsssdata_len((sstreamsdecoders7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys _read_bodys0      ' c std}t|ttf otdnt} t|tot|i} nd|t |i f} | i d} it| i| d}t|to |}nit|i|| oid||ngi}idi} ||i}i|i|| i|dS(s Write AMF message body. @param name: The name of the request. @type name: C{basestring} @param message: The AMF payload. @type message: L{Request} or L{Response} @type stream: L{BufferedByteStream} @type encoder: L{amf0.Encoder} @param encoder: Encoder to use. @type strict: C{bool} @param strict: Use strict encoding policy. Default is C{False}. @raise TypeError: Unknown message type for C{message}. cspt|toi|idSnidit |ix|iD]}i|qUWdS(Ns ( s isinstancesmessagesResponsesencoders writeElementsbodysstreamswrites write_ulongslensx(smessagesx(sstreamsencoder(s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys _encode_bodys  sUnknown message typeu%s%ssutf8snulliN(s _encode_bodys isinstancesmessagesRequestsResponses TypeErrorsNonestargetsunicodesnames _get_statussstatussencodesstreams write_ushortslenswrite_utf8_stringsresponsesstricts write_ulongstells write_possold_possnew_possseek( snamesmessagesstreamsencodersstricts write_poss _encode_bodysnew_possresponsesold_posstarget((sstreamsencoders7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys _write_bodys6           cCs/|tijotdnt|SdS(s Get status code. @type status: C{str} @raise ValueError: The status code is unknown. @return: Status code. @see: L{STATUS_CODES} sUnknown status codeN(sstatuss STATUS_CODESskeyss ValueError(sstatus((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys _get_statusscKs/|idd}|djotSntSdS(Nscodesserror(skwargssgetscodeslevels ErrorFaults BaseFault(slevelskwargsscode((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pysget_fault_class$s cCsy|d}|d=Wntj o d}nXh}xH|iD]:\}}t|to||t |} @param stream: AMF data. @type context: L{amf0.Context} or L{amf3.Context} @param context: Context. @type strict: C{bool} @param strict: Enforce strict encoding. Default is C{False}. @raise DecodeError: Malformed stream. @raise RuntimeError: Decoder is unable to fully consume the stream buffer. @return: Message envelope. @rtype: L{Envelope} i s Malformed stream (amfVersion=%d)scontextsstrictis"Unable to fully consume the bufferN(&s isinstancesstreamsutilsBufferedByteStreamsEnvelopesmsgs read_uchars amfVersionspyamfs DecodeErrorscontextsNones get_contextsAMF0scopys_get_decoder_classsstrictsdecoders clientTypes read_ushorts header_countsxrangesis _read_headersnamesrequiredsdatasheaderss set_requireds read_shorts body_countsrangesresets _read_bodystargetspayloads remainings RuntimeError( sstreamscontextsstrictspayloadsmsgs body_countsdecodersdatastargets header_countsnamesisrequired((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pysdecode=s8  $      c s.d}ti}titi|d|}|i ti i jo t |_n|i|i|i|i |it|ixB|iiD]1\}}t|||ii||||qW|it|x<|iD].\}}||_t|||||qW|SdS(s Encodes AMF stream and returns file object. @type msg: L{Envelope} @param msg: The message to encode. @type context: L{amf0.Context} or L{amf3.Context} @param context: Context. @type strict: C{bool} @param strict: Determines whether encoding should be strict. Specifically header/body lengths will be written correctly, instead of the default 0. Default is C{False}. Introduced in 0.4. @rtype: C{StringIO} @return: File object. cs<o!ti}|i|SntitiSdS(N(scontextscopys new_contextsresetspyamfs get_contextsAMF0(s new_context(scontext(s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys getNewContexts  sstrictN(s getNewContextsutilsBufferedByteStreamsstreamspyamfs_get_encoder_classsAMF0sstrictsencodersmsgs clientTypes ClientTypessFlash9sTruesuse_amf3s write_uchars amfVersions write_shortslensheaderss iteritemssnamesheaders _write_headers is_requiredsmessagescontexts _write_body( smsgscontextsstrictsnamesstreamsheadersmessagesencoders getNewContext((scontexts7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pysencodezs&     cCs0yti|iSWntj o tSnXdS(s= @raise RemotingError: Default exception from fault. N(spyamfsERROR_CLASS_MAPsfaultscodesKeyErrors RemotingError(sfault((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pysget_exception_from_faults (*s__doc__scopyspyamfsutils__all__s STATUS_OKs STATUS_ERRORs STATUS_DEBUGs STATUS_CODESs CONTENT_TYPEsrangesERROR_CALL_FAILEDs ERROR_CODESsAPPEND_TO_GATEWAY_URLsREPLACE_GATEWAY_URLsREQUEST_PERSISTENT_HEADERs BaseErrors RemotingErrorsRemotingCallFailedsadd_error_classsdictsHeaderCollectionsobjectsEnvelopesMessagesRequestsResponses BaseFaultsregister_classs ErrorFaultsFalses _read_headers _write_headers _read_bodys _write_bodys _get_statussget_fault_classs get_faultsNonesdecodesencodesget_exception_from_fault(!sget_exception_from_faultspyamfsRemotingCallFaileds _write_headers STATUS_CODESs RemotingErrorsREPLACE_GATEWAY_URLsdecodes _read_bodys__all__sEnvelopes _get_statussREQUEST_PERSISTENT_HEADERs get_faultsget_fault_classsencodes STATUS_OKs BaseFaultsERROR_CALL_FAILEDsAPPEND_TO_GATEWAY_URLsRequestsutils ERROR_CODESscopys STATUS_DEBUGs _read_headers ErrorFaultsResponses _write_bodys STATUS_ERRORs CONTENT_TYPEsMessagesHeaderCollection((s7build/bdist.linux-x86_64/egg/pyamf/remoting/__init__.pys?sJ   !"t.   $ " < A   =1PKũ:pyamf/remoting/amf0.pyc; La^Ic@sUdZdkZdkZdklZdklZdefdYZdZ dS(s' AMF0 Remoting support. @since: 0.1.0 N(sremoting(sgatewaysRequestProcessorcBs8tZdZdZedZdZdZRS(NcCs ||_dS(N(sgatewaysself(sselfsgateway((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf0.pys__init__scOs_t}}d|ijo%|id}|d}|d}n|ii|||||SdS(s Authenticates the request against the service. @param request: The AMF request @type request: L{Request} s CredentialssuseridspasswordN( sNonesusernamespasswordsrequestsheadersscredsselfsgatewaysauthenticateRequestsservice_requestsargsskwargs(sselfsrequestsservice_requestsargsskwargssusernamespasswordscred((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf0.pysauthenticateRequests   cCs[|tj o|\}}}nti\}}}tit |||dti SdS(s Builds an error response. @param request: The AMF request @type request: L{Request} @return: The AMF response @rtype: L{Response} sstatusN( serrorsNonesclssestbssyssexc_infosremotingsResponses build_faults STATUS_ERROR(sselfsrequestserrorsestbscls((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf0.pysbuildErrorResponse%s  cKs;d|ijo|iiSn|ii||i|SdS(NsDescribeService( srequestsheaderssservice_requestsservices descriptionsselfsgatewayscallServiceRequestsbodyskwargs(sselfsrequestsresponsesservice_requestskwargs((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf0.pys_getBody6scOstit}y|ii||i}Wn%ti j o}|i |SnXy|i ||||}Wn/ttfj o n|i |SnX| o/ti|_tidddd|_|Sny|ii|||Wn/ttfj o n|i |SnXy&|i||||||_|SWn/ttfj o n|i |SnXdS(s Processes an AMF0 request. @param request: The request to be processed. @type request: L{Request} @return: The response to the request. @rtype: L{Response} scodesAuthenticationErrors descriptionsAuthentication failedN(sremotingsResponsesNonesresponsesselfsgatewaysgetServiceRequestsrequeststargetsservice_requestsUnknownServiceErrorsesbuildErrorResponsesauthenticateRequestsargsskwargssauthds SystemExitsKeyboardInterrupts STATUS_ERRORsstatuss ErrorFaultsbodyspreprocessRequests_getBody(sselfsrequestsargsskwargssservice_requestsesresponsesauthd((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf0.pys__call__=s>    (s__name__s __module__s__init__sauthenticateRequestsNonesbuildErrorResponses_getBodys__call__(((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf0.pysRequestProcessors     c Csmt|do |i}n |i}tid|dt|dtt i |||i ddSdS(sj Builds a L{ErrorFault} object based on the last exception raised. s _amf_codescodes descriptionsdetailss\nsN( shasattrsclss _amf_codescodes__name__sremotings ErrorFaultsstrses tracebacksformat_exceptionstbsreplace(sclssestbscode((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf0.pys build_faultrs   ( s__doc__s tracebackssysspyamfsremotingspyamf.remotingsgatewaysobjectsRequestProcessors build_fault(sRequestProcessorsremotings build_faults tracebackssyssgateway((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf0.pys?s   cPKũ:blpyamf/remoting/amf3.pyc; +~Ic@sdZdkZdkZdkZdkZdkZdklZdklZei ei Z dei fdYZ de fdYZeiede i[ d Zed Zd Zd efd YZdS(s AMF3 RemoteObject support. @see: U{RemoteObject on LiveDocs } @since: 0.1.0 N(sremoting(s messagingsBaseServerErrorcBstZdZRS(s Base server error. (s__name__s __module__s__doc__(((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf3.pysBaseServerErrors sServerCallFailedcBstZdZdZRS(s A catchall error. sServer.Call.Failed(s__name__s __module__s__doc__s _amf_code(((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf3.pysServerCallFaileds sattrscCsttiSdS(N(sstrsuuidsuuid4(((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf3.pysgenerate_random_id$scCs[ti}t|_t|_titi |_ |o|i|_ n|SdS(N( s messagingsAcknowledgeMessagesacksgenerate_random_ids messageIdsclientIdscalendarstimegmstimesgmtimes timestampsrequests correlationId(srequestsack((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf3.pysgenerate_acknowledgement's   cCsdk}t|do |i}n |i}g}x6|i|||D]}|i |i ddqKWt idtdtdtitid|id |d t|d t|d |SdS( s Builds an L{ErrorMessage} based on the last traceback and the request that was sent. Ns _amf_codes\nss messageIdsclientIds timestamps correlationIds faultCodes faultStrings faultDetails extendedData(s tracebackshasattrsclss _amf_codescodes__name__sdetailsformat_exceptionsestbsxsappendsreplaces messagings ErrorMessagesgenerate_random_idscalendarstimegmstimesgmtimesrequests messageIdsstr(srequestsclssestbscodes tracebacksdetailsx((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf3.pysgenerate_error3s   sRequestProcessorcBsJtZdZedZdZdZdZdZdZ RS(NcCs ||_dS(N(sgatewaysself(sselfsgateway((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf3.pys__init__JscCsL|tj o|\}}}nti\}}}t||||SdS(s Builds an error response. @param request: The AMF request @type request: L{Request} @return: The AMF response @rtype: L{Response} N( serrorsNonesclssestbssyssexc_infosgenerate_errorsrequest(sselfsrequestserrorsestbscls((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf3.pysbuildErrorResponseMs  cKst|tio|i|||Snet|tio|i |||Sn;t|ti o|i |||Snt d|dS(s; @raise ServerCallFailed: Unknown request. sUnknown request: %sN( s isinstances ro_requests messagingsCommandMessagesselfs_processCommandMessages amf_requestskwargssRemotingMessages_processRemotingMessages AsyncMessages_processAsyncMessagesServerCallFailed(sselfs amf_requests ro_requestskwargs((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf3.pys_getBody]scKst|}|itiijot|_t i |Sna|itii jot dn;|itii jot i |Snt d|idS(s @raise ServerCallFailed: Unknown Command operation. @raise ServerCallFailed: Authorization is not supported in RemoteObject. s.Authorization is not supported in RemoteObjectsUnknown Command operation %sN(sgenerate_acknowledgements ro_requests ro_responses operations messagingsCommandMessagesPING_OPERATIONsTruesbodysremotingsResponsesLOGIN_OPERATIONsServerCallFailedsDISCONNECT_OPERATION(sselfs amf_requests ro_requestskwargss ro_response((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf3.pys_processCommandMessagejs  cKs&t|}t|_ti|SdS(N(sgenerate_acknowledgements ro_requests ro_responsesTruesbodysremotingsResponse(sselfs amf_requests ro_requestskwargss ro_response((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf3.pys_processAsyncMessage|s  cKst|}|i}t|do|iod|i|f}n|ii ||}|ii ||i ||ii||i ||_ ti|SdS(Ns destinations%s.%s(sgenerate_acknowledgements ro_requests ro_responses operations service_nameshasattrs destinationsselfsgatewaysgetServiceRequests amf_requestsservice_requestspreprocessRequestsbodyskwargsscallServiceRequestsremotingsResponse(sselfs amf_requests ro_requestskwargssservice_requests ro_responses service_name((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf3.pys_processRemotingMessages    cKsl|id}y|i|||SWnAttfj o n'ti |i |dti SnXdS(s Processes an AMF3 Remote Object request. @param amf_request: The request to be processed. @type amf_request: L{Request} @return: The response to the request. @rtype: L{Response} isstatusN( s amf_requestsbodys ro_requestsselfs_getBodyskwargssKeyboardInterrupts SystemExitsremotingsResponsesbuildErrorResponses STATUS_ERROR(sselfs amf_requestskwargss ro_request((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf3.pys__call__s  ( s__name__s __module__s__init__sNonesbuildErrorResponses_getBodys_processCommandMessages_processAsyncMessages_processRemotingMessages__call__(((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf3.pysRequestProcessorIs     (s__doc__scalendarstimesuuidssysspyamfsremotings pyamf.flexs messagingsget_class_aliass ErrorMessages error_aliass BaseErrorsBaseServerErrorsServerCallFailedsregister_classsattrssgenerate_random_idsNonesgenerate_acknowledgementsgenerate_errorsobjectsRequestProcessor(sgenerate_acknowledgementsremotingsuuidsRequestProcessorsgenerate_errorspyamfssyssServerCallFailedsBaseServerErrorsgenerate_random_idstimes messagingscalendars error_alias((s3build/bdist.linux-x86_64/egg/pyamf/remoting/amf3.pys? s$     PK":55pyamf/remoting/gateway/wsgi.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ WSGI server implementation. The Python Web Server Gateway Interface (WSGI) is a simple and universal interface between web servers and web applications or frameworks. The WSGI interface has two sides: the "server" or "gateway" side, and the "application" or "framework" side. The server side invokes a callable object (usually a function or a method) that is provided by the application side. Additionally WSGI provides middlewares; a WSGI middleware implements both sides of the API, so that it can be inserted "between" a WSGI server and a WSGI application -- the middleware will act as an application from the server's point of view, and as a server from the application's point of view. @see: U{WSGI homepage (external)} @see: U{PEP-333 (external)} @since: 0.1.0 """ import pyamf from pyamf import remoting from pyamf.remoting import gateway __all__ = ['WSGIGateway'] class WSGIGateway(gateway.BaseGateway): """ WSGI Remoting Gateway. """ def getResponse(self, request, environ): """ Processes the AMF request, returning an AMF response. @param request: The AMF Request. @type request: L{Envelope} @rtype: L{Envelope} @return: The AMF Response. """ response = remoting.Envelope(request.amfVersion, request.clientType) for name, message in request: processor = self.getProcessor(message) response[name] = processor(message, http_request=environ) return response def badRequestMethod(self, environ, start_response): """ Return HTTP 400 Bad Request. """ response = "400 Bad Request\n\nTo access this PyAMF gateway you " \ "must use POST requests (%s received)" % environ['REQUEST_METHOD'] start_response('400 Bad Request', [ ('Content-Type', 'text/plain'), ('Content-Length', str(len(response))), ('Server', gateway.SERVER_NAME), ]) return [response] def __call__(self, environ, start_response): """ @rtype: C{StringIO} @return: File-like object. """ if environ['REQUEST_METHOD'] != 'POST': return self.badRequestMethod(environ, start_response) body = environ['wsgi.input'].read(int(environ['CONTENT_LENGTH'])) stream = None context = pyamf.get_context(pyamf.AMF0) # Decode the request try: request = remoting.decode(body, context, strict=self.strict) except (pyamf.DecodeError, EOFError): self.logger.exception(gateway.format_exception()) response = "400 Bad Request\n\nThe request body was unable to " \ "be successfully decoded." if self.debug: response += "\n\nTraceback:\n\n%s" % gateway.format_exception() start_response('400 Bad Request', [ ('Content-Type', 'text/plain'), ('Content-Length', str(len(response))), ('Server', gateway.SERVER_NAME), ]) return [response] except (KeyboardInterrupt, SystemExit): raise except: self.logger.exception(gateway.format_exception()) response = "500 Internal Server Error\n\nAn unexpected error occurred whilst decoding." if self.debug: response += "\n\nTraceback:\n\n%s" % gateway.format_exception() start_response('500 Internal Server Error', [ ('Content-Type', 'text/plain'), ('Content-Length', str(len(response))), ('Server', gateway.SERVER_NAME), ]) return [response] self.logger.debug("AMF Request: %r" % request) # Process the request try: response = self.getResponse(request, environ) except (KeyboardInterrupt, SystemExit): raise except: self.logger.exception(gateway.format_exception()) response = "500 Internal Server Error\n\nThe request was " \ "unable to be successfully processed." if self.debug: response += "\n\nTraceback:\n\n%s" % gateway.format_exception() start_response('500 Internal Server Error', [ ('Content-Type', 'text/plain'), ('Content-Length', str(len(response))), ('Server', gateway.SERVER_NAME), ]) return [response] self.logger.debug("AMF Response: %r" % response) # Encode the response try: stream = remoting.encode(response, context, strict=self.strict) except: self.logger.exception(gateway.format_exception()) response = "500 Internal Server Error\n\nThe request was " \ "unable to be encoded." if self.debug: response += "\n\nTraceback:\n\n%s" % gateway.format_exception() start_response('500 Internal Server Error', [ ('Content-Type', 'text/plain'), ('Content-Length', str(len(response))), ('Server', gateway.SERVER_NAME), ]) return [response] response = stream.getvalue() start_response('200 OK', [ ('Content-Type', remoting.CONTENT_TYPE), ('Content-Length', str(len(response))), ('Server', gateway.SERVER_NAME), ]) return [response] PK":FF pyamf/remoting/gateway/google.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Gateway for Google App Engine. This gateway allows you to expose functions in Google App Engine web applications to AMF clients and servers. @see: U{Google App Engine homepage (external) } @since: 0.3.1 """ import sys, os.path try: sys.path.remove(os.path.dirname(os.path.abspath(__file__))) except ValueError: pass google = __import__('google') __import__('google.appengine.ext.webapp') webapp = google.appengine.ext.webapp import pyamf from pyamf import remoting from pyamf.remoting import gateway __all__ = ['WebAppGateway'] class WebAppGateway(webapp.RequestHandler, gateway.BaseGateway): """ Google App Engine Remoting Gateway. """ __name__ = None def __init__(self, *args, **kwargs): gateway.BaseGateway.__init__(self, *args, **kwargs) def getResponse(self, request): """ Processes the AMF request, returning an AMF response. @param request: The AMF Request. @type request: L{Envelope} @rtype: L{Envelope} @return: The AMF Response. """ response = remoting.Envelope(request.amfVersion, request.clientType) for name, message in request: processor = self.getProcessor(message) response[name] = processor(message, http_request=self.request) return response def get(self): self.response.headers['Content-Type'] = 'text/plain' self.response.headers['Server'] = gateway.SERVER_NAME self.error(405) self.response.out.write("405 Method Not Allowed\n\n" + \ "To access this PyAMF gateway you must use POST requests " + \ "(%s received)" % self.request.method) def post(self): body = self.request.body_file.read() stream = None context = pyamf.get_context(pyamf.AMF0) # Decode the request try: request = remoting.decode(body, context, strict=self.strict) except: fe = gateway.format_exception() self.logger.exception(fe) response = "400 Bad Request\n\nThe request body was unable to " \ "be successfully decoded." if self.debug: response += "\n\nTraceback:\n\n%s" % fe self.error(400) self.response.headers['Content-Type'] = 'text/plain' self.response.headers['Server'] = gateway.SERVER_NAME self.response.out.write(response) return self.logger.debug("AMF Request: %r" % request) # Process the request try: response = self.getResponse(request) except (KeyboardInterrupt, SystemExit): raise except: fe = gateway.format_exception() self.logger.exception(fe) response = "500 Internal Server Error\n\nThe request was " \ "unable to be successfully processed." if self.debug: response += "\n\nTraceback:\n\n%s" % fe self.error(500) self.response.headers['Content-Type'] = 'text/plain' self.response.headers['Server'] = gateway.SERVER_NAME self.response.out.write(response) return self.logger.debug("AMF Response: %r" % response) # Encode the response try: stream = remoting.encode(response, context, strict=self.strict) except: fe = gateway.format_exception() self.logger.exception(fe) response = "500 Internal Server Error\n\nThe request was " \ "unable to be encoded." if self.debug: response += "\n\nTraceback:\n\n%s" % fe self.error(500) self.response.headers['Content-Type'] = 'text/plain' self.response.headers['Server'] = gateway.SERVER_NAME self.response.out.write(response) return response = stream.getvalue() self.response.headers['Content-Type'] = remoting.CONTENT_TYPE self.response.headers['Content-Length'] = str(len(response)) self.response.headers['Server'] = gateway.SERVER_NAME self.response.out.write(response) def __call__(self, *args, **kwargs): return self PK":? FF"pyamf/remoting/gateway/__init__.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Remoting server implementations. @since: 0.1.0 """ import sys, types import pyamf from pyamf import remoting, logging, util SERVER_NAME = 'PyAMF/%s Python/%s' % ( '.'.join(map(lambda x: str(x), pyamf.__version__)), '.'.join(map(lambda x: str(x), sys.version_info[0:3])) ) fault_alias = pyamf.get_class_alias(remoting.ErrorFault) class BaseServiceError(pyamf.BaseError): """ Base service error. """ pyamf.register_class(BaseServiceError, attrs=fault_alias.attrs) del fault_alias class UnknownServiceError(BaseServiceError): """ Client made a request for an unknown service. """ _amf_code = 'Service.ResourceNotFound' class UnknownServiceMethodError(BaseServiceError): """ Client made a request for an unknown method. """ _amf_code = 'Service.MethodNotFound' class InvalidServiceMethodError(BaseServiceError): """ Client made a request for an invalid methodname. """ _amf_code = 'Service.MethodInvalid' class ServiceWrapper(object): """ Wraps a supplied service with extra functionality. @ivar service: The original service. @type service: C{callable} @ivar description: A description of the service. @type description: C{str} """ def __init__(self, service, description=None, authenticator=None, expose_request=None, preprocessor=None): self.service = service self.description = description self.authenticator = authenticator self.expose_request = expose_request self.preprocessor = preprocessor def __cmp__(self, other): if isinstance(other, ServiceWrapper): return cmp(self.__dict__, other.__dict__) return cmp(self.service, other) def _get_service_func(self, method, params): """ @raise InvalidServiceMethodError: Calls to private methods are not allowed. @raise UnknownServiceMethodError: Unknown method. @raise InvalidServiceMethodError: Service method must be callable. """ service = None if isinstance(self.service, (type, types.ClassType)): service = self.service() else: service = self.service if method is not None: method = str(method) if method.startswith('_'): raise InvalidServiceMethodError( "Calls to private methods are not allowed") try: func = getattr(service, method) except AttributeError: raise UnknownServiceMethodError( "Unknown method %s" % str(method)) if not callable(func): raise InvalidServiceMethodError( "Service method %s must be callable" % str(method)) return func if not callable(service): raise UnknownServiceMethodError( "Unknown method %s" % str(self.service)) return service def __call__(self, method, params): """ Executes the service. If the service is a class, it will be instantiated. @param method: The method to call on the service. @type method: C{None} or C{mixed} @param params: The params to pass to the service. @type params: C{list} or C{tuple} @return: The result of the execution. @rtype: C{mixed} """ func = self._get_service_func(method, params) return func(*params) def getMethods(self): """ Gets a C{dict} of valid method callables for the underlying service object. """ callables = {} for name in dir(self.service): method = getattr(self.service, name) if name.startswith('_') or not callable(method): continue callables[name] = method return callables def getAuthenticator(self, service_request=None): if service_request == None: return self.authenticator methods = self.getMethods() if service_request.method is None: if hasattr(self.service, '_pyamf_authenticator'): return self.service._pyamf_authenticator if service_request.method not in methods: return self.authenticator method = methods[service_request.method] if hasattr(method, '_pyamf_authenticator'): return method._pyamf_authenticator return self.authenticator def mustExposeRequest(self, service_request=None): if service_request == None: return self.expose_request methods = self.getMethods() if service_request.method is None: if hasattr(self.service, '_pyamf_expose_request'): return self.service._pyamf_expose_request return self.expose_request if service_request.method not in methods: return self.expose_request method = methods[service_request.method] if hasattr(method, '_pyamf_expose_request'): return method._pyamf_expose_request return self.expose_request def getPreprocessor(self, service_request=None): if service_request == None: return self.preprocessor methods = self.getMethods() if service_request.method is None: if hasattr(self.service, '_pyamf_preprocessor'): return self.service._pyamf_preprocessor if service_request.method not in methods: return self.preprocessor method = methods[service_request.method] if hasattr(method, '_pyamf_preprocessor'): return method._pyamf_preprocessor return self.preprocessor class ServiceRequest(object): """ Remoting service request. @ivar request: The request to service. @type request: L{Envelope} @ivar service: Facilitates the request. @type service: L{ServiceWrapper} @ivar method: The method to call on the service. A value of C{None} means that the service will be called directly. @type method: C{None} or C{str} """ def __init__(self, amf_request, service, method): self.request = amf_request self.service = service self.method = method def __call__(self, *args): return self.service(self.method, args) class ServiceCollection(dict): """ I hold a collection of services, mapping names to objects. """ def __contains__(self, value): if isinstance(value, basestring): return value in self.keys() return value in self.values() class BaseGateway(object): """ Generic Remoting gateway. @ivar services: A map of service names to callables. @type services: L{ServiceCollection} @ivar authenticator: A callable that will check the credentials of the request before allowing access to the service. Will return a C{bool} value. @type authenticator: C{Callable} or C{None} @ivar preprocessor: Called before the actual service method is invoked. Useful for setting up sessions etc. @ivar strict: Defines whether the gateway should use strict en/decoding. @type strict: C{bool} """ _request_class = ServiceRequest debug = False def __init__(self, services={}, authenticator=None, expose_request=False, preprocessor=None, debug=None, strict=False): """ @raise TypeError: C{dict} type is required for C{services}. """ self.logger = logging.instance_logger(self) self.services = ServiceCollection() self.authenticator = authenticator self.preprocessor = preprocessor self.expose_request = expose_request self.strict=strict if debug is not None: self.debug = debug if not hasattr(services, 'iteritems'): raise TypeError("dict type required for services") for name, service in services.iteritems(): self.addService(service, name) def addService(self, service, name=None, description=None, authenticator=None, expose_request=None, preprocessor=None): """ Adds a service to the gateway. @param service: The service to add to the gateway. @type service: C{callable}, class instance, or a module @param name: The name of the service. @type name: C{str} @raise pyamf.remoting.RemotingError: Service already exists. @raise TypeError: C{service} cannot be a scalar value. @raise TypeError: C{service} must be C{callable} or a module. """ if isinstance(service, (int, long, float, basestring)): raise TypeError("Service cannot be a scalar value") allowed_types = (types.ModuleType, types.FunctionType, types.DictType, types.MethodType, types.InstanceType, types.ObjectType) if not callable(service) and not isinstance(service, allowed_types): raise TypeError("Service must be a callable, module, or an object") if name is None: # TODO: include the module in the name if isinstance(service, (type, types.ClassType)): name = service.__name__ elif isinstance(service, types.FunctionType): name = service.func_name elif isinstance(service, types.ModuleType): name = service.__name__ else: name = str(service) if name in self.services: raise remoting.RemotingError("Service %s already exists" % name) self.services[name] = ServiceWrapper(service, description, authenticator, expose_request, preprocessor) def removeService(self, service): """ Removes a service from the gateway. @param service: The service to remove from the gateway. @type service: C{callable} or a class instance @raise NameError: Service not found. """ if service not in self.services: raise NameError("Service %s not found" % str(service)) for name, wrapper in self.services.iteritems(): if isinstance(service, basestring) and service == name: del self.services[name] return elif isinstance(service, ServiceWrapper) and wrapper == service: del self.services[name] return elif isinstance(service, (type, types.ClassType, types.FunctionType)) and wrapper.service == service: del self.services[name] return # shouldn't ever get here raise RuntimeError("Something went wrong ...") def getServiceRequest(self, request, target): """ Returns a service based on the message. @raise UnknownServiceError: Unknown service. @param request: The AMF request. @type request: L{Request} @rtype: L{ServiceRequest} """ try: return self._request_class( request.envelope, self.services[target], None) except KeyError: pass try: sp = target.split('.') name, meth = '.'.join(sp[:-1]), sp[-1] return self._request_class( request.envelope, self.services[name], meth) except (ValueError, KeyError): pass raise UnknownServiceError("Unknown service %s" % target) def getProcessor(self, request): """ Returns request processor. @param request: The AMF message. @type request: L{Request} """ if request.target == 'null': from pyamf.remoting import amf3 return amf3.RequestProcessor(self) else: from pyamf.remoting import amf0 return amf0.RequestProcessor(self) def getResponse(self, amf_request): """ Returns the response to the request. Any implementing gateway must define this function. @param amf_request: The AMF request. @type amf_request: L{Envelope} @return: The AMF response. @rtype: L{Envelope} """ raise NotImplementedError def mustExposeRequest(self, service_request): """ Decides whether the underlying http request should be exposed as the first argument to the method call. This is granular, looking at the service method first, then at the service level and finally checking the gateway. @rtype: C{bool} """ expose_request = service_request.service.mustExposeRequest(service_request) if expose_request is None: if self.expose_request is None: return False return self.expose_request return expose_request def getAuthenticator(self, service_request): """ Gets an authenticator callable based on the service_request. This is granular, looking at the service method first, then at the service level and finally to see if there is a global authenticator function for the gateway. Returns C{None} if one could not be found. """ auth = service_request.service.getAuthenticator(service_request) if auth is None: return self.authenticator return auth def authenticateRequest(self, service_request, username, password, **kwargs): """ Processes an authentication request. If no authenticator is supplied, then authentication succeeds. @return: Returns a C{bool} based on the result of authorization. A value of C{False} will stop processing the request and return an error to the client. @rtype: C{bool} """ authenticator = self.getAuthenticator(service_request) if authenticator is None: return True args = (username, password) if hasattr(authenticator, '_pyamf_expose_request'): http_request = kwargs.get('http_request', None) args = (http_request,) + args return authenticator(*args) == True def getPreprocessor(self, service_request): """ Gets a preprocessor callable based on the service_request. This is granular, looking at the service method first, then at the service level and finally to see if there is a global preprocessor function for the gateway. Returns C{None} if one could not be found. """ preproc = service_request.service.getPreprocessor(service_request) if preproc is None: return self.preprocessor return preproc def preprocessRequest(self, service_request, *args, **kwargs): """ Preprocesses a request. """ processor = self.getPreprocessor(service_request) if processor is None: return args = (service_request,) + args if hasattr(processor, '_pyamf_expose_request'): http_request = kwargs.get('http_request', None) args = (http_request,) + args return processor(*args) def callServiceRequest(self, service_request, *args, **kwargs): """ Executes the service_request call """ if self.mustExposeRequest(service_request): http_request = kwargs.get('http_request', None) args = (http_request,) + args return service_request(*args) def authenticate(func, c, expose_request=False): """ A decorator that facilitates authentication per method. Setting C{expose_request} to C{True} will set the underlying request object (if there is one), usually HTTP and set it to the first argument of the authenticating callable. If there is no request object, the default is C{None}. @raise TypeError: C{func} and authenticator must be callable. """ if not callable(func): raise TypeError('func must be callable') if not callable(c): raise TypeError('Authenticator must be callable') attr = func if isinstance(func, types.UnboundMethodType): attr = func.im_func if expose_request is True: c = globals()['expose_request'](c) setattr(attr, '_pyamf_authenticator', c) return func def expose_request(func): """ A decorator that adds an expose_request flag to the underlying callable. @raise TypeError: C{func} must be callable. """ if not callable(func): raise TypeError("func must be callable") if isinstance(func, types.UnboundMethodType): setattr(func.im_func, '_pyamf_expose_request', True) else: setattr(func, '_pyamf_expose_request', True) return func def preprocess(func, c, expose_request=False): """ A decorator that facilitates preprocessing per method. Setting C{expose_request} to C{True} will set the underlying request object (if there is one), usually HTTP and set it to the first argument of the preprocessing callable. If there is no request object, the default is C{None}. @raise TypeError: C{func} and preprocessor must be callable. """ if not callable(func): raise TypeError('func must be callable') if not callable(c): raise TypeError('Preprocessor must be callable') attr = func if isinstance(func, types.UnboundMethodType): attr = func.im_func if expose_request is True: c = globals()['expose_request'](c) setattr(attr, '_pyamf_preprocessor', c) return func def format_exception(): import traceback f = util.StringIO() traceback.print_exc(file=f) return f.getvalue() PK":D pyamf/remoting/gateway/django.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Gateway for the Django framework. This gateway allows you to expose functions in Django to AMF clients and servers. @see: U{Django homepage (external)} @since: 0.1.0 """ django = __import__('django.http') http = django.http import pyamf from pyamf import remoting from pyamf.remoting import gateway __all__ = ['DjangoGateway'] class DjangoGateway(gateway.BaseGateway): """ An instance of this class is suitable as a Django view. An example usage would be through C{urlconf}:: from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^gateway/', 'yourproject.yourapp.gateway.gw_instance'), ) where C{yourproject.yourapp.gateway.gw_instance} refers to an instance of this class. @ivar expose_request: The standard Django view always has the request object as the first parameter. To disable this functionality, set this to C{False}. @type expose_request: C{bool} """ def __init__(self, *args, **kwargs): kwargs['expose_request'] = kwargs.get('expose_request', True) gateway.BaseGateway.__init__(self, *args, **kwargs) def getResponse(self, http_request, request): """ Processes the AMF request, returning an AMF response. @param http_request: The underlying HTTP Request. @type http_request: C{HTTPRequest} @param request: The AMF Request. @type request: L{Envelope} @rtype: L{Envelope} @return: The AMF Response. """ response = remoting.Envelope(request.amfVersion, request.clientType) for name, message in request: processor = self.getProcessor(message) response[name] = processor(message, http_request=http_request) return response def __call__(self, http_request): """ Processes and dispatches the request. @param http_request: The C{HTTPRequest} object. @type http_request: C{HTTPRequest} @return: The response to the request. @rtype: C{HTTPResponse} """ if http_request.method != 'POST': return http.HttpResponseNotAllowed(['POST']) context = pyamf.get_context(pyamf.AMF0) stream = None # Decode the request try: request = remoting.decode(http_request.raw_post_data, context, strict=self.strict) except (pyamf.DecodeError, EOFError): fe = gateway.format_exception() self.logger.exception(fe) response = "400 Bad Request\n\nThe request body was unable to " \ "be successfully decoded." if self.debug: response += "\n\nTraceback:\n\n%s" % fe return http.HttpResponseBadRequest(mimetype='text/plain', content=response) except (KeyboardInterrupt, SystemExit): raise except: fe = gateway.format_exception() self.logger.exception(fe) response = "500 Internal Server Error\n\nAn unexpected error occurred." if self.debug: response += "\n\nTraceback:\n\n%s" % fe return http.HttpResponseServerError(mimetype='text/plain', content=response) self.logger.debug("AMF Request: %r" % request) # Process the request try: response = self.getResponse(http_request, request) except (KeyboardInterrupt, SystemExit): raise except: fe = gateway.format_exception() self.logger.exception(fe) response = "500 Internal Server Error\n\nThe request was " \ "unable to be successfully processed." if self.debug: response += "\n\nTraceback:\n\n%s" % fe return http.HttpResponseServerError(mimetype='text/plain', content=response) self.logger.debug("AMF Response: %r" % response) # Encode the response try: stream = remoting.encode(response, context, strict=self.strict) except: fe = gateway.format_exception() self.logger.exception(fe) response = "500 Internal Server Error\n\nThe request was " \ "unable to be encoded." if self.debug: response += "\n\nTraceback:\n\n%s" % fe return http.HttpResponseServerError(mimetype='text/plain', content=response) buf = stream.getvalue() http_response = http.HttpResponse(mimetype=remoting.CONTENT_TYPE) http_response['Server'] = gateway.SERVER_NAME http_response['Content-Length'] = str(len(buf)) http_response.write(buf) return http_response PKɨ.:e22!pyamf/remoting/gateway/twisted.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Twisted server implementation. This gateway allows you to expose functions in Twisted to AMF clients and servers. @see: U{Twisted homepage (external)} @since: 0.1.0 """ import sys, os.path try: sys.path.remove('') except ValueError: pass try: sys.path.remove(os.path.dirname(os.path.abspath(__file__))) except ValueError: pass twisted = __import__('twisted') __import__('twisted.internet.defer') __import__('twisted.internet.threads') __import__('twisted.web.resource') __import__('twisted.web.server') defer = twisted.internet.defer threads = twisted.internet.threads resource = twisted.web.resource server = twisted.web.server import pyamf from pyamf import remoting from pyamf.remoting import gateway, amf0, amf3 __all__ = ['TwistedGateway'] class AMF0RequestProcessor(amf0.RequestProcessor): """ A Twisted friendly implementation of L{amf0.RequestProcessor} """ def __call__(self, request, *args, **kwargs): """ Calls the underlying service method. @return: A C{Deferred} that will contain the AMF L{Response}. @rtype: C{twisted.internet.defer.Deferred} """ try: service_request = self.gateway.getServiceRequest(request, request.target) except gateway.UnknownServiceError, e: return defer.succeed(self.buildErrorResponse(request)) response = remoting.Response(None) deferred_response = defer.Deferred() def eb(failure): errMesg = "%s: %s" % (failure.type, failure.getErrorMessage()) self.gateway.logger.error(errMesg) self.gateway.logger.info(failure.getTraceback()) deferred_response.callback(self.buildErrorResponse( request, (failure.type, failure.value, failure.tb))) def response_cb(result): self.gateway.logger.debug("AMF Response: %s" % (result,)) response.body = result deferred_response.callback(response) def preprocess_cb(result): d = defer.maybeDeferred(self._getBody, request, response, service_request, **kwargs) d.addCallback(response_cb).addErrback(eb) def auth_cb(result): if result is not True: response.status = remoting.STATUS_ERROR response.body = remoting.ErrorFault(code='AuthenticationError', description='Authentication failed') deferred_response.callback(response) return d = defer.maybeDeferred(self.gateway.preprocessRequest, service_request, *args, **kwargs) d.addCallback(preprocess_cb).addErrback(eb) # we have a valid service, now attempt authentication d = defer.maybeDeferred(self.authenticateRequest, request, service_request, **kwargs) d.addCallback(auth_cb).addErrback(eb) return deferred_response class AMF3RequestProcessor(amf3.RequestProcessor): """ A Twisted friendly implementation of L{amf3.RequestProcessor} """ def _processRemotingMessage(self, amf_request, ro_request, **kwargs): ro_response = amf3.generate_acknowledgement(ro_request) amf_response = remoting.Response(ro_response, status=remoting.STATUS_OK) try: service_name = ro_request.operation if hasattr(ro_request, 'destination') and ro_request.destination: service_name = '%s.%s' % (ro_request.destination, service_name) service_request = self.gateway.getServiceRequest(amf_request, service_name) except gateway.UnknownServiceError, e: return defer.succeed(remoting.Response( self.buildErrorResponse(ro_request), status=remoting.STATUS_ERROR)) deferred_response = defer.Deferred() def eb(failure): errMesg = "%s: %s" % (failure.type, failure.getErrorMessage()) self.gateway.logger.error(errMesg) self.gateway.logger.info(failure.getTraceback()) ro_response = self.buildErrorResponse(ro_request, (failure.type, failure.value, failure.tb)) deferred_response.callback(remoting.Response(ro_response, status=remoting.STATUS_ERROR)) def response_cb(result): ro_response.body = result res = remoting.Response(ro_response) self.gateway.logger.debug("AMF Response: %r" % (res,)) deferred_response.callback(res) def process_cb(result): d = defer.maybeDeferred(self.gateway.callServiceRequest, service_request, *ro_request.body, **kwargs) d.addCallback(response_cb).addErrback(eb) d = defer.maybeDeferred(self.gateway.preprocessRequest, service_request, *ro_request.body, **kwargs) d.addCallback(process_cb).addErrback(eb) return deferred_response def __call__(self, amf_request, **kwargs): """ Calls the underlying service method. @return: A C{deferred} that will contain the AMF L{Response}. @rtype: C{Deferred} """ deferred_response = defer.Deferred() ro_request = amf_request.body[0] def cb(amf_response): deferred_response.callback(amf_response) def eb(failure): errMesg = "%s: %s" % (failure.type, failure.getErrorMessage()) self.gateway.logger.error(errMesg) self.gateway.logger.info(failure.getTraceback()) deferred_response.callback(self.buildErrorResponse(ro_request, (failure.type, failure.value, failure.tb))) d = defer.maybeDeferred(self._getBody, amf_request, ro_request, **kwargs) d.addCallback(cb).addErrback(eb) return deferred_response class TwistedGateway(gateway.BaseGateway, resource.Resource): """ Twisted Remoting gateway for C{twisted.web}. @ivar expose_request: Forces the underlying HTTP request to be the first argument to any service call. @type expose_request: C{bool} """ allowedMethods = ('POST',) def __init__(self, *args, **kwargs): if 'expose_request' not in kwargs: kwargs['expose_request'] = True gateway.BaseGateway.__init__(self, *args, **kwargs) resource.Resource.__init__(self) def _finaliseRequest(self, request, status, content, mimetype='text/plain'): """ Finalises the request. @param request: The HTTP Request. @type request: C{http.Request} @param status: The HTTP status code. @type status: C{int} @param content: The content of the response. @type content: C{str} @param mimetype: The MIME type of the request. @type mimetype: C{str} """ request.setResponseCode(status) request.setHeader("Content-Type", mimetype) request.setHeader("Content-Length", str(len(content))) request.setHeader("Server", gateway.SERVER_NAME) request.write(content) request.finish() def render_POST(self, request): """ Read remoting request from the client. @type request: The HTTP Request. @param request: C{twisted.web.http.Request} """ def handleDecodeError(failure): """ Return HTTP 400 Bad Request. """ errMesg = "%s: %s" % (failure.type, failure.getErrorMessage()) self.logger.error(errMesg) self.logger.info(failure.getTraceback()) body = "400 Bad Request\n\nThe request body was unable to " \ "be successfully decoded." if self.debug: body += "\n\nTraceback:\n\n%s" % failure.getTraceback() self._finaliseRequest(request, 400, body) request.content.seek(0, 0) context = pyamf.get_context(pyamf.AMF0) d = threads.deferToThread(remoting.decode, request.content.read(), context, strict=self.strict) def cb(amf_request): self.logger.debug("AMF Request: %r" % amf_request) x = self.getResponse(request, amf_request) x.addCallback(self.sendResponse, request, context) # Process the request d.addCallback(cb).addErrback(handleDecodeError) return server.NOT_DONE_YET def sendResponse(self, amf_response, request, context): def cb(result): self._finaliseRequest(request, 200, result.getvalue(), remoting.CONTENT_TYPE) def eb(failure): """ Return 500 Internal Server Error. """ errMesg = "%s: %s" % (failure.type, failure.getErrorMessage()) self.logger.error(errMesg) self.logger.info(failure.getTraceback()) body = "500 Internal Server Error\n\nThere was an error encoding" \ " the response." if self.debug: body += "\n\nTraceback:\n\n%s" % failure.getTraceback() self._finaliseRequest(request, 500, body) d = threads.deferToThread(remoting.encode, amf_response, context, strict=self.strict) d.addCallback(cb).addErrback(eb) def getProcessor(self, request): """ Determines the request processor, based on the request. @param request: The AMF message. @type request: L{Request} """ if request.target == 'null': return AMF3RequestProcessor(self) return AMF0RequestProcessor(self) def getResponse(self, http_request, amf_request): """ Processes the AMF request, returning an AMF L{Response}. @param http_request: The underlying HTTP Request @type http_request: C{twisted.web.http.Request} @param amf_request: The AMF Request. @type amf_request: L{Envelope} """ response = remoting.Envelope(amf_request.amfVersion, amf_request.clientType) dl = [] def cb(body, name): response[name] = body for name, message in amf_request: processor = self.getProcessor(message) d = defer.maybeDeferred(processor, message, http_request=http_request) d.addCallback(cb, name) dl.append(d) def cb2(result): return response def eb(failure): """ Return 500 Internal Server Error. """ errMesg = "%s: %s" % (failure.type, failure.getErrorMessage()) self.logger.error(errMesg) self.logger.info(failure.getTraceback()) body = "500 Internal Server Error\n\nThe request was unable to " \ "be successfully processed." if self.debug: body += "\n\nTraceback:\n\n%s" % failure.getTraceback() self._finaliseRequest(http_request, 500, body) d = defer.DeferredList(dl) return d.addCallback(cb2).addErrback(eb) def authenticateRequest(self, service_request, username, password, **kwargs): """ Processes an authentication request. If no authenticator is supplied, then authentication succeeds. @return: C{Deferred}. @rtype: C{twisted.internet.defer.Deferred} """ authenticator = self.getAuthenticator(service_request) self.logger.debug('Authenticator expands to: %r' % authenticator) if authenticator is None: return defer.succeed(True) args = (username, password) if hasattr(authenticator, '_pyamf_expose_request'): http_request = kwargs.get('http_request', None) args = (http_request,) + args return defer.maybeDeferred(authenticator, *args) def preprocessRequest(self, service_request, *args, **kwargs): """ Preprocesses a request. """ processor = self.getPreprocessor(service_request) self.logger.debug('Preprocessor expands to: %r' % processor) if processor is None: return args = (service_request,) + args if hasattr(processor, '_pyamf_expose_request'): http_request = kwargs.get('http_request', None) args = (http_request,) + args return defer.maybeDeferred(processor, *args) PKũ:RY6pyamf/remoting/gateway/wsgi.pyc; La^Ic@sOdZdkZdklZdklZdgZdeifdYZdS(s? WSGI server implementation. The Python Web Server Gateway Interface (WSGI) is a simple and universal interface between web servers and web applications or frameworks. The WSGI interface has two sides: the "server" or "gateway" side, and the "application" or "framework" side. The server side invokes a callable object (usually a function or a method) that is provided by the application side. Additionally WSGI provides middlewares; a WSGI middleware implements both sides of the API, so that it can be inserted "between" a WSGI server and a WSGI application -- the middleware will act as an application from the server's point of view, and as a server from the application's point of view. @see: U{WSGI homepage (external)} @see: U{PEP-333 (external)} @since: 0.1.0 N(sremoting(sgateways WSGIGatewaycBs)tZdZdZdZdZRS(s WSGI Remoting Gateway. cCs\ti|i|i}x9|D]1\}}|i |}||d|||} @rtype: L{Envelope} @return: The AMF Response. s http_requestN( sremotingsEnvelopesrequests amfVersions clientTypesresponsesnamesmessagesselfs getProcessors processorsenviron(sselfsrequestsenvironsnames processorsmessagesresponse((s;build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/wsgi.pys getResponse$s cCsPd|d}|dddfdtt|fdtifg|gSdS( s. Return HTTP 400 Bad Request. sV400 Bad Request To access this PyAMF gateway you must use POST requests (%s received)sREQUEST_METHODs400 Bad Requests Content-Types text/plainsContent-LengthsServerN(senvironsresponsesstart_responsesstrslensgateways SERVER_NAME(sselfsenvironsstart_responsesresponse((s;build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/wsgi.pysbadRequestMethod5s7cCs|ddjo|i||Sn|dit|d}t}t i t i }yt i||d|i}Wn5t itfj o|iitid}|io|dti7}n|dd d fd tt|fd tifg|gSnttfj o n|iitid }|io|dti7}n|dd d fd tt|fd tifg|gSnX|iid|y|i||}Wnttfj o n|iitid}|io|dti7}n|dd d fd tt|fd tifg|gSnX|iid|yt i||d|i}Wn|iitid}|io|dti7}n|dd d fd tt|fd tifg|gSnX|i }|dd t i!fd tt|fd tifg|gSdS(sH @rtype: C{StringIO} @return: File-like object. sREQUEST_METHODsPOSTs wsgi.inputsCONTENT_LENGTHsstrictsH400 Bad Request The request body was unable to be successfully decoded.s Traceback: %ss400 Bad Requests Content-Types text/plainsContent-LengthsServersH500 Internal Server Error An unexpected error occurred whilst decoding.s500 Internal Server ErrorsAMF Request: %rsO500 Internal Server Error The request was unable to be successfully processed.sAMF Response: %rs@500 Internal Server Error The request was unable to be encoded.s200 OKN("senvironsselfsbadRequestMethodsstart_responsesreadsintsbodysNonesstreamspyamfs get_contextsAMF0scontextsremotingsdecodesstrictsrequests DecodeErrorsEOFErrorsloggers exceptionsgatewaysformat_exceptionsresponsesdebugsstrslens SERVER_NAMEsKeyboardInterrupts SystemExits getResponsesencodesgetvalues CONTENT_TYPE(sselfsenvironsstart_responsesbodysstreamsrequestscontextsresponse((s;build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/wsgi.pys__call__Dsb 7  7  7  7  :(s__name__s __module__s__doc__s getResponsesbadRequestMethods__call__(((s;build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/wsgi.pys WSGIGateways   (s__doc__spyamfsremotingspyamf.remotingsgateways__all__s BaseGateways WSGIGateway(spyamfsremotingsgateways__all__s WSGIGateway((s;build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/wsgi.pys?s     PKũ:>}}!pyamf/remoting/gateway/google.pyc; La^Ic@sdZdkZdkZy,eiieiieiieWne j onXe dZ e de i i iZdkZdklZdklZdgZdeieifdYZdS(s Gateway for Google App Engine. This gateway allows you to expose functions in Google App Engine web applications to AMF clients and servers. @see: U{Google App Engine homepage (external) } @since: 0.3.1 Nsgooglesgoogle.appengine.ext.webapp(sremoting(sgateways WebAppGatewaycBsAtZdZeZdZdZdZdZdZRS(s- Google App Engine Remoting Gateway. cOstii|||dS(N(sgateways BaseGateways__init__sselfsargsskwargs(sselfsargsskwargs((s=build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/google.pys__init__(scCs_ti|i|i}x<|D]4\}}|i |}||d|i||} @rtype: L{Envelope} @return: The AMF Response. s http_requestN( sremotingsEnvelopesrequests amfVersions clientTypesresponsesnamesmessagesselfs getProcessors processor(sselfsrequestsnames processorsmessagesresponse((s=build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/google.pys getResponse+s cCsYd|iidsiisBaseServiceErrorcBstZdZRS(s Base service error. (s__name__s __module__s__doc__(((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pysBaseServiceErrors sattrssUnknownServiceErrorcBstZdZdZRS(s7 Client made a request for an unknown service. sService.ResourceNotFound(s__name__s __module__s__doc__s _amf_code(((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pysUnknownServiceErrors sUnknownServiceMethodErrorcBstZdZdZRS(s6 Client made a request for an unknown method. sService.MethodNotFound(s__name__s __module__s__doc__s _amf_code(((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pysUnknownServiceMethodError$s sInvalidServiceMethodErrorcBstZdZdZRS(s: Client made a request for an invalid methodname. sService.MethodInvalid(s__name__s __module__s__doc__s _amf_code(((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pysInvalidServiceMethodError*s sServiceWrappercBsktZdZeeeedZdZdZdZdZedZ edZ edZ RS( s Wraps a supplied service with extra functionality. @ivar service: The original service. @type service: C{callable} @ivar description: A description of the service. @type description: C{str} cCs1||_||_||_||_||_dS(N(sservicesselfs descriptions authenticatorsexpose_requests preprocessor(sselfsservices descriptions authenticatorsexpose_requests preprocessor((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pys__init__9s     cCs;t|tot|i|iSnt|i|SdS(N(s isinstancesothersServiceWrapperscmpsselfs__dict__sservice(sselfsother((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pys__cmp__AscCst}t|ittifo|i}n |i}|tj ot|}|i dot dnyt ||}Wn)t j otdt|nXt| ot dt|n|Snt| otdt|in|SdS(s @raise InvalidServiceMethodError: Calls to private methods are not allowed. @raise UnknownServiceMethodError: Unknown method. @raise InvalidServiceMethodError: Service method must be callable. s_s(Calls to private methods are not allowedsUnknown method %ss"Service method %s must be callableN(sNonesservices isinstancesselfstypestypess ClassTypesmethodsstrs startswithsInvalidServiceMethodErrorsgetattrsfuncsAttributeErrorsUnknownServiceMethodErrorscallable(sselfsmethodsparamssfuncsservice((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pys_get_service_funcGs&   cCs |i||}||SdS(st Executes the service. If the service is a class, it will be instantiated. @param method: The method to call on the service. @type method: C{None} or C{mixed} @param params: The params to pass to the service. @type params: C{list} or C{tuple} @return: The result of the execution. @rtype: C{mixed} N(sselfs_get_service_funcsmethodsparamssfunc(sselfsmethodsparamssfunc((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pys__call__ns cCsih}xXt|iD]G}t|i|}|idp t| oqn|||} @ivar service: Facilitates the request. @type service: L{ServiceWrapper} @ivar method: The method to call on the service. A value of C{None} means that the service will be called directly. @type method: C{None} or C{str} cCs||_||_||_dS(N(s amf_requestsselfsrequestsservicesmethod(sselfs amf_requestsservicesmethod((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pys__init__s  cGs|i|i|SdS(N(sselfsservicesmethodsargs(sselfsargs((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pys__call__s(s__name__s __module__s__doc__s__init__s__call__(((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pysServiceRequests  sServiceCollectioncBstZdZdZRS(sD I hold a collection of services, mapping names to objects. cCs8t|to||ijSn||ijSdS(N(s isinstancesvalues basestringsselfskeyssvalues(sselfsvalue((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pys __contains__s(s__name__s __module__s__doc__s __contains__(((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pysServiceCollections s BaseGatewaycBstZdZeZeZheeeeedZeeeeedZ dZ dZ dZ dZ dZdZd Zd Zd Zd ZRS( s< Generic Remoting gateway. @ivar services: A map of service names to callables. @type services: L{ServiceCollection} @ivar authenticator: A callable that will check the credentials of the request before allowing access to the service. Will return a C{bool} value. @type authenticator: C{Callable} or C{None} @ivar preprocessor: Called before the actual service method is invoked. Useful for setting up sessions etc. @ivar strict: Defines whether the gateway should use strict en/decoding. @type strict: C{bool} c Csti||_t|_||_||_||_||_ |t j o ||_ nt |d ot dnx*|iD]\}}|i||qWdS(sM @raise TypeError: C{dict} type is required for C{services}. s iteritemssdict type required for servicesN(sloggingsinstance_loggersselfsloggersServiceCollectionsservicess authenticators preprocessorsexpose_requestsstrictsdebugsNoneshasattrs TypeErrors iteritemssnamesservices addService( sselfsservicess authenticatorsexpose_requests preprocessorsdebugsstrictsnamesservice((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pys__init__s        cCsRt|ttttfotdntiti ti ti ti ti f}t| ot|| otdn|tjovt|ttifo |i}qt|ti o |i}qt|tio |i}qt|}n||ijotid|nt||||||i|} @rtype: L{ServiceRequest} s.isUnknown service %sN(sselfs_request_classsrequestsenvelopesservicesstargetsNonesKeyErrorssplitsspsjoinsnamesmeths ValueErrorsUnknownServiceError(sselfsrequeststargetsspsmethsname((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pysgetServiceRequestWs!#!cCsL|idjodkl}|i|Sndkl}|i|SdS(s Returns request processor. @param request: The AMF message. @type request: L{Request} snull(samf3(samf0N(srequeststargetspyamf.remotingsamf3sRequestProcessorsselfsamf0(sselfsrequestsamf0samf3((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pys getProcessorqs   cCs tdS(s: Returns the response to the request. Any implementing gateway must define this function. @param amf_request: The AMF request. @type amf_request: L{Envelope} @return: The AMF response. @rtype: L{Envelope} N(sNotImplementedError(sselfs amf_request((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pys getResponses cCsJ|ii|}|tjo#|itjotSn|iSn|SdS(s Decides whether the underlying http request should be exposed as the first argument to the method call. This is granular, looking at the service method first, then at the service level and finally checking the gateway. @rtype: C{bool} N(sservice_requestsservicesmustExposeRequestsexpose_requestsNonesselfsFalse(sselfsservice_requestsexpose_request((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pysmustExposeRequests  cCs2|ii|}|tjo |iSn|SdS(s2 Gets an authenticator callable based on the service_request. This is granular, looking at the service method first, then at the service level and finally to see if there is a global authenticator function for the gateway. Returns C{None} if one could not be found. N(sservice_requestsservicesgetAuthenticatorsauthsNonesselfs authenticator(sselfsservice_requestsauth((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pysgetAuthenticators   cKsw|i|}|tjotSn||f}t |do#|i dt}|f|}n||tjSdS(sO Processes an authentication request. If no authenticator is supplied, then authentication succeeds. @return: Returns a C{bool} based on the result of authorization. A value of C{False} will stop processing the request and return an error to the client. @rtype: C{bool} s_pyamf_expose_requests http_requestN( sselfsgetAuthenticatorsservice_requests authenticatorsNonesTruesusernamespasswordsargsshasattrskwargssgets http_request(sselfsservice_requestsusernamespasswordskwargssargss http_requests authenticator((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pysauthenticateRequests   cCs2|ii|}|tjo |iSn|SdS(s/ Gets a preprocessor callable based on the service_request. This is granular, looking at the service method first, then at the service level and finally to see if there is a global preprocessor function for the gateway. Returns C{None} if one could not be found. N(sservice_requestsservicesgetPreprocessorspreprocsNonesselfs preprocessor(sselfsservice_requestspreproc((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pysgetPreprocessors   cOsr|i|}|tjodSn|f|}t|do#|idt}|f|}n||SdS(s) Preprocesses a request. Ns_pyamf_expose_requests http_request( sselfsgetPreprocessorsservice_requests processorsNonesargsshasattrskwargssgets http_request(sselfsservice_requestsargsskwargss http_requests processor((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pyspreprocessRequests  cOsA|i|o#|idt}|f|}n||SdS(s3 Executes the service_request call s http_requestN(sselfsmustExposeRequestsservice_requestskwargssgetsNones http_requestsargs(sselfsservice_requestsargsskwargss http_request((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pyscallServiceRequests (s__name__s __module__s__doc__sServiceRequests_request_classsFalsesdebugsNones__init__s addServices removeServicesgetServiceRequests getProcessors getResponsesmustExposeRequestsgetAuthenticatorsauthenticateRequestsgetPreprocessorspreprocessRequestscallServiceRequest(((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pys BaseGateways '         cCst| otdnt| otdn|}t|tio |i}n|t jot d|}nt |d||SdS(sx A decorator that facilitates authentication per method. Setting C{expose_request} to C{True} will set the underlying request object (if there is one), usually HTTP and set it to the first argument of the authenticating callable. If there is no request object, the default is C{None}. @raise TypeError: C{func} and authenticator must be callable. sfunc must be callablesAuthenticator must be callablesexpose_requests_pyamf_authenticatorN( scallablesfuncs TypeErrorscsattrs isinstancestypessUnboundMethodTypesim_funcsexpose_requestsTruesglobalsssetattr(sfuncscsexpose_requestsattr((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pys authenticates   cCs`t| otdnt|tiot|idtnt|dt|SdS(s A decorator that adds an expose_request flag to the underlying callable. @raise TypeError: C{func} must be callable. sfunc must be callables_pyamf_expose_requestN( scallablesfuncs TypeErrors isinstancestypessUnboundMethodTypessetattrsim_funcsTrue(sfunc((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pysexpose_request scCst| otdnt| otdn|}t|tio |i}n|t jot d|}nt |d||SdS(su A decorator that facilitates preprocessing per method. Setting C{expose_request} to C{True} will set the underlying request object (if there is one), usually HTTP and set it to the first argument of the preprocessing callable. If there is no request object, the default is C{None}. @raise TypeError: C{func} and preprocessor must be callable. sfunc must be callablesPreprocessor must be callablesexpose_requests_pyamf_preprocessorN( scallablesfuncs TypeErrorscsattrs isinstancestypessUnboundMethodTypesim_funcsexpose_requestsTruesglobalsssetattr(sfuncscsexpose_requestsattr((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pys preprocesss   cCs3dk}ti}|id||iSdS(Nsfile(s tracebacksutilsStringIOsfs print_excsgetvalue(s tracebacksf((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pysformat_exception8s  (!s__doc__ssysstypesspyamfsremotingsloggingsutilsjoinsmaps __version__s version_infos SERVER_NAMEsget_class_aliass ErrorFaults fault_aliass BaseErrorsBaseServiceErrorsregister_classsattrssUnknownServiceErrorsUnknownServiceMethodErrorsInvalidServiceMethodErrorsobjectsServiceWrappersServiceRequestsdictsServiceCollections BaseGatewaysFalses authenticatesexpose_requests preprocesssformat_exception(sremotingsUnknownServiceErrorspyamfs BaseGatewaysexpose_requestsInvalidServiceMethodErrors authenticates SERVER_NAMEsServiceCollections preprocesssBaseServiceErrorsServiceRequestsutils fault_aliasstypesssyssloggingsformat_exceptionsServiceWrappersUnknownServiceMethodError((s?build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/__init__.pys?s( G    PKũ:M!pyamf/remoting/gateway/django.pyc; La^Ic@sddZedZeiZdkZdklZdklZdgZdei fdYZ dS(s Gateway for the Django framework. This gateway allows you to expose functions in Django to AMF clients and servers. @see: U{Django homepage (external)} @since: 0.1.0 s django.httpN(sremoting(sgateways DjangoGatewaycBs)tZdZdZdZdZRS(sK An instance of this class is suitable as a Django view. An example usage would be through C{urlconf}:: from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^gateway/', 'yourproject.yourapp.gateway.gw_instance'), ) where C{yourproject.yourapp.gateway.gw_instance} refers to an instance of this class. @ivar expose_request: The standard Django view always has the request object as the first parameter. To disable this functionality, set this to C{False}. @type expose_request: C{bool} cOs0|idt|d} @param request: The AMF Request. @type request: L{Envelope} @rtype: L{Envelope} @return: The AMF Response. s http_requestN( sremotingsEnvelopesrequests amfVersions clientTypesresponsesnamesmessagesselfs getProcessors processors http_request(sselfs http_requestsrequestsnames processorsmessagesresponse((s=build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/django.pys getResponse2s  c Cs|idjotidgSntiti}t}y"t i |i |d|i}Wntitfj o[ti}|ii|d}|io|d|7}ntiddd|Snwttfj o n\ti}|ii|d}|io|d|7}ntiddd|SnX|iid |y|i||}Wnvttfj o n\ti}|ii|d }|io|d|7}ntiddd|SnX|iid |yt i||d|i}Wn[ti}|ii|d }|io|d|7}ntiddd|SnX|i}ti!dt i"}ti$|d } @since: 0.1.0 Nsstwistedstwisted.internet.deferstwisted.internet.threadsstwisted.web.resourcestwisted.web.server(sremoting(sgatewaysamf0samf3sTwistedGatewaysAMF0RequestProcessorcBstZdZdZRS(sq A Twisted friendly implementation of L{amf0.RequestProcessor} c syiiiWn.tij o}ti i SnXt i t  tid d d d}tii} | i|iSdS(s Calls the underlying service method. @return: A C{Deferred} that will contain the AMF L{Response}. @rtype: C{twisted.internet.defer.Deferred} cstd|i|if}iii|iii|i i i |i|i|ifdS(Ns%s: %s(sfailurestypesgetErrorMessageserrMesgsselfsgatewaysloggerserrorsinfos getTracebacksdeferred_responsescallbacksbuildErrorResponsesrequestsvaluestb(sfailureserrMesg(sdeferred_responsesselfsrequest(s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pysebBscs4iiid|f|_idS(NsAMF Response: %s( sselfsgatewaysloggersdebugsresultsresponsesbodysdeferred_responsescallback(sresult(sdeferred_responsesselfsresponse(s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pys response_cbIs cs8tii}|i i dS(N( sdefers maybeDeferredsselfs_getBodysrequestsresponsesservice_requestskwargssds addCallbacks response_cbs addErrbackseb(sresultsd(sservice_requestsselfsrequestsebskwargss response_cbsresponse(s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pys preprocess_cbOs cs|tj o<ti_tidddd_i dSnt i i i}|iidS(NscodesAuthenticationErrors descriptionsAuthentication failed(sresultsTruesremotings STATUS_ERRORsresponsesstatuss ErrorFaultsbodysdeferred_responsescallbacksdefers maybeDeferredsselfsgatewayspreprocessRequestsservice_requestsargsskwargssds addCallbacks preprocess_cbs addErrbackseb(sresultsd(sservice_requests preprocess_cbsselfsargssebskwargssdeferred_responsesresponse(s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pysauth_cbTs    N(sselfsgatewaysgetServiceRequestsrequeststargetsservice_requestsUnknownServiceErrorsesdeferssucceedsbuildErrorResponsesremotingsResponsesNonesresponsesDeferredsdeferred_responsesebs response_cbs preprocess_cbsauth_cbs maybeDeferredsauthenticateRequestskwargssds addCallbacks addErrback( sselfsrequestsargsskwargssservice_requestsesauth_cbs preprocess_cbsresponsesdeferred_responsesebs response_cbsd(( sselfsrequestsargsskwargssservice_requests response_cbs preprocess_cbsebsdeferred_responsesresponses>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pys__call__2s   ! (s__name__s __module__s__doc__s__call__(((s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pysAMF0RequestProcessor,s sAMF3RequestProcessorcBs tZdZdZdZRS(sq A Twisted friendly implementation of L{amf3.RequestProcessor} c sGtitidti} ySi}t doi odi |f}ni i||Wn@t ij o1}titiidtiSnXtiddd} tii ii}|i!| i"SdS(Nsstatuss destinations%s.%scsd|i|if}iii|iii|i i |i|i |i f}iti|dtidS(Ns%s: %ssstatus(sfailurestypesgetErrorMessageserrMesgsselfsgatewaysloggerserrorsinfos getTracebacksbuildErrorResponses ro_requestsvaluestbs ro_responsesdeferred_responsescallbacksremotingsResponses STATUS_ERROR(sfailures ro_responseserrMesg(sselfsdeferred_responses ro_request(s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pysebs $csC|_ti}iii d|fi |dS(NsAMF Response: %r( sresults ro_responsesbodysremotingsResponsesressselfsgatewaysloggersdebugsdeferred_responsescallback(sresultsres(s ro_responsesselfsdeferred_response(s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pys response_cbs cs;tiiii}|i i dS(N(sdefers maybeDeferredsselfsgatewayscallServiceRequestsservice_requests ro_requestsbodyskwargssds addCallbacks response_cbs addErrbackseb(sresultsd(sservice_requestsselfsebskwargss response_cbs ro_request(s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pys process_cbs(#samf3sgenerate_acknowledgements ro_requests ro_responsesremotingsResponses STATUS_OKs amf_responses operations service_nameshasattrs destinationsselfsgatewaysgetServiceRequests amf_requestsservice_requestsUnknownServiceErrorsesdeferssucceedsbuildErrorResponses STATUS_ERRORsDeferredsdeferred_responsesebs response_cbs process_cbs maybeDeferredspreprocessRequestsbodyskwargssds addCallbacks addErrback(sselfs amf_requests ro_requestskwargssservice_requests ro_responsesesds service_names process_cbs amf_responsesdeferred_responsesebs response_cb((sselfs ro_requestskwargssservice_requests response_cbs ro_responsesebsdeferred_responses>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pys_processRemotingMessageos$     !c spti|idd}d}tii ||}|i |i|SdS(s Calls the underlying service method. @return: A C{deferred} that will contain the AMF L{Response}. @rtype: C{Deferred} icsi|dS(N(sdeferred_responsescallbacks amf_response(s amf_response(sdeferred_response(s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pyscbscstd|i|if}iii|iii|i i i |i|i|ifdS(Ns%s: %s(sfailurestypesgetErrorMessageserrMesgsselfsgatewaysloggerserrorsinfos getTracebacksdeferred_responsescallbacksbuildErrorResponses ro_requestsvaluestb(sfailureserrMesg(sdeferred_responsesselfs ro_request(s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pysebs N(sdefersDeferredsdeferred_responses amf_requestsbodys ro_requestscbsebs maybeDeferredsselfs_getBodyskwargssds addCallbacks addErrback(sselfs amf_requestskwargssdscbsebsdeferred_responses ro_request((sselfsdeferred_responses ro_requests>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pys__call__s   (s__name__s __module__s__doc__s_processRemotingMessages__call__(((s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pysAMF3RequestProcessoris  .cBsbtZdZdfZdZddZdZdZdZdZ d Z d Z RS( s Twisted Remoting gateway for C{twisted.web}. @ivar expose_request: Forces the underlying HTTP request to be the first argument to any service call. @type expose_request: C{bool} sPOSTcOsEd|jot|dbuild/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pys__init__s s text/plaincCsg|i||id||idtt||idti |i ||i dS(sm Finalises the request. @param request: The HTTP Request. @type request: C{http.Request} @param status: The HTTP status code. @type status: C{int} @param content: The content of the response. @type content: C{str} @param mimetype: The MIME type of the request. @type mimetype: C{str} s Content-TypesContent-LengthsServerN( srequestssetResponseCodesstatuss setHeadersmimetypesstrslenscontentsgateways SERVER_NAMEswritesfinish(sselfsrequestsstatusscontentsmimetype((s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pys_finaliseRequests   csd}iiddtititi t i ii di}d}|i|i|tiSdS(s Read remoting request from the client. @type request: The HTTP Request. @param request: C{twisted.web.http.Request} cs~d|i|if}ii|ii|id}i o|d|i7}ni d|dS(s6 Return HTTP 400 Bad Request. s%s: %ssH400 Bad Request The request body was unable to be successfully decoded.s Traceback: %siN( sfailurestypesgetErrorMessageserrMesgsselfsloggerserrorsinfos getTracebacksbodysdebugs_finaliseRequestsrequest(sfailuresbodyserrMesg(sselfsrequest(s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pyshandleDecodeErrors isstrictcs@iid|i|}|iidS(NsAMF Request: %r( sselfsloggersdebugs amf_requests getResponsesrequestsxs addCallbacks sendResponsescontext(s amf_requestsx(sselfsrequestscontext(s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pyscbsN(shandleDecodeErrorsrequestscontentsseekspyamfs get_contextsAMF0scontextsthreadss deferToThreadsremotingsdecodesreadsselfsstrictsdscbs addCallbacks addErrbacksservers NOT_DONE_YET(sselfsrequestshandleDecodeErrorsdscbscontext((sselfsrequestscontexts>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pys render_POSTsc sYd}d}titi||di }|i |i |dS(Ncs#id|itidS(Ni(sselfs_finaliseRequestsrequestsresultsgetvaluesremotings CONTENT_TYPE(sresult(sselfsrequest(s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pyscbscs~d|i|if}ii|ii|id}i o|d|i7}ni d|dS(s; Return 500 Internal Server Error. s%s: %ssD500 Internal Server Error There was an error encoding the response.s Traceback: %siN( sfailurestypesgetErrorMessageserrMesgsselfsloggerserrorsinfos getTracebacksbodysdebugs_finaliseRequestsrequest(sfailuresbodyserrMesg(sselfsrequest(s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pyseb s sstrict( scbsebsthreadss deferToThreadsremotingsencodes amf_responsescontextsselfsstrictsds addCallbacks addErrback(sselfs amf_responsesrequestscontextsdscbseb((sselfsrequests>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pys sendResponses!cCs,|idjot|Snt|SdS(s Determines the request processor, based on the request. @param request: The AMF message. @type request: L{Request} snullN(srequeststargetsAMF3RequestProcessorsselfsAMF0RequestProcessor(sselfsrequest((s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pys getProcessorsc sti|i|ig}d}xX|D]P\}}i |}t i||d} | i|||i| q1Wd}d} t i|} | i|i| SdS(s) Processes the AMF request, returning an AMF L{Response}. @param http_request: The underlying HTTP Request @type http_request: C{twisted.web.http.Request} @param amf_request: The AMF Request. @type amf_request: L{Envelope} cs||build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pyscb8ss http_requestcsSdS(N(sresponse(sresult(sresponse(s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pyscb2Dscs~d|i|if}ii|ii|id}i o|d|i7}ni d|dS(s; Return 500 Internal Server Error. s%s: %ssO500 Internal Server Error The request was unable to be successfully processed.s Traceback: %siN( sfailurestypesgetErrorMessageserrMesgsselfsloggerserrorsinfos getTracebacksbodysdebugs_finaliseRequests http_request(sfailuresbodyserrMesg(sselfs http_request(s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pysebGs N(sremotingsEnvelopes amf_requests amfVersions clientTypesresponsesdlscbsnamesmessagesselfs getProcessors processorsdefers maybeDeferreds http_requestsds addCallbacksappendscb2sebs DeferredLists addErrback( sselfs http_requests amf_requestsdlsnamescbs processorscb2smessagesebsresponsesd((sselfs http_requestsresponses>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pys getResponse+s        cKs|i|}|iid||tjotit Sn||f}t |do#|idt}|f|}nti||SdS(s Processes an authentication request. If no authenticator is supplied, then authentication succeeds. @return: C{Deferred}. @rtype: C{twisted.internet.defer.Deferred} sAuthenticator expands to: %rs_pyamf_expose_requests http_requestN(sselfsgetAuthenticatorsservice_requests authenticatorsloggersdebugsNonesdeferssucceedsTruesusernamespasswordsargsshasattrskwargssgets http_requests maybeDeferred(sselfsservice_requestsusernamespasswordskwargssargss http_requests authenticator((s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pysauthenticateRequest\s  cOs|i|}|iid||tjodSn|f|}t|do#|i dt}|f|}nt i ||SdS(s) Preprocesses a request. sPreprocessor expands to: %rNs_pyamf_expose_requests http_request(sselfsgetPreprocessorsservice_requests processorsloggersdebugsNonesargsshasattrskwargssgets http_requestsdefers maybeDeferred(sselfsservice_requestsargsskwargss http_requests processor((s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pyspreprocessRequestrs  ( s__name__s __module__s__doc__sallowedMethodss__init__s_finaliseRequests render_POSTs sendResponses getProcessors getResponsesauthenticateRequestspreprocessRequest(((s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pysTwistedGateways     (  1 (s__doc__ssyssos.pathsosspathsremoves ValueErrorsdirnamesabspaths__file__s __import__stwistedsinternetsdefersthreadsswebsresourcesserverspyamfsremotingspyamf.remotingsgatewaysamf0samf3s__all__sRequestProcessorsAMF0RequestProcessorsAMF3RequestProcessors BaseGatewaysResourcesTwistedGateway(sdefersremotingsresources__all__stwistedsTwistedGatewaysserverssyssamf0samf3sthreadssAMF3RequestProcessorsAMF0RequestProcessorsgatewaysosspyamf((s>build/bdist.linux-x86_64/egg/pyamf/remoting/gateway/twisted.pys? s2,            =MPKY:lۋ>>!pyamf/remoting/client/__init__.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Remoting client implementation. @since: 0.1.0 """ import httplib, urlparse import pyamf from pyamf import remoting, logging #: Default AMF client type. #: @see: L{ClientTypes} DEFAULT_CLIENT_TYPE = pyamf.ClientTypes.Flash6 #: Default user agent is C{PyAMF/x.x.x}. DEFAULT_USER_AGENT = 'PyAMF/%s' % '.'.join(map(lambda x: str(x), pyamf.__version__)) HTTP_OK = 200 def convert_args(args): if args == (tuple(),): return [] else: return [x for x in args] class ServiceMethodProxy(object): """ Serves as a proxy for calling a service method. @ivar service: The parent service. @type service: L{ServiceProxy} @ivar name: The name of the method. @type name: C{str} or C{None} @see: L{ServiceProxy.__getattr__} """ def __init__(self, service, name): self.service = service self.name = name def __call__(self, *args): """ Inform the proxied service that this function has been called. """ return self.service._call(self, *args) def __str__(self): """ Returns the full service name, including the method name if there is one. """ service_name = str(self.service) if self.name is not None: service_name = '%s.%s' % (service_name, self.name) return service_name class ServiceProxy(object): """ Serves as a service object proxy for RPC calls. Generates L{ServiceMethodProxy} objects for method calls. @see: L{RequestWrapper} for more info. @ivar _gw: The parent gateway @type _gw: L{RemotingService} @ivar _name: The name of the service @type _name: C{str} @ivar _auto_execute: If set to C{True}, when a service method is called, the AMF request is immediately sent to the remote gateway and a response is returned. If set to C{False}, a L{RequestWrapper} is returned, waiting for the underlying gateway to fire the L{execute} method. """ def __init__(self, gw, name, auto_execute=True): self._gw = gw self._name = name self._auto_execute = auto_execute def __getattr__(self, name): return ServiceMethodProxy(self, name) def _call(self, method_proxy, *args): """ Executed when a L{ServiceMethodProxy} is called. Adds a request to the underlying gateway. If C{_auto_execute} is set to C{True}, then the request is immediately called on the remote gateway. """ request = self._gw.addRequest(method_proxy, *args) if self._auto_execute: response = self._gw.execute_single(request) # XXX nick: What to do about Fault objects here? return response.body return request def __call__(self, *args): """ This allows services to be 'called' without a method name. """ return self._call(ServiceMethodProxy(self, None), *args) def __str__(self): """ Returns a string representation of the name of the service. """ return self._name class RequestWrapper(object): """ A container object that wraps a service method request. @ivar gw: The underlying gateway. @type gw: L{RemotingService} @ivar id: The id of the request. @type id: C{str} @ivar service: The service proxy. @type service: L{ServiceProxy} @ivar args: The args used to invoke the call. @type args: C{list} """ def __init__(self, gw, id_, service, *args): self.gw = gw self.id = id_ self.service = service self.args = args def __str__(self): return str(self.id) def setResponse(self, response): """ A response has been received by the gateway """ # XXX nick: What to do about Fault objects here? self.response = response self.result = self.response.body if isinstance(self.result, remoting.ErrorFault): self.result.raiseException() def _get_result(self): """ Returns the result of the called remote request. If the request has not yet been called, an C{AttributeError} exception is raised. """ if not hasattr(self, '_result'): raise AttributeError("'RequestWrapper' object has no attribute 'result'") return self._result def _set_result(self, result): self._result = result result = property(_get_result, _set_result) class RemotingService(object): """ Acts as a client for AMF calls. @ivar url: The url of the remote gateway. Accepts C{http} or C{https} as valid schemes. @type url: C{str} @ivar requests: The list of pending requests to process. @type requests: C{list} @ivar request_number: A unique identifier for tracking the number of requests. @ivar amf_version: The AMF version to use. See L{ENCODING_TYPES}. @type amf_version: C{int} @ivar referer: The referer, or HTTP referer, identifies the address of the client. Ignored by default. @type referer: C{str} @ivar client_type: The client type. See L{ClientTypes}. @type client_type: C{int} @ivar user_agent: Contains information about the user agent (client) originating the request. See L{DEFAULT_USER_AGENT}. @type user_agent: C{str} @ivar connection: The underlying connection to the remoting server. @type connection: C{httplib.HTTPConnection} or C{httplib.HTTPSConnection} @ivar headers: A list of persistent headers to send with each request. @type headers: L{HeaderCollection} @ivar http_headers: A dict of HTTP headers to apply to the underlying HTTP connection. @type http_headers: L{dict} @ivar strict: Whether to use strict AMF en/decoding or not. @type strict: C{bool} """ def __init__(self, url, amf_version=pyamf.AMF0, client_type=DEFAULT_CLIENT_TYPE, referer=None, user_agent=DEFAULT_USER_AGENT, strict=False): self.logger = logging.instance_logger(self) self.original_url = url self.requests = [] self.request_number = 1 self.user_agent = user_agent self.referer = referer self.amf_version = amf_version self.client_type = client_type self.headers = remoting.HeaderCollection() self.http_headers = {} self.strict = strict self._setUrl(url) def _setUrl(self, url): """ @param url: Gateway URL. @type url: C{str} @raise ValueError: Unknown scheme. """ self.url = urlparse.urlparse(url) self._root_url = urlparse.urlunparse(['', ''] + list(self.url[2:])) port = None hostname = None if hasattr(self.url, 'port'): if self.url.port is not None: port = self.url.port else: if ':' not in self.url[1]: hostname = self.url[1] port = None else: sp = self.url[1].split(':') hostname, port = sp[0], sp[1] port = int(port) if hostname is None: if hasattr(self.url, 'hostname'): hostname = self.url.hostname if self.url[0] == 'http': if port is None: port = httplib.HTTP_PORT self.connection = httplib.HTTPConnection(hostname, port) elif self.url[0] == 'https': if port is None: port = httplib.HTTPS_PORT self.connection = httplib.HTTPSConnection(hostname, port) else: raise ValueError('Unknown scheme') location = '%s://%s:%s%s' % (self.url[0], hostname, port, self.url[2]) self.logger.info('Connecting to %s' % location) self.logger.debug('Referer: %s' % self.referer) self.logger.debug('User-Agent: %s' % self.user_agent) def addHeader(self, name, value, must_understand=False): """ Sets a persistent header to send with each request. @param name: Header name. @type name: C{str} @param must_understand: Default is C{False}. @type must_understand: C{bool} """ self.headers[name] = value self.headers.set_required(name, must_understand) def addHTTPHeader(self, name, value): """ Adds a header to the underlying HTTP connection. """ self.http_headers[name] = value def removeHTTPHeader(self, name): """ Deletes an HTTP header. """ del self.http_headers[name] def getService(self, name, auto_execute=True): """ Returns a L{ServiceProxy} for the supplied name. Sets up an object that can have method calls made to it that build the AMF requests. @param auto_execute: Default is C{True}. @type auto_execute: C{bool} @raise TypeError: C{string} type required for C{name}. @rtype: L{ServiceProxy} """ if not isinstance(name, basestring): raise TypeError('string type required') return ServiceProxy(self, name, auto_execute) def getRequest(self, id_): """ Gets a request based on the id. @raise LookupError: Request not found. """ for request in self.requests: if request.id == id_: return request raise LookupError("Request %s not found" % id_) def addRequest(self, service, *args): """ Adds a request to be sent to the remoting gateway. """ wrapper = RequestWrapper(self, '/%d' % self.request_number, service, *args) self.request_number += 1 self.requests.append(wrapper) self.logger.debug('Adding request %s%r' % (wrapper.service, args)) return wrapper def removeRequest(self, service, *args): """ Removes a request from the pending request list. @raise LookupError: Request not found. """ if isinstance(service, RequestWrapper): self.logger.debug('Removing request: %s' % ( self.requests[self.requests.index(service)])) del self.requests[self.requests.index(service)] return for request in self.requests: if request.service == service and request.args == args: self.logger.debug('Removing request: %s' % ( self.requests[self.requests.index(request)])) del self.requests[self.requests.index(request)] return raise LookupError("Request not found") def getAMFRequest(self, requests): """ Builds an AMF request L{Envelope} from a supplied list of requests. @param requests: List of requests @type requests: C{list} @rtype: L{Envelope} """ envelope = remoting.Envelope(self.amf_version, self.client_type) self.logger.debug('AMF version: %s' % self.amf_version) self.logger.debug('Client type: %s' % self.client_type) for request in requests: service = request.service args = list(request.args) envelope[request.id] = remoting.Request(str(service), args) envelope.headers = self.headers return envelope def _get_execute_headers(self): headers = self.http_headers.copy() headers.update({ 'Content-Type': remoting.CONTENT_TYPE, 'User-Agent': self.user_agent }) if self.referer is not None: headers['Referer'] = self.referer return headers def execute_single(self, request): """ Builds, sends and handles the response to a single request, returning the response. @param request: @type request: @rtype: """ self.logger.debug('Executing single request: %s' % request) body = remoting.encode(self.getAMFRequest([request]), strict=self.strict) self.logger.debug('Sending POST request to %s' % self._root_url) self.connection.request('POST', self._root_url, body.getvalue(), self._get_execute_headers() ) envelope = self._getResponse() self.removeRequest(request) return envelope[request.id] def execute(self): """ Builds, sends and handles the responses to all requests listed in C{self.requests}. """ body = remoting.encode(self.getAMFRequest(self.requests), strict=self.strict) self.logger.debug('Sending POST request to %s' % self._root_url) self.connection.request('POST', self._root_url, body.getvalue(), self._get_execute_headers() ) envelope = self._getResponse() for response in envelope: request = self.getRequest(response[0]) response = response[1] request.setResponse(response) self.removeRequest(request) def _getResponse(self): """ Gets and handles the HTTP response from the remote gateway. @raise RemotingError: HTTP Gateway reported error status. @raise RemotingError: Incorrect MIME type received. """ self.logger.debug('Waiting for response...') http_response = self.connection.getresponse() self.logger.debug('Got response status: %s' % http_response.status) self.logger.debug('Content-Type: %s' % http_response.getheader('Content-Type')) if http_response.status != HTTP_OK: self.logger.debug('Body: %s' % http_response.read()) if hasattr(httplib, 'responses'): raise remoting.RemotingError("HTTP Gateway reported status %d %s" % ( http_response.status, httplib.responses[http_response.status])) raise remoting.RemotingError("HTTP Gateway reported status %d" % ( http_response.status,)) content_type = http_response.getheader('Content-Type') if content_type != remoting.CONTENT_TYPE: self.logger.debug('Body = %s' % http_response.read()) raise remoting.RemotingError("Incorrect MIME type received. (got: %s)" % content_type) content_length = http_response.getheader('Content-Length') bytes = '' self.logger.debug('Content-Length: %s' % content_length) self.logger.debug('Server: %s' % http_response.getheader('Server')) if content_length in (None, ''): bytes = http_response.read() else: bytes = http_response.read(int(content_length)) self.logger.debug('Read %d bytes for the response' % len(bytes)) response = remoting.decode(bytes, strict=self.strict) self.logger.debug('Response: %s' % response) if remoting.APPEND_TO_GATEWAY_URL in response.headers: self.original_url += response.headers[remoting.APPEND_TO_GATEWAY_URL] self._setUrl(self.original_url) elif remoting.REPLACE_GATEWAY_URL in response.headers: self.original_url = response.headers[remoting.REPLACE_GATEWAY_URL] self._setUrl(self.original_url) if remoting.REQUEST_PERSISTENT_HEADER in response.headers: data = response.headers[remoting.REQUEST_PERSISTENT_HEADER] for k, v in data.iteritems(): self.headers[k] = v http_response.close() return response def setCredentials(self, username, password): """ Sets authentication credentials for accessing the remote gateway. """ self.addHeader('Credentials', dict(userid=unicode(username), password=unicode(password)), True) PKũ:j;RR"pyamf/remoting/client/__init__.pyc; QIc@sdZdkZdkZdkZdklZlZeiiZddi e dei Z dZ dZdefd YZd efd YZd efd YZdefdYZdS(s0 Remoting client implementation. @since: 0.1.0 N(sremotingsloggingsPyAMF/%ss.cCs t|S(N(sstrsx(sx((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pyssicCsD|tfjogSn&gi}|D]}||q)~SdS(N(sargsstuplesappends_[1]sx(sargss_[1]sx((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys convert_argsssServiceMethodProxycBs)tZdZdZdZdZRS(s Serves as a proxy for calling a service method. @ivar service: The parent service. @type service: L{ServiceProxy} @ivar name: The name of the method. @type name: C{str} or C{None} @see: L{ServiceProxy.__getattr__} cCs||_||_dS(N(sservicesselfsname(sselfsservicesname((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys__init__+s cGs|ii||SdS(sP Inform the proxied service that this function has been called. N(sselfsservices_callsargs(sselfsargs((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys__call__/scCs>t|i}|itj od||if}n|SdS(sc Returns the full service name, including the method name if there is one. s%s.%sN(sstrsselfsservices service_namesnamesNone(sselfs service_name((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys__str__6s (s__name__s __module__s__doc__s__init__s__call__s__str__(((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pysServiceMethodProxys   s ServiceProxycBs>tZdZedZdZdZdZdZRS(s| Serves as a service object proxy for RPC calls. Generates L{ServiceMethodProxy} objects for method calls. @see: L{RequestWrapper} for more info. @ivar _gw: The parent gateway @type _gw: L{RemotingService} @ivar _name: The name of the service @type _name: C{str} @ivar _auto_execute: If set to C{True}, when a service method is called, the AMF request is immediately sent to the remote gateway and a response is returned. If set to C{False}, a L{RequestWrapper} is returned, waiting for the underlying gateway to fire the L{execute} method. cCs||_||_||_dS(N(sgwsselfs_gwsnames_names auto_executes _auto_execute(sselfsgwsnames auto_execute((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys__init__Ts  cCst||SdS(N(sServiceMethodProxysselfsname(sselfsname((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys __getattr__YscGsD|ii||}|io|ii|}|i Sn|SdS(s Executed when a L{ServiceMethodProxy} is called. Adds a request to the underlying gateway. If C{_auto_execute} is set to C{True}, then the request is immediately called on the remote gateway. N( sselfs_gws addRequests method_proxysargssrequests _auto_executesexecute_singlesresponsesbody(sselfs method_proxysargssrequestsresponse((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys_call\s   cGs|it|t|SdS(sL This allows services to be 'called' without a method name. N(sselfs_callsServiceMethodProxysNonesargs(sselfsargs((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys__call__lscCs |iSdS(sM Returns a string representation of the name of the service. N(sselfs_name(sself((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys__str__rs( s__name__s __module__s__doc__sTrues__init__s __getattr__s_calls__call__s__str__(((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys ServiceProxyBs     sRequestWrappercBsJtZdZdZdZdZdZdZeeeZ RS(sV A container object that wraps a service method request. @ivar gw: The underlying gateway. @type gw: L{RemotingService} @ivar id: The id of the request. @type id: C{str} @ivar service: The service proxy. @type service: L{ServiceProxy} @ivar args: The args used to invoke the call. @type args: C{list} cGs(||_||_||_||_dS(N(sgwsselfsid_sidsservicesargs(sselfsgwsid_sservicesargs((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys__init__s   cCst|iSdS(N(sstrsselfsid(sself((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys__str__scCsC||_|ii|_t|itio|iindS(s= A response has been received by the gateway N(sresponsesselfsbodysresults isinstancesremotings ErrorFaultsraiseException(sselfsresponse((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys setResponses  cCs,t|d otdn|iSdS(s Returns the result of the called remote request. If the request has not yet been called, an C{AttributeError} exception is raised. s_results1'RequestWrapper' object has no attribute 'result'N(shasattrsselfsAttributeErrors_result(sself((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys _get_resultscCs ||_dS(N(sresultsselfs_result(sselfsresult((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys _set_results( s__name__s __module__s__doc__s__init__s__str__s setResponses _get_results _set_resultspropertysresult(((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pysRequestWrapperxs    sRemotingServicecBstZdZeieeeedZ dZ edZ dZ dZ edZdZdZd Zd Zd Zd Zd ZdZdZRS(s| Acts as a client for AMF calls. @ivar url: The url of the remote gateway. Accepts C{http} or C{https} as valid schemes. @type url: C{str} @ivar requests: The list of pending requests to process. @type requests: C{list} @ivar request_number: A unique identifier for tracking the number of requests. @ivar amf_version: The AMF version to use. See L{ENCODING_TYPES}. @type amf_version: C{int} @ivar referer: The referer, or HTTP referer, identifies the address of the client. Ignored by default. @type referer: C{str} @ivar client_type: The client type. See L{ClientTypes}. @type client_type: C{int} @ivar user_agent: Contains information about the user agent (client) originating the request. See L{DEFAULT_USER_AGENT}. @type user_agent: C{str} @ivar connection: The underlying connection to the remoting server. @type connection: C{httplib.HTTPConnection} or C{httplib.HTTPSConnection} @ivar headers: A list of persistent headers to send with each request. @type headers: L{HeaderCollection} @ivar http_headers: A dict of HTTP headers to apply to the underlying HTTP connection. @type http_headers: L{dict} @ivar strict: Whether to use strict AMF en/decoding or not. @type strict: C{bool} cCsti||_||_g|_d|_||_||_ ||_ ||_ t i |_h|_||_|i|dS(Ni(sloggingsinstance_loggersselfsloggersurls original_urlsrequestssrequest_numbers user_agentsreferers amf_versions client_typesremotingsHeaderCollectionsheaderss http_headerssstricts_setUrl(sselfsurls amf_versions client_typesreferers user_agentsstrict((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys__init__s         cCs ti||_tiddgt|id|_t}t}t |ido'|iitj o|ii}qnhd|idjo|id}t}n=|idi d}|d|df\}}t |}|tjo't |ido|ii}qn|iddjo3|tjo t i}nt i|||_nT|idd jo3|tjo t i}nt i|||_n td d |id|||idf}|iid ||iid |i|iid|idS(so @param url: Gateway URL. @type url: C{str} @raise ValueError: Unknown scheme. sisports:iishostnameshttpshttpssUnknown schemes %s://%s:%s%ssConnecting to %ss Referer: %ssUser-Agent: %sN(surlparsesurlsselfs urlunparseslists _root_urlsNonesportshostnameshasattrssplitsspsintshttplibs HTTP_PORTsHTTPConnections connections HTTPS_PORTsHTTPSConnections ValueErrorslocationsloggersinfosdebugsreferers user_agent(sselfsurlsspshostnameslocationsport((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys_setUrls<)         $cCs$||i|<|ii||dS(s Sets a persistent header to send with each request. @param name: Header name. @type name: C{str} @param must_understand: Default is C{False}. @type must_understand: C{bool} N(svaluesselfsheaderssnames set_requiredsmust_understand(sselfsnamesvaluesmust_understand((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys addHeader s cCs||i|build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys addHTTPHeaderscCs|i|=dS(s) Deletes an HTTP header. N(sselfs http_headerssname(sselfsname((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pysremoveHTTPHeaderscCs5t|t otdnt|||SdS(sT Returns a L{ServiceProxy} for the supplied name. Sets up an object that can have method calls made to it that build the AMF requests. @param auto_execute: Default is C{True}. @type auto_execute: C{bool} @raise TypeError: C{string} type required for C{name}. @rtype: L{ServiceProxy} sstring type requiredN(s isinstancesnames basestrings TypeErrors ServiceProxysselfs auto_execute(sselfsnames auto_execute((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys getService#s cCs@x)|iD]}|i|jo|Sq q Wtd|dS(sa Gets a request based on the id. @raise LookupError: Request not found. sRequest %s not foundN(sselfsrequestssrequestsidsid_s LookupError(sselfsid_srequest((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys getRequest2s   cGs`t|d|i||}|id7_|ii||ii d|i|f|SdS(sD Adds a request to be sent to the remoting gateway. s/%disAdding request %s%rN( sRequestWrappersselfsrequest_numbersservicesargsswrappersrequestssappendsloggersdebug(sselfsservicesargsswrapper((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys addRequest>s cGst|toE|iid|i|ii||i|ii|=dSnxv|iD]k}|i|jo |i |joE|iid|i|ii||i|ii|=dSq_q_Wt ddS(sr Removes a request from the pending request list. @raise LookupError: Request not found. sRemoving request: %sNsRequest not found( s isinstancesservicesRequestWrappersselfsloggersdebugsrequestssindexsrequestsargss LookupError(sselfsservicesargssrequest((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys removeRequestKs'  ' cCsti|i|i}|iid|i|iid|ixE|D]=}|i }t |i }ti t||||i} from a supplied list of requests. @param requests: List of requests @type requests: C{list} @rtype: L{Envelope} sAMF version: %ssClient type: %sN(sremotingsEnvelopesselfs amf_versions client_typesenvelopesloggersdebugsrequestssrequestsserviceslistsargssRequestsstrsidsheaders(sselfsrequestssservicesenvelopesargssrequest((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys getAMFRequestbs # cCs]|ii}|ihdti<d|i<|it j o|i|dbuild/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys_get_execute_headerszs %cCs|iid|ti|i|gd|i}|iid|i |i id|i |i |i |i }|i|||iSdS(s Builds, sends and handles the response to a single request, returning the response. @param request: @type request: @rtype: sExecuting single request: %ssstrictsSending POST request to %ssPOSTN(sselfsloggersdebugsrequestsremotingsencodes getAMFRequestsstrictsbodys _root_urls connectionsgetvalues_get_execute_headerss _getResponsesenvelopes removeRequestsid(sselfsrequestsbodysenvelope((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pysexecute_singles$    cCsti|i|id|i}|iid|i |i i d|i |i |i |i}xE|D]=}|i|d}|d}|i||i|qvWdS(sm Builds, sends and handles the responses to all requests listed in C{self.requests}. sstrictsSending POST request to %ssPOSTiiN(sremotingsencodesselfs getAMFRequestsrequestssstrictsbodysloggersdebugs _root_urls connectionsrequestsgetvalues_get_execute_headerss _getResponsesenvelopesresponses getRequests setResponses removeRequest(sselfsbodysenvelopesrequestsresponse((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pysexecutes$     c Cs|iid|ii}|iid|i|iid|id|itjoq|iid|i t t do*t i d|it i|ifnt i d|ifn|id}|t ijo1|iid |i t i d |n|id }d }|iid ||iid|id|td fjo|i }n|i t|}|iidt|t i|d|i}|iid|t i|ijo-|i|it i7_|i|in;t i|ijo'|it i|_|i|int i|ijo>|it i}x+|i D]\}}||i|build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys _getResponsesJ*  cCs2|idtdt|dt|tdS(sS Sets authentication credentials for accessing the remote gateway. s CredentialssuseridspasswordN(sselfs addHeadersdictsunicodesusernamespasswordsTrue(sselfsusernamespassword((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pyssetCredentialss(s__name__s __module__s__doc__spyamfsAMF0sDEFAULT_CLIENT_TYPEsNonesDEFAULT_USER_AGENTsFalses__init__s_setUrls addHeaders addHTTPHeadersremoveHTTPHeadersTrues getServices getRequests addRequests removeRequests getAMFRequests_get_execute_headerssexecute_singlesexecutes _getResponsessetCredentials(((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pysRemotingServices  0        @(s__doc__shttplibsurlparsespyamfsremotingsloggings ClientTypessFlash6sDEFAULT_CLIENT_TYPEsjoinsmaps __version__sDEFAULT_USER_AGENTsHTTP_OKs convert_argssobjectsServiceMethodProxys ServiceProxysRequestWrappersRemotingService( shttplibsremotingsloggingspyamfsurlparses convert_argssRequestWrappersServiceMethodProxysDEFAULT_CLIENT_TYPEsHTTP_OKsRemotingServices ServiceProxysDEFAULT_USER_AGENT((s>build/bdist.linux-x86_64/egg/pyamf/remoting/client/__init__.pys?s   #61PKS:lyՎ&&pyamf/util/imports.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Tools for doing dynamic imports This module has been borrowed from the Importing package. @see: U{http://pypi.python.org/pypi/Importing} @see: U{http://peak.telecommunity.com/DevCenter/Importing} Original author: U{Phillip J. Eby} @since: 0.3.0 """ __all__ = [ 'lazyModule', 'joinPath', 'whenImported', 'getModuleHooks', ] import sys, os.path from types import ModuleType postLoadHooks = {} loadedModules = [] try: from imp import find_module # google app engine requires this because it checks to ensure that the # find_module function is functioning at least basically # most appengine patchers just stub the function find_module('pyamf.util.imports') except ImportError: def find_module(subname, path=None): # the dev_appserver freaks out if you have pyc, pyo in here as # we're hooking pyamf.amf0 and pyamf.amf3 in the gae adapter and # monkey-patching it. It rightly complains as the byte-compiled module # is different to the 'final' module. PY_EXT = ('.py',) if path is None: path = sys.path for p in path: py = os.path.join(p, subname) for full in PY_EXT: full = py + full if os.path.exists(full): return open(full), full, None py = os.path.join(p, subname, '__init__') for full in PY_EXT: full = py + full if os.path.exists(full): return None, os.path.join(p, subname), None raise ImportError('No module named %s' % subname) class SubModuleLoadHook(object): def __init__(self, parent, child, hook, *args, **kwargs): self.parent = parent self.child = child self.hook = hook self.args = args self.kwargs = kwargs def __eq__(self, other): if not isinstance(other, SubModuleLoadHook): return False return self.parent == other.parent and self.child == other.child def __call__(self, module): return self.hook(*self.args, **self.kwargs) class AlreadyRead(Exception): pass class LazyModule(ModuleType): __slots__ = () __reserved_attrs__ = ('__name__', '__file__', '__path__') def __init__(self, name, file, path=None): ModuleType.__setattr__(self, '__name__', name) ModuleType.__setattr__(self, '__file__', file) if path is not None: ModuleType.__setattr__(self, '__path__', path) def __getattribute__(self, attr): if attr not in LazyModule.__reserved_attrs__: _loadModule(self) return ModuleType.__getattribute__(self, attr) def __setattr__(self, attr, value): if attr not in LazyModule.__reserved_attrs__: _loadModule(self) return ModuleType.__setattr__(self, attr, value) def _loadModule(module): if _isLazy(module) and module not in loadedModules: _loadAndRunHooks(module) def joinPath(modname, relativePath): """ Adjust a module name by a '/'-separated, relative or absolute path """ module = modname.split('.') for p in relativePath.split('/'): if p == '..': module.pop() elif not p: module = [] elif p != '.': module.append(p) return '.'.join(module) def lazyModule(modname, relativePath=None): """ Return module 'modname', but with its contents loaded "on demand" This function returns 'sys.modules[modname]', if present. Otherwise it creates a 'LazyModule' object for the specified module, caches it in 'sys.modules', and returns it. 'LazyModule' is a subclass of the standard Python module type, that remains empty until an attempt is made to access one of its attributes. At that moment, the module is loaded into memory, and any hooks that were defined via 'whenImported()' are invoked. Note that calling 'lazyModule' with the name of a non-existent or unimportable module will delay the 'ImportError' until the moment access is attempted. The 'ImportError' will occur every time an attribute access is attempted, until the problem is corrected. This function also takes an optional second parameter, 'relativePath', which will be interpreted as a '/'-separated path string relative to 'modname'. If a 'relativePath' is supplied, the module found by traversing the path will be loaded instead of 'modname'. In the path, '.' refers to the current module, and '..' to the current module's parent. For example:: fooBaz = lazyModule('foo.bar','../baz') will return the module 'foo.baz'. The main use of the 'relativePath' feature is to allow relative imports in modules that are intended for use with module inheritance. Where an absolute import would be carried over as-is into the inheriting module, an import relative to '__name__' will be relative to the inheriting module, e.g.:: something = lazyModule(__name__,'../path/to/something') The above code will have different results in each module that inherits it. (Note: 'relativePath' can also be an absolute path (starting with '/'); this is mainly useful for module '__bases__' lists.) """ if relativePath: modname = joinPath(modname, relativePath) if modname not in sys.modules: file_name = path = None if '.' in modname: splitpos = modname.rindex('.') parent = sys.modules[modname[:splitpos]] file_name = find_module(modname[splitpos + 1:], parent.__path__)[1] else: file_name = find_module(modname)[1] if os.path.isdir(file_name): path = [file_name] py = os.path.join(file_name, '__init__') for full in ('.pyo', '.pyc', '.py'): full = py + full if os.path.exists(full): break else: raise ImportError('No module name %d' % modname) file_name = full getModuleHooks(modname) # force an empty hook list into existence sys.modules[modname] = LazyModule(modname, file_name, path) if '.' in modname: # ensure parent module/package is in sys.modules # and parent.modname=module, as soon as the parent is imported splitpos = modname.rindex('.') whenImported( modname[:splitpos], lambda m: setattr(m, modname[splitpos + 1:], sys.modules[modname]) ) return sys.modules[modname] def _isLazy(module): """ Checks to see if the supplied C{module} is lazy """ if module.__name__ not in postLoadHooks.keys(): return False return postLoadHooks[module.__name__] is not None def _loadAndRunHooks(module): """ Load an unactivated "lazy" module object """ if _isLazy(module): # don't reload if already loaded! loadedModules.append(module) reload(module) try: for hook in getModuleHooks(module.__name__): hook(module) finally: # Ensure hooks are not called again, even if they fail postLoadHooks[module.__name__] = None def getModuleHooks(moduleName): """ Get list of hooks for 'moduleName'; error if module already loaded """ hooks = postLoadHooks.setdefault(moduleName, []) if hooks is None: raise AlreadyRead("Module already imported", moduleName) return hooks def _setModuleHook(moduleName, hook): if moduleName in sys.modules and postLoadHooks.get(moduleName) is None: # Module is already imported/loaded, just call the hook module = sys.modules[moduleName] hook(module) return module getModuleHooks(moduleName).append(hook) return lazyModule(moduleName) def whenImported(moduleName, hook): """ Call 'hook(module)' when module named 'moduleName' is first used 'hook' must accept one argument: the module object named by 'moduleName', which must be a fully qualified (i.e. absolute) module name. The hook should not raise any exceptions, or it may prevent later hooks from running. If the module has already been imported normally, 'hook(module)' is called immediately, and the module object is returned from this function. If the module has not been imported, or has only been imported lazily, then the hook is called when the module is first used, and a lazy import of the module is returned from this function. If the module was imported lazily and used before calling this function, the hook is called immediately, and the loaded module is returned from this function. Note that using this function implies a possible lazy import of the specified module, and lazy importing means that any 'ImportError' will be deferred until the module is used. """ if '.' in moduleName: # If parent is not yet imported, delay hook installation until the # parent is imported. splitpos = moduleName.rindex('.') sub_hook = SubModuleLoadHook(moduleName[:splitpos], moduleName[splitpos + 1:], _setModuleHook, moduleName, hook) if moduleName[:splitpos] not in postLoadHooks.keys(): whenImported(moduleName[:splitpos], sub_hook) elif postLoadHooks[moduleName[:splitpos]] is None: whenImported(moduleName[:splitpos], sub_hook) elif sub_hook not in postLoadHooks[moduleName[:splitpos]]: whenImported(moduleName[:splitpos], sub_hook) else: postLoadHooks[moduleName[:splitpos]].append(sub_hook) else: return _setModuleHook(moduleName, hook) PKmGl:WReRepyamf/util/__init__.py# -*- coding: utf-8 -*- # # Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ AMF Utilities. @since: 0.1.0 """ import struct, calendar, datetime, types import pyamf try: from cStringIO import StringIO except ImportError: from StringIO import StringIO xml_types = None ET = None negative_timestamp_broken = False def find_xml_lib(): """ Run through a predefined order looking through the various C{ElementTree} implementations so that any type can be encoded but PyAMF will return elements as the first implementation found. We work through the C implementations first - then the pure Python versions. The downside to this is that a possible of three libraries will be loaded into memory that are not used but the libs are small (relatively) and the flexibility that this gives seems to outweigh the cost. Time will tell. @since: 0.4 """ global xml_types, ET xml_types = [] try: import xml.etree.cElementTree as cET ET = cET xml_types.append(type(cET.Element('foo'))) except ImportError: pass try: import cElementTree as cET if ET is None: ET = cET xml_types.append(type(cET.Element('foo'))) except ImportError: pass try: import xml.etree.ElementTree as pET if ET is None: ET = pET xml_types.append(pET._ElementInterface) except ImportError: pass try: import elementtree.ElementTree as pET if ET is None: ET = pET xml_types.append(pET._ElementInterface) except ImportError: pass for x in xml_types[:]: # hack for jython if x.__name__ == 'instance': xml_types.remove(x) xml_types = tuple(xml_types) return xml_types class StringIOProxy(object): """ I am a C{StringIO} type object containing byte data from the AMF stream. @see: U{ByteArray on OSFlash (external) } @see: U{Parsing ByteArrays on OSFlash (external) } """ _wrapped_class = StringIO def __init__(self, buf=None): """ @raise TypeError: Unable to coerce C{buf} to C{StringIO}. """ self._buffer = StringIOProxy._wrapped_class() if isinstance(buf, (str, unicode)): self._buffer.write(buf) elif hasattr(buf, 'getvalue'): self._buffer.write(buf.getvalue()) elif hasattr(buf, 'read') and hasattr(buf, 'seek') and hasattr(buf, 'tell'): old_pos = buf.tell() buf.seek(0) self._buffer.write(buf.read()) buf.seek(old_pos) elif buf is None: pass else: raise TypeError("Unable to coerce buf->StringIO") self._get_len() self._len_changed = False self._buffer.seek(0, 0) def close(self): self._buffer.close() self._len = 0 self._len_changed = False def flush(self): self._buffer.flush() def getvalue(self): return self._buffer.getvalue() def next(self): return self._buffer.next() def read(self, n=-1): bytes = self._buffer.read(n) return bytes def readline(self): line = self._buffer.readline() return line def readlines(self, sizehint=0): """ @type sizehint: C{int} @param sizehint: Default is 0. @note: This function does not consume the buffer. """ lines = self._buffer.readlines(sizehint) return lines def seek(self, pos, mode=0): return self._buffer.seek(pos, mode) def tell(self): return self._buffer.tell() def truncate(self, size=0): if size == 0: self._buffer = StringIOProxy._wrapped_class() self._len_changed = True return cur_pos = self.tell() self.seek(0) buf = self.read(size) self._buffer = StringIOProxy._wrapped_class() self._buffer.write(buf) self.seek(cur_pos) self._len_changed = True def write(self, s): self._buffer.write(s) self._len_changed = True def writelines(self, iterable): self._buffer.writelines(iterable) self._len_changed = True def _get_len(self): if hasattr(self._buffer, 'len'): self._len = self._buffer.len return old_pos = self._buffer.tell() self._buffer.seek(0, 2) self._len = self._buffer.tell() self._buffer.seek(old_pos) def __len__(self): if not self._len_changed: return self._len self._get_len() self._len_changed = False return self._len def consume(self): """ Chops the tail off the stream starting at 0 and ending at C{tell()}. The stream pointer is set to 0 at the end of this function. @since: 0.4 """ bytes = self.read() self.truncate() if len(bytes) > 0: self.write(bytes) self.seek(0) class DataTypeMixIn(object): """ Provides methods for reading and writing basic data types for file-like objects. """ ENDIAN_NETWORK = "!" ENDIAN_NATIVE = "@" ENDIAN_LITTLE = "<" ENDIAN_BIG = ">" endian = ENDIAN_NETWORK def _read(self, length): """ Reads C{length} bytes from the stream. If an attempt to read past the end of the buffer is made, L{EOFError} is raised. """ bytes = self.read(length) if len(bytes) != length: self.seek(0 - len(bytes), 1) raise EOFError("Tried to read %d byte(s) from the stream" % length) return bytes def _is_big_endian(self): """ Whether this system is big endian or not. @rtype: C{bool} """ if self.endian == DataTypeMixIn.ENDIAN_NATIVE: return DataTypeMixIn._system_endian == DataTypeMixIn.ENDIAN_BIG return self.endian in (DataTypeMixIn.ENDIAN_BIG, DataTypeMixIn.ENDIAN_NETWORK) def read_uchar(self): """ Reads an C{unsigned char} from the stream. """ return struct.unpack("B", self._read(1))[0] def write_uchar(self, c): """ Writes an C{unsigned char} to the stream. @raise OverflowError: Not in range. """ if not 0 <= c <= 255: raise OverflowError("Not in range, %d" % c) self.write(struct.pack("B", c)) def read_char(self): """ Reads a C{char} from the stream. """ return struct.unpack("b", self._read(1))[0] def write_char(self, c): """ Write a C{char} to the stream. @raise OverflowError: Not in range. """ if not -128 <= c <= 127: raise OverflowError("Not in range, %d" % c) self.write(struct.pack("b", c)) def read_ushort(self): """ Reads a 2 byte unsigned integer from the stream. """ return struct.unpack("%sH" % self.endian, self._read(2))[0] def write_ushort(self, s): """ Writes a 2 byte unsigned integer to the stream. @raise OverflowError: Not in range. """ if not 0 <= s <= 65535: raise OverflowError("Not in range, %d" % s) self.write(struct.pack("%sH" % self.endian, s)) def read_short(self): """ Reads a 2 byte integer from the stream. """ return struct.unpack("%sh" % self.endian, self._read(2))[0] def write_short(self, s): """ Writes a 2 byte integer to the stream. @raise OverflowError: Not in range. """ if not -32768 <= s <= 32767: raise OverflowError("Not in range, %d" % s) self.write(struct.pack("%sh" % self.endian, s)) def read_ulong(self): """ Reads a 4 byte unsigned integer from the stream. """ return struct.unpack("%sL" % self.endian, self._read(4))[0] def write_ulong(self, l): """ Writes a 4 byte unsigned integer to the stream. @raise OverflowError: Not in range. """ if not 0 <= l <= 4294967295: raise OverflowError("Not in range, %d" % l) self.write(struct.pack("%sL" % self.endian, l)) def read_long(self): """ Reads a 4 byte integer from the stream. """ return struct.unpack("%sl" % self.endian, self._read(4))[0] def write_long(self, l): """ Writes a 4 byte integer to the stream. @raise OverflowError: Not in range. """ if not -2147483648 <= l <= 2147483647: raise OverflowError("Not in range, %d" % l) self.write(struct.pack("%sl" % self.endian, l)) def read_24bit_uint(self): """ Reads a 24 bit unsigned integer from the stream. @since: 0.4 """ order = None if not self._is_big_endian(): order = [0, 8, 16] else: order = [16, 8, 0] n = 0 for x in order: n += (self.read_uchar() << x) return n def write_24bit_uint(self, n): """ Writes a 24 bit unsigned integer to the stream. @since: 0.4 """ if not 0 <= n <= 0xffffff: raise OverflowError("n is out of range") order = None if not self._is_big_endian(): order = [0, 8, 16] else: order = [16, 8, 0] for x in order: self.write_uchar((n >> x) & 0xff) def read_24bit_int(self): """ Reads a 24 bit integer from the stream. @since: 0.4 """ n = self.read_24bit_uint() if n & 0x800000 != 0: # the int is signed n -= 0x1000000 return n def write_24bit_int(self, n): """ Writes a 24 bit integer to the stream. @since: 0.4 """ if not -8388608 <= n <= 8388607: raise OverflowError("n is out of range") order = None if not self._is_big_endian(): order = [0, 8, 16] else: order = [16, 8, 0] if n < 0: n += 0x1000000 for x in order: self.write_uchar((n >> x) & 0xff) def read_double(self): """ Reads an 8 byte float from the stream. """ return struct.unpack("%sd" % self.endian, self._read(8))[0] def write_double(self, d): """ Writes an 8 byte float to the stream. """ self.write(struct.pack("%sd" % self.endian, d)) def read_float(self): """ Reads a 4 byte float from the stream. """ return struct.unpack("%sf" % self.endian, self._read(4))[0] def write_float(self, f): """ Writes a 4 byte float to the stream. """ self.write(struct.pack("%sf" % self.endian, f)) def read_utf8_string(self, length): """ Reads a UTF-8 string from the stream. @rtype: C{unicode} """ str = struct.unpack("%s%ds" % (self.endian, length), self.read(length))[0] return unicode(str, "utf8") def write_utf8_string(self, u): """ Writes a unicode object to the stream in UTF-8 """ bytes = u.encode("utf8") self.write(struct.pack("%s%ds" % (self.endian, len(bytes)), bytes)) if struct.pack('@H', 1)[0] == '\x01': DataTypeMixIn._system_endian = DataTypeMixIn.ENDIAN_LITTLE else: DataTypeMixIn._system_endian = DataTypeMixIn.ENDIAN_BIG class BufferedByteStream(StringIOProxy, DataTypeMixIn): """ An extension of C{StringIO}. Features: - Raises L{EOFError} if reading past end. - Allows you to C{peek()} at the next byte. """ def __init__(self, buf=None): """ @param buf: Initial byte stream. @type buf: C{str} or C{StringIO} instance """ StringIOProxy.__init__(self, buf=buf) self.seek(0) def read(self, length=-1): """ Read bytes from stream. If we are at the end of the buffer, a C{EOFError} is raised. If there is not enough buffer to be read and length is specified C{IOError} is raised. @param length: Number of bytes to read. @type length: C{int} @raise EOFError: Reading past end of stream. @raise IOError: Length specified but not enough buffer available. @rtype: array of C{char} @return: The bytes read from the stream. """ if length > 0 and self.at_eof(): raise EOFError if length > 0 and self.tell() + length > len(self): raise IOError return StringIOProxy.read(self, length) def peek(self, size=1): """ Looks size bytes ahead in the stream, returning what it finds, returning the stream pointer to its initial position. @param size: Default is 1. @type size: C{int} @raise ValueError: Trying to peek backwards. @rtype: @return: Bytes. """ if size == -1: return self.peek(len(self) - self.tell()) if size < -1: raise ValueError("Cannot peek backwards") bytes = '' pos = self.tell() while not self.at_eof() and len(bytes) != size: bytes += self.read(1) self.seek(pos) return bytes def at_eof(self): """ Returns true if C{next.read(1)} will trigger an C{EOFError}. @rtype: C{bool} @return: """ return self.tell() >= len(self) def remaining(self): """ Returns number of remaining bytes. @rtype: C{number} @return: Number of remaining bytes. """ return len(self) - self.tell() def __add__(self, other): old_pos = self.tell() old_other_pos = other.tell() new = BufferedByteStream(self) other.seek(0) new.seek(0, 2) new.write(other.read()) self.seek(old_pos) other.seek(old_other_pos) new.seek(0) return new def hexdump(data): """ Get hexadecimal representation of C{StringIO} data. @type data: @param data: @rtype: C{str} @return: Hexadecimal string. """ import string hex = ascii = buf = "" index = 0 for c in data: hex += "%02x " % ord(c) if c in string.printable and c not in string.whitespace: ascii += c else: ascii += "." if len(ascii) == 16: buf += "%04x: %s %s %s\n" % (index, hex[:24], hex[24:], ascii) hex = ascii = "" index += 16 if len(ascii): buf += "%04x: %-24s %-24s %s\n" % (index, hex[:24], hex[24:], ascii) return buf def get_timestamp(d): """ Returns a UTC timestamp for a C{datetime.datetime} object. @type d: C{datetime.datetime} @param d: The date object. @return: UTC timestamp. @rtype: C{str} @note: Inspiration taken from the U{Intertwingly blog }. """ if isinstance(d, datetime.date) and not isinstance(d, datetime.datetime): d = datetime.datetime.combine(d, datetime.time(0, 0, 0, 0)) msec = str(d.microsecond).rjust(6).replace(' ', '0') return float('%s.%s' % (calendar.timegm(d.utctimetuple()), msec)) def get_datetime(secs): """ Return a UTC date from a timestamp. @type secs: C{long} @param secs: Seconds since 1970. @return: UTC timestamp. @rtype: C{datetime.datetime} """ if secs < 0 and negative_timestamp_broken: return datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=secs) return datetime.datetime.utcfromtimestamp(secs) def make_classic_instance(klass): """ Create an instance of a classic class (not inherited from ``object``) without calling __init__(). @type klass: C{class} @param klass: The classic class to create an instance for. @rtype: @return: instance created """ assert isinstance(klass, types.ClassType), "not an old style class" class _TemporaryClass: pass inst = _TemporaryClass() inst.__class__ = klass return inst def get_mro(C): """ Compute the class precedence list (mro). @raise TypeError: class type expected. """ def merge(seqs): """ @raise NameError: Inconsistent hierarchy. @raise TypeError: Class type expected. """ res = [] i = 0 while 1: nonemptyseqs = [seq for seq in seqs if seq] if not nonemptyseqs: return res i += 1 for seq in nonemptyseqs: cand = seq[0] nothead = [s for s in nonemptyseqs if cand in s[1:]] if nothead: cand = None else: break if not cand: raise NameError("Inconsistent hierarchy") res.append(cand) for seq in nonemptyseqs: if seq[0] == cand: del seq[0] if not isinstance(C, (types.ClassType, types.ObjectType)): raise TypeError('class type expected') if hasattr(C, '__mro__'): return C.__mro__ return merge([[C]] + map(get_mro, C.__bases__) + [list(C.__bases__)]) def get_attrs(obj): """ Gets a C{dict} of the attrs of an object in a predefined resolution order. @raise AttributeError: A duplicate attribute was already found in this collection, are you mixing different key types? """ if hasattr(obj, 'iteritems'): attrs = {} for k, v in obj.iteritems(): sk = str(k) if sk in attrs.keys(): raise AttributeError('A duplicate attribute (%s) was ' 'already found in this collection, are you mixing ' 'different key types?' % (sk,)) attrs[sk] = v return attrs elif hasattr(obj, '__dict__'): return obj.__dict__.copy() elif hasattr(obj, '__slots__'): attrs = {} for k in obj.__slots__: attrs[k] = getattr(obj, k) return attrs return None def set_attrs(obj, attrs): """ A generic function which applies a collection of attributes C{attrs} to object C{obj} @param obj: An instance implementing the __setattr__ function @param attrs: A collection implementing the iteritems function @type attrs: Usually a dict """ f = lambda n, v: setattr(obj, n, v) if isinstance(obj, (list, dict)): f = obj.__setitem__ for k, v in attrs.iteritems(): f(k, v) def get_class_alias(klass): for k, v in pyamf.ALIAS_TYPES.iteritems(): for kl in v: if isinstance(kl, types.FunctionType): if kl(klass) is True: return k elif isinstance(kl, (type, (types.ClassType, types.ObjectType))): if issubclass(klass, kl): return k return None class IndexedCollection(object): def __init__(self, use_hash=False): if use_hash is True: self.func = hash else: self.func = id self.clear() def clear(self): self.list = [] self.dict = {} def getByReference(self, ref): """ @raise TypeError: Bad reference type. @raise pyamf.ReferenceError: Reference not found. """ if not isinstance(ref, (int, long)): raise TypeError("Bad reference type") try: return self.list[ref] except IndexError: raise pyamf.ReferenceError("Reference %r not found" % (ref,)) def getReferenceTo(self, obj): """ @raise pyamf.ReferenceError: Value not found. """ try: return self.dict[self.func(obj)] except KeyError: raise pyamf.ReferenceError("Value %r not found" % (obj,)) def append(self, obj): h = self.func(obj) try: return self.dict[h] except KeyError: self.list.append(obj) idx = len(self.list) - 1 self.dict[h] = idx return idx def remove(self, obj): """ @raise pyamf.ReferenceError: Trying to remove an invalid reference. """ h = self.func(obj) try: idx = self.dict[h] except KeyError: raise pyamf.ReferenceError("%r is not a valid reference" % (obj,)) del self.list[idx] del self.dict[h] return idx def __eq__(self, other): if isinstance(other, list): return self.list == other elif isinstance(other, dict): return self.dict == other return False def __len__(self): return len(self.list) def __getitem__(self, idx): return self.getByReference(idx) def __contains__(self, obj): try: r = self.getReferenceTo(obj) except pyamf.ReferenceError: r = None return r is not None def __repr__(self): return '<%s list=%r dict=%r>' % (self.__class__.__name__, self.list, self.dict) def __iter__(self): return iter(self.list) class IndexedMap(IndexedCollection): """ Like L{IndexedCollection}, but also maps to another object. @since: 0.4 """ def __init__(self, use_hash=False): IndexedCollection.__init__(self, use_hash) self.mapped = [] def clear(self): IndexedCollection.clear(self) self.mapped = [] def getMappedByReference(self, ref): """ @raise TypeError: Bad reference type. @raise pyamf.ReferenceError: Reference not found. """ if not isinstance(ref, (int, long)): raise TypeError("Bad reference type.") try: return self.mapped[ref] except IndexError: raise pyamf.ReferenceError("Reference %r not found" % ref) def append(self, obj): idx = IndexedCollection.append(self, obj) diff = (idx + 1) - len(self.mapped) for i in range(0, diff): self.mapped.append(None) return idx def map(self, obj, mapped_obj): idx = self.append(obj) self.mapped[idx] = mapped_obj return idx def remove(self, obj): idx = IndexedCollection.remove(self, obj) del self.mapped[idx] return idx def is_ET_element(obj): """ Determines if the supplied C{obj} param is a valid ElementTree element. """ return isinstance(obj, xml_types) def is_float_broken(): """ Older versions of Python (<=2.5) and the Windows platform are renowned for mixing up 'special' floats. This function determines whether this is the case. @since: 0.4 @rtype: C{bool} """ # we do this instead of float('nan') because windows throws a wobbler. nan = 1e300000/1e300000 return str(nan) != str(struct.unpack("!d", '\xff\xf8\x00\x00\x00\x00\x00\x00')[0]) # init the module from here .. find_xml_lib() try: datetime.datetime.utcfromtimestamp(-31536000.0) except ValueError: negative_timestamp_broken = True if is_float_broken(): import fpconst def read_double_workaround(self): bytes = self.read(8) if self._is_big_endian(): if bytes == '\xff\xf8\x00\x00\x00\x00\x00\x00': return fpconst.NaN if bytes == '\xff\xf0\x00\x00\x00\x00\x00\x00': return fpconst.NegInf if bytes == '\x7f\xf0\x00\x00\x00\x00\x00\x00': return fpconst.PosInf else: if bytes == '\x00\x00\x00\x00\x00\x00\xf8\xff': return fpconst.NaN if bytes == '\x00\x00\x00\x00\x00\x00\xf0\xff': return fpconst.NegInf if bytes == '\x00\x00\x00\x00\x00\x00\xf0\x7f': return fpconst.PosInf return struct.unpack("%sd" % self.endian, bytes)[0] DataTypeMixIn.read_double = read_double_workaround def write_double_workaround(self, d): if fpconst.isNaN(d): if self._is_big_endian(): self.write('\xff\xf8\x00\x00\x00\x00\x00\x00') else: self.write('\x00\x00\x00\x00\x00\x00\xf8\xff') elif fpconst.isNegInf(d): if self._is_big_endian(): self.write('\xff\xf0\x00\x00\x00\x00\x00\x00') else: self.write('\x00\x00\x00\x00\x00\x00\xf0\xff') elif fpconst.isPosInf(d): if self._is_big_endian(): self.write('\x7f\xf0\x00\x00\x00\x00\x00\x00') else: self.write('\x00\x00\x00\x00\x00\x00\xf0\x7f') else: write_double_workaround.old_func(self, d) x = DataTypeMixIn.write_double DataTypeMixIn.write_double = write_double_workaround write_double_workaround.old_func = x try: from cpyamf.util import BufferedByteStream class StringIOProxy(BufferedByteStream): _wrapped_class = None def __init__(self, *args, **kwargs): BufferedByteStream.__init__(self, *args, **kwargs) self._buffer = self class DataTypeMixIn(BufferedByteStream): ENDIAN_NETWORK = "!" ENDIAN_NATIVE = "@" ENDIAN_LITTLE = "<" ENDIAN_BIG = ">" except ImportError: pass PKũ:0..pyamf/util/imports.pyc; PIc@sdZddddgZdkZdkZdklZhZgZydk l Z e dWne j oe d Z nXd e fd YZd efd YZdefdYZdZdZe dZdZdZdZdZdZdS(s Tools for doing dynamic imports This module has been borrowed from the Importing package. @see: U{http://pypi.python.org/pypi/Importing} @see: U{http://peak.telecommunity.com/DevCenter/Importing} Original author: U{Phillip J. Eby} @since: 0.3.0 s lazyModulesjoinPaths whenImportedsgetModuleHooksN(s ModuleType(s find_modulespyamf.util.importscCsdf}|tjo ti}nx|D]}tii||}xB|D]:}||}tii |ot ||tfSqLqLWtii||d}xK|D]C}||}tii |o ttii||tfSqqWq*Wt d|dS(Ns.pys__init__sNo module named %s( sPY_EXTspathsNonessysspsossjoinssubnamespysfullsexistssopens ImportError(ssubnamespathsfullspyspsPY_EXT((s2build/bdist.linux-x86_64/egg/pyamf/util/imports.pys find_module#s$     (sSubModuleLoadHookcBs#tZdZdZdZRS(NcOs1||_||_||_||_||_dS(N(sparentsselfschildshooksargsskwargs(sselfsparentschildshooksargsskwargs((s2build/bdist.linux-x86_64/egg/pyamf/util/imports.pys__init__As     cCs@t|t otSn|i|ijo|i|ijSdS(N(s isinstancesothersSubModuleLoadHooksFalsesselfsparentschild(sselfsother((s2build/bdist.linux-x86_64/egg/pyamf/util/imports.pys__eq__HscCs|i|i|iSdS(N(sselfshooksargsskwargs(sselfsmodule((s2build/bdist.linux-x86_64/egg/pyamf/util/imports.pys__call__Ns(s__name__s __module__s__init__s__eq__s__call__(((s2build/bdist.linux-x86_64/egg/pyamf/util/imports.pysSubModuleLoadHook@s  s AlreadyReadcBstZRS(N(s__name__s __module__(((s2build/bdist.linux-x86_64/egg/pyamf/util/imports.pys AlreadyReadQss LazyModulecBs;tZfZdddfZedZdZdZRS(Ns__name__s__file__s__path__cCsNti|d|ti|d||tj oti|d|ndS(Ns__name__s__file__s__path__(s ModuleTypes __setattr__sselfsnamesfilespathsNone(sselfsnamesfilespath((s2build/bdist.linux-x86_64/egg/pyamf/util/imports.pys__init__Xs cCs2|tijot|nti||SdS(N(sattrs LazyModules__reserved_attrs__s _loadModulesselfs ModuleTypes__getattribute__(sselfsattr((s2build/bdist.linux-x86_64/egg/pyamf/util/imports.pys__getattribute___scCs5|tijot|nti|||SdS(N(sattrs LazyModules__reserved_attrs__s _loadModulesselfs ModuleTypes __setattr__svalue(sselfsattrsvalue((s2build/bdist.linux-x86_64/egg/pyamf/util/imports.pys __setattr__es(s__name__s __module__s __slots__s__reserved_attrs__sNones__init__s__getattribute__s __setattr__(((s2build/bdist.linux-x86_64/egg/pyamf/util/imports.pys LazyModuleTs   cCs,t|o |tjot|ndS(N(s_isLazysmodules loadedModuless_loadAndRunHooks(smodule((s2build/bdist.linux-x86_64/egg/pyamf/util/imports.pys _loadModulekscCs|id}xb|idD]Q}|djo|iq| o g}q|djo|i|qqWdi|SdS(sL Adjust a module name by a '/'-separated, relative or absolute path s.s/s..N(smodnamessplitsmodules relativePathspspopsappendsjoin(smodnames relativePathsmodulesp((s2build/bdist.linux-x86_64/egg/pyamf/util/imports.pysjoinPathos   cs|ot|ntijoQt}}djoBidti }t d|i d}nt d}t ii|ot|g}t ii|d}xIdddfD](}||}t ii|oPqqWtd|}ntt||tisN(s relativePathsjoinPathsmodnamessyssmodulessNones file_namespathsrindexssplitpossparents find_modules__path__sossisdirsjoinspysfullsexistss ImportErrorsgetModuleHookss LazyModules whenImported(smodnames relativePathsfullsparentspyssplitposs file_namespath((smodnamessplitposs2build/bdist.linux-x86_64/egg/pyamf/util/imports.pys lazyModules6(  "       cCs3|itijotSnt|itj SdS(s9 Checks to see if the supplied C{module} is lazy N(smodules__name__s postLoadHooksskeyssFalsesNone(smodule((s2build/bdist.linux-x86_64/egg/pyamf/util/imports.pys_isLazyscCset|oti|t|nz(x!t|iD]}||q;WWdtt |i} @see: U{Parsing ByteArrays on OSFlash (external) } cCsti|_t|ttfo|ii|nt |do|ii|i nt |dot |do t |do@|i }|i d|ii|i|i |n|tjon td|it|_|ii dddS(sK @raise TypeError: Unable to coerce C{buf} to C{StringIO}. sgetvaluesreadsseekstellisUnable to coerce buf->StringION(s StringIOProxys_wrapped_classsselfs_buffers isinstancesbufsstrsunicodeswriteshasattrsgetvaluestellsold_possseeksreadsNones TypeErrors_get_lensFalses _len_changed(sselfsbufsold_pos((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys__init__fs"0      cCs#|iid|_t|_dS(Ni(sselfs_bufferscloses_lensFalses _len_changed(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysclose~s  cCs|iidS(N(sselfs_buffersflush(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysflushscCs|iiSdS(N(sselfs_buffersgetvalue(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysgetvaluescCs|iiSdS(N(sselfs_buffersnext(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysnextsicCs|ii|}|SdS(N(sselfs_buffersreadsnsbytes(sselfsnsbytes((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysreadscCs|ii}|SdS(N(sselfs_buffersreadlinesline(sselfsline((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysreadlinesicCs|ii|}|SdS(s @type sizehint: C{int} @param sizehint: Default is 0. @note: This function does not consume the buffer. N(sselfs_buffers readlinesssizehintslines(sselfssizehintslines((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys readlinesscCs|ii||SdS(N(sselfs_buffersseekspossmode(sselfspossmode((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysseekscCs|iiSdS(N(sselfs_bufferstell(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pystellscCs|djo ti|_t|_dSn|i}|i d|i |}ti|_|ii ||i |t|_dS(Ni( ssizes StringIOProxys_wrapped_classsselfs_buffersTrues _len_changedstellscur_possseeksreadsbufswrite(sselfssizesbufscur_pos((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pystruncates     cCs|ii|t|_dS(N(sselfs_bufferswritesssTrues _len_changed(sselfss((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pyswritescCs|ii|t|_dS(N(sselfs_buffers writelinessiterablesTrues _len_changed(sselfsiterable((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys writelinesscCsrt|ido|ii|_dSn|ii}|iidd|ii|_|ii|dS(Nslenii(shasattrsselfs_bufferslens_lenstellsold_possseek(sselfsold_pos((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys_get_lenscCs4|i o |iSn|it|_|iSdS(N(sselfs _len_changeds_lens_get_lensFalse(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys__len__s     cCsK|i}|it|djo|i||idndS(s Chops the tail off the stream starting at 0 and ending at C{tell()}. The stream pointer is set to 0 at the end of this function. @since: 0.4 iN(sselfsreadsbytesstruncateslenswritesseek(sselfsbytes((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysconsumes    (s__name__s __module__s__doc__sStringIOs_wrapped_classsNones__init__sclosesflushsgetvaluesnextsreadsreadlines readlinessseekstellstruncateswrites writeliness_get_lens__len__sconsume(((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys StringIOProxyZs$              s DataTypeMixIncBstZdZdZdZdZdZeZdZdZ dZ dZ d Z d Z d Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZRS(s^ Provides methods for reading and writing basic data types for file-like objects. s!s@scCsX|i|}t||jo.|idt|dtd|n|SdS(s Reads C{length} bytes from the stream. If an attempt to read past the end of the buffer is made, L{EOFError} is raised. iis(Tried to read %d byte(s) from the streamN(sselfsreadslengthsbytesslensseeksEOFError(sselfslengthsbytes((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys_reads cCsD|itijotitijSn|ititifjSdS(sT Whether this system is big endian or not. @rtype: C{bool} N(sselfsendians DataTypeMixIns ENDIAN_NATIVEs_system_endians ENDIAN_BIGsENDIAN_NETWORK(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys_is_big_endianscCs!tid|iddSdS(s< Reads an C{unsigned char} from the stream. sBiiN(sstructsunpacksselfs_read(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys read_ucharscCsPd|jo djn otd|n|itid|dS(sp Writes an C{unsigned char} to the stream. @raise OverflowError: Not in range. iisNot in range, %dsBN(scs OverflowErrorsselfswritesstructspack(sselfsc((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys write_uchar scCs!tid|iddSdS(s2 Reads a C{char} from the stream. sbiiN(sstructsunpacksselfs_read(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys read_charscCsPd|jo djn otd|n|itid|dS(se Write a C{char} to the stream. @raise OverflowError: Not in range. iisNot in range, %dsbN(scs OverflowErrorsselfswritesstructspack(sselfsc((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys write_charscCs(tid|i|iddSdS(sB Reads a 2 byte unsigned integer from the stream. s%sHiiN(sstructsunpacksselfsendians_read(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys read_ushort)scCsWd|jo djn otd|n|itid|i|dS(sv Writes a 2 byte unsigned integer to the stream. @raise OverflowError: Not in range. iisNot in range, %ds%sHN(sss OverflowErrorsselfswritesstructspacksendian(sselfss((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys write_ushort/scCs(tid|i|iddSdS(s9 Reads a 2 byte integer from the stream. s%shiiN(sstructsunpacksselfsendians_read(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys read_short:scCsWd|jo djn otd|n|itid|i|dS(sm Writes a 2 byte integer to the stream. @raise OverflowError: Not in range. iisNot in range, %ds%shN(sss OverflowErrorsselfswritesstructspacksendian(sselfss((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys write_short@scCs(tid|i|iddSdS(sB Reads a 4 byte unsigned integer from the stream. s%sLiiN(sstructsunpacksselfsendians_read(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys read_ulongKscCsWd|jo djn otd|n|itid|i|dS(sv Writes a 4 byte unsigned integer to the stream. @raise OverflowError: Not in range. iIsNot in range, %ds%sLN(sls OverflowErrorsselfswritesstructspacksendian(sselfsl((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys write_ulongQscCs(tid|i|iddSdS(s9 Reads a 4 byte integer from the stream. s%sliiN(sstructsunpacksselfsendians_read(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys read_long\scCsWd|jo djn otd|n|itid|i|dS(sm Writes a 4 byte integer to the stream. @raise OverflowError: Not in range. iisNot in range, %ds%slN(sls OverflowErrorsselfswritesstructspacksendian(sselfsl((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys write_longbscCsit}|i odddg}ndddg}d}x"|D]}||i|>7}qCW|SdS(sW Reads a 24 bit unsigned integer from the stream. @since: 0.4 iiiN(sNonesordersselfs_is_big_endiansnsxs read_uchar(sselfsxsordersn((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysread_24bit_uintmscCsd|jo djn otdnt}|i odddg}ndddg}x#|D]}|i||?d@qlWdS(sV Writes a 24 bit unsigned integer to the stream. @since: 0.4 iisn is out of rangeiiiN(sns OverflowErrorsNonesordersselfs_is_big_endiansxs write_uchar(sselfsnsxsorder((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pyswrite_24bit_uintscCs3|i}|d@djo|d8}n|SdS(sN Reads a 24 bit integer from the stream. @since: 0.4 iiiN(sselfsread_24bit_uintsn(sselfsn((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysread_24bit_ints  cCsd|jo djn otdnt}|i odddg}ndddg}|djo|d7}nx#|D]}|i||?d@qWd S( sM Writes a 24 bit integer to the stream. @since: 0.4 iisn is out of rangeiiiiiN(sns OverflowErrorsNonesordersselfs_is_big_endiansxs write_uchar(sselfsnsxsorder((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pyswrite_24bit_ints cCs(tid|i|iddSdS(s8 Reads an 8 byte float from the stream. s%sdiiN(sstructsunpacksselfsendians_read(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys read_doublescCs$|itid|i|dS(s7 Writes an 8 byte float to the stream. s%sdN(sselfswritesstructspacksendiansd(sselfsd((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys write_doublescCs(tid|i|iddSdS(s7 Reads a 4 byte float from the stream. s%sfiiN(sstructsunpacksselfsendians_read(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys read_floatscCs$|itid|i|dS(s6 Writes a 4 byte float to the stream. s%sfN(sselfswritesstructspacksendiansf(sselfsf((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys write_floatscCs=tid|i|f|i|d}t|dSdS(sS Reads a UTF-8 string from the stream. @rtype: C{unicode} s%s%dsisutf8N(sstructsunpacksselfsendianslengthsreadsstrsunicode(sselfslengthsstr((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysread_utf8_strings,cCs?|id}|itid|it|f|dS(s@ Writes a unicode object to the stream in UTF-8 sutf8s%s%dsN( susencodesbytessselfswritesstructspacksendianslen(sselfsusbytes((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pyswrite_utf8_strings( s__name__s __module__s__doc__sENDIAN_NETWORKs ENDIAN_NATIVEs ENDIAN_LITTLEs ENDIAN_BIGsendians_reads_is_big_endians read_uchars write_uchars read_chars write_chars read_ushorts write_ushorts read_shorts write_shorts read_ulongs write_ulongs read_longs write_longsread_24bit_uintswrite_24bit_uintsread_24bit_intswrite_24bit_ints read_doubles write_doubles read_floats write_floatsread_utf8_stringswrite_utf8_string(((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys DataTypeMixIns<                 s@HiissBufferedByteStreamcBsMtZdZedZddZddZdZdZdZ RS( s An extension of C{StringIO}. Features: - Raises L{EOFError} if reading past end. - Allows you to C{peek()} at the next byte. cCs$ti|d||iddS(sd @param buf: Initial byte stream. @type buf: C{str} or C{StringIO} instance sbufiN(s StringIOProxys__init__sselfsbufsseek(sselfsbuf((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys__init__sicCsl|djo |io tn|djo|i|t|jo tnti||SdS(s Read bytes from stream. If we are at the end of the buffer, a C{EOFError} is raised. If there is not enough buffer to be read and length is specified C{IOError} is raised. @param length: Number of bytes to read. @type length: C{int} @raise EOFError: Reading past end of stream. @raise IOError: Length specified but not enough buffer available. @rtype: array of C{char} @return: The bytes read from the stream. iN( slengthsselfsat_eofsEOFErrorstellslensIOErrors StringIOProxysread(sselfslength((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysreads  * icCs|djo!|it||iSn|djotdnd}|i}x9|i ot||jo||i d7}q`W|i ||SdS(s+ Looks size bytes ahead in the stream, returning what it finds, returning the stream pointer to its initial position. @param size: Default is 1. @type size: C{int} @raise ValueError: Trying to peek backwards. @rtype: @return: Bytes. isCannot peek backwardssiN( ssizesselfspeekslenstells ValueErrorsbytesspossat_eofsreadsseek(sselfssizesbytesspos((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pyspeeks  !  ! cCs|it|jSdS(sx Returns true if C{next.read(1)} will trigger an C{EOFError}. @rtype: C{bool} @return: N(sselfstellslen(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysat_eof-scCst||iSdS(s{ Returns number of remaining bytes. @rtype: C{number} @return: Number of remaining bytes. N(slensselfstell(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys remaining6scCs|i}|i}t|}|id|idd|i|i |i||i||id|SdS(Nii( sselfstellsold_possothers old_other_possBufferedByteStreamsnewsseekswritesread(sselfsothers old_other_possnewsold_pos((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys__add__?s       ( s__name__s __module__s__doc__sNones__init__sreadspeeksat_eofs remainings__add__(((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysBufferedByteStreams    cCsdk}d}}}d}x|D]}|dt|7}||ijo ||i jo||7}n |d7}t |djo:|d||d |d|f7}d}}|d7}q$q$Wt |o&|d ||d |d|f7}n|SdS( s Get hexadecimal representation of C{StringIO} data. @type data: @param data: @rtype: C{str} @return: Hexadecimal string. Nsis%02x s.is%04x: %s %s %s is%04x: %-24s %-24s %s ( sstringshexsasciisbufsindexsdatascsords printables whitespaceslen(sdatasindexscsstringsasciishexsbuf((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pyshexdumpOs"   "  &cCst|tiot|ti o+tii|tidddd}nt|iidi dd}t dt i |i|fSdS(s3 Returns a UTC timestamp for a C{datetime.datetime} object. @type d: C{datetime.datetime} @param d: The date object. @return: UTC timestamp. @rtype: C{str} @note: Inspiration taken from the U{Intertwingly blog }. iis s0s%s.%sN(s isinstancesdsdatetimesdatescombinestimesstrs microsecondsrjustsreplacesmsecsfloatscalendarstimegms utctimetuple(sdsmsec((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys get_timestampns '+$cCsO|djoto'tidddtid|Sntii|SdS(s Return a UTC date from a timestamp. @type secs: C{long} @param secs: Seconds since 1970. @return: UTC timestamp. @rtype: C{datetime.datetime} iiissecondsN(ssecssnegative_timestamp_brokensdatetimes timedeltasutcfromtimestamp(ssecs((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys get_datetimes'cCsJt|tip tddfdY}|}||_|SdS(s Create an instance of a classic class (not inherited from ``object``) without calling __init__(). @type klass: C{class} @param klass: The classic class to create an instance for. @rtype: @return: instance created snot an old style classs_TemporaryClasscBstZRS(N(s__name__s __module__(((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys_TemporaryClasssN(s isinstancesklassstypess ClassTypesAssertionErrors_TemporaryClasssinsts __class__(sklasssinsts_TemporaryClass((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysmake_classic_instances   cCsd}t|titif otdnt|do |iSn||ggt t |i t |i gSdS(s^ Compute the class precedence list (mro). @raise TypeError: class type expected. c Cs&g}d}xno gi}|D]}|o||q$q$~}| o|Sn|d7}xf|D]^}|d}gi}|D]%}||djo||qq~}|o t }qiPqiW| ot dn|i|x*|D]"}|d|jo |d=qqWqWdS(sj @raise NameError: Inconsistent hierarchy. @raise TypeError: Class type expected. iisInconsistent hierarchyN( sressisappends_[1]sseqssseqs nonemptyseqsscandsssnotheadsNones NameError( sseqss nonemptyseqsscandsseqsisressnotheads_[1]ss((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysmerges.2  <  sclass type expecteds__mro__N( smerges isinstancesCstypess ClassTypes ObjectTypes TypeErrorshasattrs__mro__smapsget_mros __bases__slist(sCsmerge((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysget_mros  cCst|dokh}xZ|iD]L\}}t|}||ijot d|fn|||sN( sfs isinstancesobjslistsdicts __setitem__sattrss iteritemssksv(sobjsattrssfsksv((sobjs3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys set_attrss   cCsxtiiD]\}}x~|D]v}t|tio||t jo|Sqq#t|t ti ti ffot||o|Sqq#q#WqWtSdS(N(spyamfs ALIAS_TYPESs iteritemssksvskls isinstancestypess FunctionTypesklasssTruestypes ClassTypes ObjectTypes issubclasssNone(sklasssksklsv((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysget_class_aliass  "sIndexedCollectioncBswtZedZdZdZdZdZdZdZ dZ d Z d Z d Z d ZRS( NcCs1|tjo t|_n t|_|idS(N(suse_hashsTrueshashsselfsfuncsidsclear(sselfsuse_hash((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys__init__s   cCsg|_h|_dS(N(sselfslistsdict(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysclears cCsft|ttf otdny|i|SWn)tj oti d|fnXdS(sq @raise TypeError: Bad reference type. @raise pyamf.ReferenceError: Reference not found. sBad reference typesReference %r not foundN( s isinstancesrefsintslongs TypeErrorsselfslists IndexErrorspyamfsReferenceError(sselfsref((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysgetByReferencescCsHy|i|i|SWn)tj otid|fnXdS(s? @raise pyamf.ReferenceError: Value not found. sValue %r not foundN(sselfsdictsfuncsobjsKeyErrorspyamfsReferenceError(sselfsobj((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysgetReferenceTo*s cCsl|i|}y|i|SWnGtj o;|ii|t|id}||i|<|SnXdS(Ni( sselfsfuncsobjshsdictsKeyErrorslistsappendslensidx(sselfsobjsidxsh((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysappend3s cCsh|i|}y|i|}Wn)tj otid|fnX|i |=|i|=|SdS(sU @raise pyamf.ReferenceError: Trying to remove an invalid reference. s%r is not a valid referenceN( sselfsfuncsobjshsdictsidxsKeyErrorspyamfsReferenceErrorslist(sselfsobjsidxsh((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysremove?s  cCsJt|to|i|jSn"t|to|i|jSntSdS(N(s isinstancesotherslistsselfsdictsFalse(sselfsother((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys__eq__Os cCst|iSdS(N(slensselfslist(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys__len__WscCs|i|SdS(N(sselfsgetByReferencesidx(sselfsidx((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys __getitem__ZscCs@y|i|}Wntij o t}nX|tj SdS(N(sselfsgetReferenceTosobjsrspyamfsReferenceErrorsNone(sselfsobjsr((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys __contains__]s  cCs!d|ii|i|ifSdS(Ns<%s list=%r dict=%r>(sselfs __class__s__name__slistsdict(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys__repr__escCst|iSdS(N(sitersselfslist(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys__iter__hs(s__name__s __module__sFalses__init__sclearsgetByReferencesgetReferenceTosappendsremoves__eq__s__len__s __getitem__s __contains__s__repr__s__iter__(((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysIndexedCollections        s IndexedMapcBsGtZdZedZdZdZdZdZdZ RS(sV Like L{IndexedCollection}, but also maps to another object. @since: 0.4 cCsti||g|_dS(N(sIndexedCollections__init__sselfsuse_hashsmapped(sselfsuse_hash((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys__init__rscCsti|g|_dS(N(sIndexedCollectionsclearsselfsmapped(sself((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysclearvs cCsct|ttf otdny|i|SWn&tj oti d|nXdS(sq @raise TypeError: Bad reference type. @raise pyamf.ReferenceError: Reference not found. sBad reference type.sReference %r not foundN( s isinstancesrefsintslongs TypeErrorsselfsmappeds IndexErrorspyamfsReferenceError(sselfsref((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysgetMappedByReferencezscCs[ti||}|dt|i}x'td|D]}|iit q9W|SdS(Nii( sIndexedCollectionsappendsselfsobjsidxslensmappedsdiffsrangesisNone(sselfsobjsidxsisdiff((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysappends cCs$|i|}||i|<|SdS(N(sselfsappendsobjsidxs mapped_objsmapped(sselfsobjs mapped_objsidx((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysmaps cCs$ti||}|i|=|SdS(N(sIndexedCollectionsremovesselfsobjsidxsmapped(sselfsobjsidx((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysremoves ( s__name__s __module__s__doc__sFalses__init__sclearsgetMappedByReferencesappendsmapsremove(((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys IndexedMapks     cCst|tSdS(sQ Determines if the supplied C{obj} param is a valid ElementTree element. N(s isinstancesobjs xml_types(sobj((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys is_ET_elementscCs4dd}t|ttidddjSdS(s Older versions of Python (<=2.5) and the Windows platform are renowned for mixing up 'special' floats. This function determines whether this is the case. @since: 0.4 @rtype: C{bool} finfs!dsiN(snansstrsstructsunpack(snan((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysis_float_brokens f -31536000.0cCs|id}|ioL|djo tiSn|djo tiSn|djo tiSqnI|djo tiSn|djo tiSn|djo tiSnti d|i |d SdS( Nisssssss%sdi( sselfsreadsbytess_is_big_endiansfpconstsNaNsNegInfsPosInfsstructsunpacksendian(sselfsbytes((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pysread_double_workarounds            cCsti|o/|io|idq|idnti|o/|io|idq|idnPti|o/|io|idq|idnti ||dS(Nssssss( sfpconstsisNaNsdsselfs_is_big_endianswritesisNegInfsisPosInfswrite_double_workaroundsold_func(sselfsd((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pyswrite_double_workarounds   (sBufferedByteStreamcBstZeZdZRS(NcOs ti|||||_dS(N(sBufferedByteStreams__init__sselfsargsskwargss_buffer(sselfsargsskwargs((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys__init__s(s__name__s __module__sNones_wrapped_classs__init__(((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys StringIOProxyscBs tZdZdZdZdZRS(Ns!s@s(s__name__s __module__sENDIAN_NETWORKs ENDIAN_NATIVEs ENDIAN_LITTLEs ENDIAN_BIG(((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys DataTypeMixIns(.s__doc__sstructscalendarsdatetimestypesspyamfs cStringIOsStringIOs ImportErrorsNones xml_typessETsFalsesnegative_timestamp_brokens find_xml_libsobjects StringIOProxys DataTypeMixInspacks ENDIAN_LITTLEs_system_endians ENDIAN_BIGsBufferedByteStreamshexdumps get_timestamps get_datetimesmake_classic_instancesget_mros get_attrss set_attrssget_class_aliassIndexedCollections IndexedMaps is_ET_elementsis_float_brokensutcfromtimestamps ValueErrorsTruesfpconstsread_double_workarounds read_doubleswrite_double_workarounds write_doublesxsold_funcs cpyamf.util(sget_mros get_timestampsBufferedByteStreamspyamfsdatetimeswrite_double_workarounds is_ET_elementscalendarshexdumpsstructs set_attrss IndexedMaps find_xml_libs DataTypeMixInsread_double_workaroundsIndexedCollections get_datetimesis_float_brokensfpconsts StringIOProxystypessnegative_timestamp_brokensmake_classic_instancesStringIOs get_attrssget_class_aliassx((s3build/bdist.linux-x86_64/egg/pyamf/util/__init__.pys? s`$  A h     . !  \-            PK":FO#pyamf/flex/data.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Flex Data Management Service implementation. This module contains the message classes used with Flex Data Management Service. @since: 0.1.0 """ import pyamf from pyamf.flex.messaging import AsyncMessage, AcknowledgeMessage, ErrorMessage __all__ = [ 'DataMessage', 'SequencedMessage', 'PagedMessage', 'DataErrorMessage' ] class DataMessage(AsyncMessage): """ I am used to transport an operation that occured on a managed object or collection. This class of message is transmitted between clients subscribed to a remote destination as well as between server nodes within a cluster. The payload of this message describes all of the relevant details of the operation. This information is used to replicate updates and detect conflicts. @see: U{DataMessage on Livedocs (external) } """ def __init__(self): AsyncMessage.__init__(self) #: Provides access to the identity map which defines the #: unique identity of the item affected by this DataMessage #: (relevant for create/update/delete but not fill operations). self.identity = None #: Provides access to the operation/command of this DataMessage. #: #: Operations indicate how the remote destination should process #: this message. self.operation = None class SequencedMessage(AcknowledgeMessage): """ Response to L{DataMessage} requests. @see: U{SequencedMessage on Livedocs (external) } """ def __init__(self): AcknowledgeMessage.__init__(self) #: Provides access to the sequence id for this message. #: #: The sequence id is a unique identifier for a sequence #: within a remote destination. This value is only unique for #: the endpoint and destination contacted. self.sequenceId = None #: self.sequenceProxies = None #: Provides access to the sequence size for this message. #: #: The sequence size indicates how many items reside in the #: remote sequence. self.sequenceSize = None #: self.dataMessage = None class PagedMessage(SequencedMessage): """ This messsage provides information about a partial sequence result. @see: U{PagedMessage on Livedocs (external) } """ def __init__(self): SequencedMessage.__init__(self) #: Provides access to the number of total pages in a sequence #: based on the current page size. self.pageCount = None #: Provides access to the index of the current page in a #: sequence. self.pageIndex = None class DataErrorMessage(ErrorMessage): """ Special cases of ErrorMessage will be sent when a data conflict occurs. This message provides the conflict information in addition to the L{ErrorMessage} information. @see: U{DataErrorMessage on Livedocs (external) } """ def __init__(self): ErrorMessage.__init__(self) #: The client oringinated message which caused the conflict. self.cause = None #: An array of properties that were found to be conflicting #: between the client and server objects. self.propertyNames = None #: The value that the server had for the object with the #: conflicting properties. self.serverObject = None #: Namespace for C{flex.data} messages. MESSAGES_NS = 'flex.data.messages' for x in (DataMessage, SequencedMessage, PagedMessage, DataErrorMessage): pyamf.register_class(x, '%s.%s' % (MESSAGES_NS, x.__name__), metadata=['amf3']) del x PK":Cf'f'pyamf/flex/messaging.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Flex Messaging implementation. This module contains the message classes used with Flex Data Services. @see: U{RemoteObject on OSFlash (external) } @since: 0.1.0 """ import pyamf __all__ = [ 'RemotingMessage', 'CommandMessage', 'AcknowledgeMessage', 'ErrorMessage' ] NAMESPACE = 'flex.messaging.messages' class AbstractMessage(object): """ Abstract base class for all Flex messages. Messages have two customizable sections; headers and data. The headers property provides access to specialized meta information for a specific message instance. The data property contains the instance specific data that needs to be delivered and processed by the decoder. @see: U{AbstractMessage on Livedocs (external) } @ivar body: Specific data that needs to be delivered to the remote destination. @type body: C{mixed} @ivar clientId: Indicates which client sent the message. @type clientId: C{str} @ivar destination: Message destination. @type destination: C{str} @ivar headers: Message headers. Core header names start with DS. @type headers: C{dict} @ivar messageId: Unique Message ID. @type messageId: C{str} @ivar timeToLive: How long the message should be considered valid and deliverable. @type timeToLive: C{int} @ivar timestamp: Timestamp when the message was generated. @type timestamp: C{int} """ #: Each message pushed from the server will contain this header identifying #: the client that will receive the message. DESTINATION_CLIENT_ID_HEADER = "DSDstClientId" #: Messages are tagged with the endpoint id for the channel they are sent #: over. ENDPOINT_HEADER = "DSEndpoint" #: Messages that need to set remote credentials for a destination carry the #: C{Base64} encoded credentials in this header. REMOTE_CREDENTIALS_HEADER = "DSRemoteCredentials" #: The request timeout value is set on outbound messages by services or #: channels and the value controls how long the responder will wait for an #: acknowledgement, result or fault response for the message before timing #: out the request. REQUEST_TIMEOUT_HEADER = "DSRequestTimeout" def __init__(self, *args, **kwargs): self.body = kwargs.get('body', None) self.clientId = kwargs.get('clientId', None) self.destination = kwargs.get('destination', None) self.headers = kwargs.get('headers', {}) self.messageId = kwargs.get('messageId', None) self.timeToLive = kwargs.get('timeToLive', 0) self.timestamp = kwargs.get('timestamp', 0) def __repr__(self): m = '<%s ' % self.__class__.__name__ for k, v in self.__dict__.iteritems(): m += ' %s=%r' % (k, v) return m + " />" # This class shouldn't be encoded directly but is registered to allow # inheritable static attrs to work pyamf.register_class(AbstractMessage, '.'.join([NAMESPACE, 'AbstractMessage']), attrs=[ 'body', 'clientId', 'destination', 'headers', 'messageId', 'timeToLive', 'timestamp' ], metadata=['amf3', 'static']) class AsyncMessage(AbstractMessage): """ I am the base class for all asynchronous Flex messages. @see: U{AsyncMessage on Livedocs (external) } @ivar correlationId: Correlation id of the message. @type correlationId: C{str} """ #: Messages that were sent with a defined subtopic property indicate their #: target subtopic in this header. SUBTOPIC_HEADER = "DSSubtopic" def __init__(self, *args, **kwargs): AbstractMessage.__init__(self, *args, **kwargs) self.correlationId = kwargs.get('correlationId', None) pyamf.register_class(AsyncMessage, '.'.join([NAMESPACE, 'AsyncMessage']), attrs=['correlationId'], metadata=['amf3', 'static']) class AcknowledgeMessage(AsyncMessage): """ I acknowledge the receipt of a message that was sent previously. Every message sent within the messaging system must receive an acknowledgement. @see: U{AcknowledgeMessage on Livedocs (external) } """ #: Used to indicate that the acknowledgement is for a message that #: generated an error. ERROR_HINT_HEADER = "DSErrorHint" pyamf.register_class(AcknowledgeMessage, '.'.join([NAMESPACE, 'AcknowledgeMessage']), attrs=[], metadata=['amf3', 'static']) class CommandMessage(AsyncMessage): """ Provides a mechanism for sending commands related to publish/subscribe messaging, ping, and cluster operations. @see: U{CommandMessage on Livedocs (external) } @ivar operation: The command @type operation: C{int} @ivar messageRefType: hmm, not sure about this one. @type messageRefType: C{str} """ #: The server message type for authentication commands. AUTHENTICATION_MESSAGE_REF_TYPE = "flex.messaging.messages.AuthenticationMessage" #: This is used to test connectivity over the current channel to the remote #: endpoint. PING_OPERATION = 5 #: This is used by a remote destination to sync missed or cached messages #: back to a client as a result of a client issued poll command. SYNC_OPERATION = 4 #: This is used to request a list of failover endpoint URIs for the remote #: destination based on cluster membership. CLUSTER_REQUEST_OPERATION = 7 #: This is used to send credentials to the endpoint so that the user can be #: logged in over the current channel. The credentials need to be C{Base64} #: encoded and stored in the body of the message. LOGIN_OPERATION = 8 #: This is used to log the user out of the current channel, and will #: invalidate the server session if the channel is HTTP based. LOGOUT_OPERATION = 9 #: This is used to poll a remote destination for pending, undelivered #: messages. POLL_OPERATION = 2 #: Subscribe commands issued by a consumer pass the consumer's C{selector} #: expression in this header. SELECTOR_HEADER = "DSSelector" #: This is used to indicate that the client's session with a remote #: destination has timed out. SESSION_INVALIDATE_OPERATION = 10 #: This is used to subscribe to a remote destination. SUBSCRIBE_OPERATION = 0 #: This is the default operation for new L{CommandMessage} instances. UNKNOWN_OPERATION = 1000 #: This is used to unsubscribe from a remote destination. UNSUBSCRIBE_OPERATION = 1 #: This operation is used to indicate that a channel has disconnected. DISCONNECT_OPERATION = 12 def __init__(self, *args, **kwargs): AsyncMessage.__init__(self, *args, **kwargs) self.operation = kwargs.get('operation', None) #: Remote destination belonging to a specific service, based upon #: whether this message type matches the message type the service #: handles. self.messageRefType = kwargs.get('messageRefType', None) pyamf.register_class(CommandMessage, '.'.join([NAMESPACE, 'CommandMessage']), attrs=['operation', 'messageRefType'], metadata=['amf3', 'static']) class ErrorMessage(AcknowledgeMessage): """ I am the Flex error message to be returned to the client. This class is used to report errors within the messaging system. @see: U{ErrorMessage on Livedocs (external) } """ #: If a message may not have been delivered, the faultCode will contain #: this constant. MESSAGE_DELIVERY_IN_DOUBT = "Client.Error.DeliveryInDoubt" #: Header name for the retryable hint header. #: #: This is used to indicate that the operation that generated the error may #: be retryable rather than fatal. RETRYABLE_HINT_HEADER = "DSRetryableErrorHint" def __init__(self, *args, **kwargs): AcknowledgeMessage.__init__(self, *args, **kwargs) #: Extended data that the remote destination has chosen to associate #: with this error to facilitate custom error processing on the client. self.extendedData = kwargs.get('extendedData', {}) #: Fault code for the error. self.faultCode = kwargs.get('faultCode', None) #: Detailed description of what caused the error. self.faultDetail = kwargs.get('faultDetail', None) #: A simple description of the error. self.faultString = kwargs.get('faultString', None) #: Should a traceback exist for the error, this property contains the #: message. self.rootCause = kwargs.get('rootCause', {}) pyamf.register_class(ErrorMessage, '.'.join([NAMESPACE, 'ErrorMessage']), attrs=['extendedData', 'faultCode', 'faultDetail', 'faultString', 'rootCause'], metadata=['amf3', 'static']) class RemotingMessage(AbstractMessage): """ I am used to send RPC requests to a remote endpoint. @see: U{RemotingMessage on Livedocs (external) } """ def __init__(self, *args, **kwargs): AbstractMessage.__init__(self, *args, **kwargs) #: Name of the remote method/operation that should be called. self.operation = kwargs.get('operation', None) #: Name of the service to be called including package name. #: This property is provided for backwards compatibility. self.source = kwargs.get('source', None) pyamf.register_class(RemotingMessage, '.'.join([NAMESPACE, 'RemotingMessage']), attrs=['operation', 'source'], metadata=['amf3', 'static']) PK:I\vOpyamf/flex/__init__.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Compatibility classes/functions for Flex. @note: Not available in ActionScript 1.0 and 2.0. @see: U{Flex on Wikipedia (external) } @since: 0.1.0 """ import pyamf __all__ = ['ArrayCollection', 'ObjectProxy'] class ArrayCollection(list): """ I represent the ActionScript 3 based class C{flex.messaging.io.ArrayCollection} used in the Flex framework. The C{ArrayCollection} class is a wrapper class that exposes an Array as a collection that can be accessed and manipulated using the methods and properties of the C{ICollectionView} or C{IList} interfaces in the Flex framework. @see: U{ArrayCollection on Livedocs (external) } @note: This class does not implement the RemoteObject part of the documentation. @ivar length: [read-only] The number of items in this collection. Introduced in 0.4. @type length: C{int} """ def __init__(self, source=None): if source is not None: if isinstance(source, dict): raise TypeError('Cannot convert dicts to ArrayCollection') if hasattr(source, '__iter__'): self.extend(source) def __repr__(self): return "" % list.__repr__(self) def __readamf__(self, input): data = input.readObject() if hasattr(data, 'source'): data = data.source else: if not hasattr(data, '__iter__'): raise pyamf.DecodeError('Unable to read a list when decoding ' 'ArrayCollection') self.extend(data) def __writeamf__(self, output): output.encoder.writeList(list(self), use_references=True, _use_proxies=False) def _get_length(self): return len(self) def _set_length(self, length): raise RuntimeError("Property length is read-only") length = property(_get_length, _set_length) def addItem(self, item): """ Adds the specified item to the end of the list. @param item: The object to add to the collection. @type item: C{mixed}. @since: 0.4 """ self.append(item) def addItemAt(self, item, index): """ Adds the item at the specified index. @param item: The object to add to the collection. @type item: C{mixed}. @param index: The index at which to place the item. @raise IndexError: If index is less than 0 or greater than the length of the list. @since: 0.4 """ if index < 0: raise IndexError if index > len(self): raise IndexError self.insert(index, item) def getItemAt(self, index, prefetch=0): """ Gets the item at the specified index. @param index: The index in the list from which to retrieve the item. @type index: C{int} @param prefetch: This param is ignored and is only here as part of the interface. @raise IndexError: if C{index < 0} or C{index >= length} @return: The item at index C{index}. @rtype: C{mixed}. @since: 0.4 """ if index < 0: raise IndexError if index > len(self): raise IndexError return self.__getitem__(index) def getItemIndex(self, item): """ Returns the index of the item if it is in the list such that C{getItemAt(index) == item}. @param item: The item to find. @type item: C{mixed}. @return: The index of the item or -1 if the item is not in the list. @rtype: C{int} @since: 0.4 """ try: return self.index(item) except ValueError: return -1 def removeAll(self): """ Removes all items from the list. @since: 0.4 """ while len(self) > 0: self.pop() def removeItemAt(self, index): """ Removes the item at the specified index and returns it. Any items that were after this index are now one index earlier. @param index: The index from which to remove the item. @return: The item that was removed. @rtype: C{mixed}. @raise IndexError: If index is less than 0 or greater than length. @since: 0.4 """ if index < 0: raise IndexError if index > len(self): raise IndexError x = self[index] del self[index] return x def setItemAt(self, item, index): """ Places the item at the specified index. If an item was already at that index the new item will replace it and it will be returned. @param item: The new item to be placed at the specified index. @type item: C{mixed}. @param index: The index at which to place the item. @type index: C{int} @return: The item that was replaced, or C{None}. @rtype: C{mixed} or C{None}. @raise IndexError: If index is less than 0 or greater than length. @since: 0.4 """ if index < 0: raise IndexError if index > len(self): raise IndexError tmp = self.__getitem__(index) self.__setitem__(index, item) return tmp def toArray(self): """ Returns an Array that is populated in the same order as the C{IList} implementation. @return: The array. @rtype: C{list} """ return self pyamf.register_class(ArrayCollection, 'flex.messaging.io.ArrayCollection', metadata=['external', 'amf3']) class ObjectProxy(object): """ I represent the ActionScript 3 based class C{flex.messaging.io.ObjectProxy} used in the Flex framework. Flex's C{ObjectProxy} class allows an anonymous, dynamic ActionScript Object to be bindable and report change events. @see: U{ObjectProxy on Livedocs (external) } """ def __init__(self, object=None): if object is None: self._amf_object = pyamf.ASObject() else: self._amf_object = object def __repr__(self): return "" % self._amf_object def __getattr__(self, name): if name == '_amf_object': return self.__dict__['_amf_object'] return getattr(self.__dict__['_amf_object'], name) def __setattr__(self, name, value): if name == '_amf_object': self.__dict__['_amf_object'] = value else: setattr(self._amf_object, name, value) def __readamf__(self, input): self._amf_object = input.readObject() def __writeamf__(self, output): output.writeObject(self._amf_object) pyamf.register_class(ObjectProxy, 'flex.messaging.io.ObjectProxy', metadata=['external', 'amf3']) PKũ:INpyamf/flex/data.pyc; La^Ic@sdZdkZdklZlZlZddddgZdefdYZdefdYZdefd YZ defd YZ d Z x@eee e fD],Z ei e d e e ifd dgqW[ dS(s Flex Data Management Service implementation. This module contains the message classes used with Flex Data Management Service. @since: 0.1.0 N(s AsyncMessagesAcknowledgeMessages ErrorMessages DataMessagesSequencedMessages PagedMessagesDataErrorMessagecBstZdZdZRS(s I am used to transport an operation that occured on a managed object or collection. This class of message is transmitted between clients subscribed to a remote destination as well as between server nodes within a cluster. The payload of this message describes all of the relevant details of the operation. This information is used to replicate updates and detect conflicts. @see: U{DataMessage on Livedocs (external) } cCs#ti|t|_t|_dS(N(s AsyncMessages__init__sselfsNonesidentitys operation(sself((s/build/bdist.linux-x86_64/egg/pyamf/flex/data.pys__init__&s  (s__name__s __module__s__doc__s__init__(((s/build/bdist.linux-x86_64/egg/pyamf/flex/data.pys DataMessages cBstZdZdZRS(s Response to L{DataMessage} requests. @see: U{SequencedMessage on Livedocs (external) } cCs5ti|t|_t|_t|_t|_dS(N(sAcknowledgeMessages__init__sselfsNones sequenceIdssequenceProxiess sequenceSizes dataMessage(sself((s/build/bdist.linux-x86_64/egg/pyamf/flex/data.pys__init__:s     (s__name__s __module__s__doc__s__init__(((s/build/bdist.linux-x86_64/egg/pyamf/flex/data.pysSequencedMessage2s cBstZdZdZRS(s This messsage provides information about a partial sequence result. @see: U{PagedMessage on Livedocs (external) } cCs#ti|t|_t|_dS(N(sSequencedMessages__init__sselfsNones pageCounts pageIndex(sself((s/build/bdist.linux-x86_64/egg/pyamf/flex/data.pys__init__Ts  (s__name__s __module__s__doc__s__init__(((s/build/bdist.linux-x86_64/egg/pyamf/flex/data.pys PagedMessageLs cBstZdZdZRS(sn Special cases of ErrorMessage will be sent when a data conflict occurs. This message provides the conflict information in addition to the L{ErrorMessage} information. @see: U{DataErrorMessage on Livedocs (external) } cCs,ti|t|_t|_t|_dS(N(s ErrorMessages__init__sselfsNonescauses propertyNamess serverObject(sself((s/build/bdist.linux-x86_64/egg/pyamf/flex/data.pys__init__is   (s__name__s __module__s__doc__s__init__(((s/build/bdist.linux-x86_64/egg/pyamf/flex/data.pysDataErrorMessage]s sflex.data.messagess%s.%ssmetadatasamf3(s__doc__spyamfspyamf.flex.messagings AsyncMessagesAcknowledgeMessages ErrorMessages__all__s DataMessagesSequencedMessages PagedMessagesDataErrorMessages MESSAGES_NSsxsregister_classs__name__( s__all__s MESSAGES_NSspyamfs ErrorMessagesDataErrorMessagesAcknowledgeMessagesSequencedMessages PagedMessagesxs AsyncMessages DataMessage((s/build/bdist.linux-x86_64/egg/pyamf/flex/data.pys? s *PKũ:NQ##pyamf/flex/messaging.pyc; La^Ic @sdZdkZddddgZdZdefdYZeied iedgd d d d ddddgdddgdefdYZeied iedgd dgdddgdefdYZ eie d iedgd gdddgdefdYZ eie d iedgd ddgdddgde fdYZ eie d iedgd dddd d!gdddgdefd"YZ eie d iedgd dd#gdddgdS($s Flex Messaging implementation. This module contains the message classes used with Flex Data Services. @see: U{RemoteObject on OSFlash (external) } @since: 0.1.0 NsRemotingMessagesCommandMessagesAcknowledgeMessages ErrorMessagesflex.messaging.messagessAbstractMessagecBs8tZdZdZdZdZdZdZdZRS(sy Abstract base class for all Flex messages. Messages have two customizable sections; headers and data. The headers property provides access to specialized meta information for a specific message instance. The data property contains the instance specific data that needs to be delivered and processed by the decoder. @see: U{AbstractMessage on Livedocs (external) } @ivar body: Specific data that needs to be delivered to the remote destination. @type body: C{mixed} @ivar clientId: Indicates which client sent the message. @type clientId: C{str} @ivar destination: Message destination. @type destination: C{str} @ivar headers: Message headers. Core header names start with DS. @type headers: C{dict} @ivar messageId: Unique Message ID. @type messageId: C{str} @ivar timeToLive: How long the message should be considered valid and deliverable. @type timeToLive: C{int} @ivar timestamp: Timestamp when the message was generated. @type timestamp: C{int} s DSDstClientIds DSEndpointsDSRemoteCredentialssDSRequestTimeoutcOs|idt|_|idt|_|idt|_|idh|_|idt|_|idd|_ |idd|_ dS( NsbodysclientIds destinationsheaderss messageIds timeToLiveis timestamp( skwargssgetsNonesselfsbodysclientIds destinationsheaderss messageIds timeToLives timestamp(sselfsargsskwargs((s4build/bdist.linux-x86_64/egg/pyamf/flex/messaging.pys__init__GscCsPd|ii}x1|iiD] \}}|d||f7}q W|dSdS(Ns<%s s %s=%rs />(sselfs __class__s__name__sms__dict__s iteritemssksv(sselfsmsksv((s4build/bdist.linux-x86_64/egg/pyamf/flex/messaging.pys__repr__Ps  ( s__name__s __module__s__doc__sDESTINATION_CLIENT_ID_HEADERsENDPOINT_HEADERsREMOTE_CREDENTIALS_HEADERsREQUEST_TIMEOUT_HEADERs__init__s__repr__(((s4build/bdist.linux-x86_64/egg/pyamf/flex/messaging.pysAbstractMessages  s.sattrssbodysclientIds destinationsheaderss messageIds timeToLives timestampsmetadatasamf3sstatics AsyncMessagecBstZdZdZdZRS(s% I am the base class for all asynchronous Flex messages. @see: U{AsyncMessage on Livedocs (external) } @ivar correlationId: Correlation id of the message. @type correlationId: C{str} s DSSubtopiccOs,ti||||idt|_dS(Ns correlationId(sAbstractMessages__init__sselfsargsskwargssgetsNones correlationId(sselfsargsskwargs((s4build/bdist.linux-x86_64/egg/pyamf/flex/messaging.pys__init__os(s__name__s __module__s__doc__sSUBTOPIC_HEADERs__init__(((s4build/bdist.linux-x86_64/egg/pyamf/flex/messaging.pys AsyncMessage`s s correlationIdcBstZdZdZRS(s: I acknowledge the receipt of a message that was sent previously. Every message sent within the messaging system must receive an acknowledgement. @see: U{AcknowledgeMessage on Livedocs (external) } s DSErrorHint(s__name__s __module__s__doc__sERROR_HINT_HEADER(((s4build/bdist.linux-x86_64/egg/pyamf/flex/messaging.pysAcknowledgeMessagews cBsetZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZRS(s Provides a mechanism for sending commands related to publish/subscribe messaging, ping, and cluster operations. @see: U{CommandMessage on Livedocs (external) } @ivar operation: The command @type operation: C{int} @ivar messageRefType: hmm, not sure about this one. @type messageRefType: C{str} s-flex.messaging.messages.AuthenticationMessageiiiii is DSSelectori iiii cOsAti||||idt|_|idt|_dS(Ns operationsmessageRefType( s AsyncMessages__init__sselfsargsskwargssgetsNones operationsmessageRefType(sselfsargsskwargs((s4build/bdist.linux-x86_64/egg/pyamf/flex/messaging.pys__init__s(s__name__s __module__s__doc__sAUTHENTICATION_MESSAGE_REF_TYPEsPING_OPERATIONsSYNC_OPERATIONsCLUSTER_REQUEST_OPERATIONsLOGIN_OPERATIONsLOGOUT_OPERATIONsPOLL_OPERATIONsSELECTOR_HEADERsSESSION_INVALIDATE_OPERATIONsSUBSCRIBE_OPERATIONsUNKNOWN_OPERATIONsUNSUBSCRIBE_OPERATIONsDISCONNECT_OPERATIONs__init__(((s4build/bdist.linux-x86_64/egg/pyamf/flex/messaging.pysCommandMessages s operationsmessageRefTypecBs#tZdZdZdZdZRS(s I am the Flex error message to be returned to the client. This class is used to report errors within the messaging system. @see: U{ErrorMessage on Livedocs (external) } sClient.Error.DeliveryInDoubtsDSRetryableErrorHintcOsti||||idh|_|idt|_|idt|_ |idt|_ |idh|_ dS(Ns extendedDatas faultCodes faultDetails faultStrings rootCause( sAcknowledgeMessages__init__sselfsargsskwargssgets extendedDatasNones faultCodes faultDetails faultStrings rootCause(sselfsargsskwargs((s4build/bdist.linux-x86_64/egg/pyamf/flex/messaging.pys__init__s (s__name__s __module__s__doc__sMESSAGE_DELIVERY_IN_DOUBTsRETRYABLE_HINT_HEADERs__init__(((s4build/bdist.linux-x86_64/egg/pyamf/flex/messaging.pys ErrorMessages s extendedDatas faultCodes faultDetails faultStrings rootCausecBstZdZdZRS(s I am used to send RPC requests to a remote endpoint. @see: U{RemotingMessage on Livedocs (external) } cOsAti||||idt|_|idt|_dS(Ns operationssource( sAbstractMessages__init__sselfsargsskwargssgetsNones operationssource(sselfsargsskwargs((s4build/bdist.linux-x86_64/egg/pyamf/flex/messaging.pys__init__s(s__name__s __module__s__doc__s__init__(((s4build/bdist.linux-x86_64/egg/pyamf/flex/messaging.pysRemotingMessages ssource( s__doc__spyamfs__all__s NAMESPACEsobjectsAbstractMessagesregister_classsjoins AsyncMessagesAcknowledgeMessagesCommandMessages ErrorMessagesRemotingMessage( s ErrorMessages__all__spyamfs NAMESPACEsCommandMessagesAcknowledgeMessagesRemotingMessagesAbstractMessages AsyncMessage((s4build/bdist.linux-x86_64/egg/pyamf/flex/messaging.pys? s. @;"PKũ:uɎQ)Q)pyamf/flex/__init__.pyc; JIc@sdZdkZddgZdefdYZeieddddgdefd YZeied dddgdS( s Compatibility classes/functions for Flex. @note: Not available in ActionScript 1.0 and 2.0. @see: U{Flex on Wikipedia (external) } @since: 0.1.0 NsArrayCollections ObjectProxycBstZdZedZdZdZdZdZdZ e ee Z dZ dZ d d Zd Zd Zd ZdZdZRS(s I represent the ActionScript 3 based class C{flex.messaging.io.ArrayCollection} used in the Flex framework. The C{ArrayCollection} class is a wrapper class that exposes an Array as a collection that can be accessed and manipulated using the methods and properties of the C{ICollectionView} or C{IList} interfaces in the Flex framework. @see: U{ArrayCollection on Livedocs (external) } @note: This class does not implement the RemoteObject part of the documentation. @ivar length: [read-only] The number of items in this collection. Introduced in 0.4. @type length: C{int} cCsV|tj oEt|totdnt|do|i|qRndS(Ns'Cannot convert dicts to ArrayCollections__iter__(ssourcesNones isinstancesdicts TypeErrorshasattrsselfsextend(sselfssource((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pys__init__'s  cCsdti|SdS(Ns&(slists__repr__sself(sself((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pys__repr__/scCs^|i}t|do |i}n%t|d otidn|i|dS(Nssources__iter__s3Unable to read a list when decoding ArrayCollection( sinputs readObjectsdatashasattrssourcespyamfs DecodeErrorsselfsextend(sselfsinputsdata((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pys __readamf__2s   cCs&|iit|dtdtdS(Nsuse_referencess _use_proxies(soutputsencoders writeListslistsselfsTruesFalse(sselfsoutput((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pys __writeamf__>scCst|SdS(N(slensself(sself((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pys _get_lengthAscCstddS(NsProperty length is read-only(s RuntimeError(sselfslength((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pys _set_lengthDscCs|i|dS(s Adds the specified item to the end of the list. @param item: The object to add to the collection. @type item: C{mixed}. @since: 0.4 N(sselfsappendsitem(sselfsitem((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pysaddItemIscCsH|djo tn|t|jo tn|i||dS(sG Adds the item at the specified index. @param item: The object to add to the collection. @type item: C{mixed}. @param index: The index at which to place the item. @raise IndexError: If index is less than 0 or greater than the length of the list. @since: 0.4 iN(sindexs IndexErrorslensselfsinsertsitem(sselfsitemsindex((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pys addItemAtSs    icCsE|djo tn|t|jo tn|i|SdS(s Gets the item at the specified index. @param index: The index in the list from which to retrieve the item. @type index: C{int} @param prefetch: This param is ignored and is only here as part of the interface. @raise IndexError: if C{index < 0} or C{index >= length} @return: The item at index C{index}. @rtype: C{mixed}. @since: 0.4 iN(sindexs IndexErrorslensselfs __getitem__(sselfsindexsprefetch((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pys getItemAtfs    cCs/y|i|SWntj o dSnXdS(s1 Returns the index of the item if it is in the list such that C{getItemAt(index) == item}. @param item: The item to find. @type item: C{mixed}. @return: The index of the item or -1 if the item is not in the list. @rtype: C{int} @since: 0.4 iN(sselfsindexsitems ValueError(sselfsitem((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pys getItemIndex{s cCs)x"t|djo|iqWdS(sG Removes all items from the list. @since: 0.4 iN(slensselfspop(sself((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pys removeAllscCsM|djo tn|t|jo tn||}||=|SdS(sv Removes the item at the specified index and returns it. Any items that were after this index are now one index earlier. @param index: The index from which to remove the item. @return: The item that was removed. @rtype: C{mixed}. @raise IndexError: If index is less than 0 or greater than length. @since: 0.4 iN(sindexs IndexErrorslensselfsx(sselfsindexsx((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pys removeItemAts     cCs[|djo tn|t|jo tn|i|}|i|||SdS(s Places the item at the specified index. If an item was already at that index the new item will replace it and it will be returned. @param item: The new item to be placed at the specified index. @type item: C{mixed}. @param index: The index at which to place the item. @type index: C{int} @return: The item that was replaced, or C{None}. @rtype: C{mixed} or C{None}. @raise IndexError: If index is less than 0 or greater than length. @since: 0.4 iN(sindexs IndexErrorslensselfs __getitem__stmps __setitem__sitem(sselfsitemsindexstmp((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pys setItemAts    cCs|SdS(s Returns an Array that is populated in the same order as the C{IList} implementation. @return: The array. @rtype: C{list} N(sself(sself((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pystoArrays(s__name__s __module__s__doc__sNones__init__s__repr__s __readamf__s __writeamf__s _get_lengths _set_lengthspropertyslengthsaddItems addItemAts getItemAts getItemIndexs removeAlls removeItemAts setItemAtstoArray(((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pysArrayCollections           s!flex.messaging.io.ArrayCollectionsmetadatasexternalsamf3cBsGtZdZedZdZdZdZdZdZ RS(sk I represent the ActionScript 3 based class C{flex.messaging.io.ObjectProxy} used in the Flex framework. Flex's C{ObjectProxy} class allows an anonymous, dynamic ActionScript Object to be bindable and report change events. @see: U{ObjectProxy on Livedocs (external) } cCs-|tjoti|_n ||_dS(N(sobjectsNonespyamfsASObjectsselfs _amf_object(sselfsobject((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pys__init__s cCsd|iSdS(Ns"(sselfs _amf_object(sself((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pys__repr__scCs4|djo|idSnt|id|SdS(Ns _amf_object(snamesselfs__dict__sgetattr(sselfsname((s3build/bdist.linux-x86_64/egg/pyamf/flex/__init__.pys __getattr__s cCs5|djo||idtZdZdZdZdZdZdZRS(NcCstidd}|i|id|i|id|i|ittiddt}|i|id|i|id|i|ittit t t }|i|it |i|it |i|it dS(Nsspamseggsshellosworld( sclients ServiceProxysxsselfs assertEqualss_gws_names _auto_executesTruesordschrsFalse(sselfsx((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys test_create3scCsKtitt}|i}|it|ti |i |i ddS(Nsspam( sclients ServiceProxysNonesxsspamsysselfs assertTrues isinstancesServiceMethodProxys assertEqualssname(sselfsysx((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys test_getattrFs cCs|dtfdY}||}ti|d}|i}||_ f|_ |dddf|_ |ddddS(Ns DummyGatewaycBs#tZdZdZdZRS(NcCs ||_dS(N(stcsself(sselfstc((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys__init__OscGsR|ii||i|ii||ihd|<d|<|_|iSdS(Ns method_proxysargs(sselfstcs assertEqualss method_proxysargssrequest(sselfs method_proxysargs((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys addRequestRscCs*|ii||itidtSdS(Nsbody(sselfstcs assertEqualssrequestspyamfsASObjectsNone(sselfsrequest((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pysexecute_singleYs(s__name__s __module__s__init__s addRequestsexecute_single(((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys DummyGatewayNs  stestiii( sobjects DummyGatewaysselfsgwsclients ServiceProxysxsspamsys method_proxysargs(sselfsgwsysxs DummyGateway((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys test_callMs    cCsHdtfdY}||}ti|d}||_|dS(Ns DummyGatewaycBs#tZdZdZdZRS(NcCs ||_dS(N(stcsself(sselfstc((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys__init__lscGsI|ii|i|i|ii|itti d|d|SdS(Ns method_proxysargs( sselfstcs assertEqualss method_proxysservicesxsnamesNonespyamfsASObjectsargs(sselfs method_proxysargs((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys addRequestoscCstidtSdS(Nsbody(spyamfsASObjectsNone(sselfsrequest((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pysexecute_singleus(s__name__s __module__s__init__s addRequestsexecute_single(((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys DummyGatewayks  stest(sobjects DummyGatewaysselfsgwsclients ServiceProxysx(sselfsgwsxs DummyGateway((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_service_calljs   cCs~dtfdY}||}ti|dt}|i}||_ f|_ |}|i t|it|dS(Ns DummyGatewaycBstZdZdZRS(NcCs ||_dS(N(stcsself(sselfstc((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys__init__scGsR|ii||i|ii||itid|d||_|iSdS(Ns method_proxysargs(sselfstcs assertEqualss method_proxysargsspyamfsASObjectsrequest(sselfs method_proxysargs((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys addRequests(s__name__s __module__s__init__s addRequest(((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys DummyGateways stest(sobjects DummyGatewaysselfsgwsclients ServiceProxysFalsesxseggssys method_proxysargssress assertEqualssidsrequest(sselfsgwsressysxs DummyGateway((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_pending_call~s     cCs,titd}|it|ddS(Nstest(sclients ServiceProxysNonesxsselfs assertEqualssstr(sselfsx((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_strs(s__name__s __module__s test_creates test_getattrs test_callstest_service_callstest_pending_callstest_str(((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pysServiceProxyTestCase2s      sRequestWrapperTestCasecBs,tZdZdZdZdZRS(NcCsktidddd}|i|id|i|id|i|id|i|idfdS(Niiii( sclientsRequestWrappersxsselfs assertEqualssgwsidsservicesargs(sselfsx((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys test_creates cCs2titdtt}|it|ddS(Ns/1(sclientsRequestWrappersNonesxsselfs assertEqualssstr(sselfsx((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_strscCs2titttt}|itt|ddS(Nsresult(sclientsRequestWrappersNonesxsselfs assertRaisessAttributeErrorsgetattr(sselfsx((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_null_responsescCsatitttt}tidd}|i||i |i ||i |i ddS(Nsbodys spam.eggs( sclientsRequestWrappersNonesxspyamfsASObjectsys setResponsesselfs assertEqualssresponsesresult(sselfsysx((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_set_responses  (s__name__s __module__s test_createstest_strstest_null_responsestest_set_response(((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pysRequestWrapperTestCases   s DummyResponsecBs>tZeZeZfdZdZedZdZ RS(NcCs||_||_||_dS(N(sstatussselfsbodysheaders(sselfsstatussbodysheaders((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys__init__s  cCs'||ijo|i|SntSdS(N(sheadersselfsheaderssNone(sselfsheader((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys getheaderscCs'|tjo |iSn|i| SdS(N(sxsNonesselfsbody(sselfsx((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pysreads  cCs t|_dS(N(sTruesselfsclosed(sself((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pyscloses( s__name__s __module__sNonestcsFalsescloseds__init__s getheadersreadsclose(((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys DummyResponses    sDummyConnectioncBs;tZeZeZeZeZeZedZdZ RS(NcCsY|ii|d|ii||i|ii||i|ii||i dS(NsPOST( sselfstcs assertEqualssmethodsurls expected_urlsvaluesexpected_valuesheaderssexpected_headers(sselfsmethodsurlsvaluesheaders((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pysrequestscCs |iSdS(N(sselfsresponse(sself((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys getresponses( s__name__s __module__sNonestcsexpected_values expected_urlsexpected_headerssresponsesrequests getresponse(((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pysDummyConnections sRemotingServiceTestCasecBstZdZdZdZdZdZdZdZdZ d Z d Z d Z d Z d ZdZdZdZdZdZdZdZRS(NcCs|ittitid}|i|iddddddf|i|ii d|i|ii dtidt i }|i|i t i tidt i t ii}|i|it iidS(Nshttp://example.orgshttps example.orgsiP(sselfs assertRaisess TypeErrorsclientsRemotingServicesxs assertEqualssurls connectionshostsportspyamfsAMF3s amf_versions ClientTypessFlashComs client_type(sselfsx((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys test_creates%cCsdtid}|i|iidtid}|i|iid|ittiddS(Nshttp://example.orgiPshttps://example.orgisftp://example.org( sclientsRemotingServicesxsselfs assertEqualss connectionsports assertRaisess ValueError(sselfsx((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys test_schemess cCs?tid}|i|iid|i|iiddS(Nshttp://example.org:8080s example.orgi(sclientsRemotingServicesxsselfs assertEqualss connectionshostsport(sselfsx((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys test_portscCswtid}|id}|it|ti|i |i d|i |i ||i t |iddS(Nshttp://example.orgsspami(sclientsRemotingServicesxs getServicesysselfs assertTrues isinstances ServiceProxys assertEqualss_names_gws assertRaisess TypeError(sselfsysx((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_get_services cCstid}|i|id|i|ig|id}|i |ddd}|i|i|g|i|i||i|id|i|i d|i|i||i|i dddf|i |t }|i|i||g|i|i||i|id|i|i d|i|i||i|i t f|i |}|i|i|||g|i|i||i|id|i|i d |i|i||i|i tdS( Nshttp://spameggs.netisbaziis/1s/2is/3(sclientsRemotingServicesgwsselfs assertEqualssrequest_numbersrequestss getServicesservices addRequestswrappersidsargssNoneswrapper2swrapper3stuple(sselfsgwswrapper2sserviceswrapperswrapper3((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_add_requests2cCstid}|i|ig|id}|i|ddd}|i|i|g|i ||i|ig|i|ddd}|i|i|g|i |ddd|i|ig|i t |i |ddddS(Nshttp://spameggs.netsbaziii( sclientsRemotingServicesgwsselfs assertEqualssrequestss getServicesservices addRequestswrappers removeRequests assertRaisess LookupError(sselfsgwsserviceswrapper((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_remove_request1s cCstid}|id}|i|ddd}|it|}|i |||id}|i |||i|i }|i ||dS(Nshttp://spameggs.netsbaziiis/1( sclientsRemotingServicesgws getServicesservices addRequestswrappers getRequestsstrswrapper2sselfs assertEqualssid(sselfsgwswrapper2sserviceswrapper((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_get_requestDscCsxtidtitii}|id}|i }|i |ddd}|i |g}|i|iti|i|itii|i|idg|d}|i|id|i|idddg|i |i}|i|iti|i|itii|i|idg|d}|i|id|i|idddgdS(Nshttp://example.orgsbaziiis/1sbaz.gak(sclientsRemotingServicespyamfsAMF3s ClientTypessFlashComsgws getServicesservicesgaks method_proxys addRequestswrappers getAMFRequestsenvelopesselfs assertEqualss amfVersions clientTypeskeyssrequeststargetsbodysrequestss envelope2(sselfsgwsservicesrequestsenvelopes method_proxyswrappers envelope2((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_get_amf_requestSs&   cCs8tid}t}||_||_hdti <dti <|_ |i ddt }|i}tddhdd<d d <}||_d |_d d |_||_|i||i|ig|i}tddhdd<}||_d |_d d|_||_|i|dS(Nshttp://example.org/x/y/zs Content-Types User-Agentsbazs auto_executeis& /1/onResultnullhellosapplication/x-amfsContent-Lengthi2s/x/y/zsbaz.gaks /1 s& /2/onResultnullhellos /2 (sclientsRemotingServicesgwsDummyConnectionsdcs connectionsselfstcsremotings CONTENT_TYPEsDEFAULT_USER_AGENTsexpected_headerss getServicesFalsesservicesgakswrappers DummyResponsesresponses expected_urlsexpected_valuesexecute_singles assertEqualssrequests(sselfsgwsservicesdcswrappersresponse((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_execute_singleos.   !             cCstid}t}||_||_hdd<dti<|_ |i ddt }|i ddt }|i}|i}tdd hdd<}||_d |_d d d |_||_|i|i|igdS(Nshttp://example.org/x/y/zs Content-Typesapplication/x-amfs User-Agentsbazs auto_executesspamisF /1/onResultnullhello /2/onResultnullhellos/x/y/zsbaz.gaks/1 spam.eggs/2s (sclientsRemotingServicesgwsDummyConnectionsdcs connectionsselfstcsDEFAULT_USER_AGENTsexpected_headerss getServicesFalsesbazsspamsgakswrapperseggsswrapper2s DummyResponsesresponses expected_urlsexpected_valuesexecutes assertEqualssrequests(sselfsgwswrapper2sspamsbazsdcswrappersresponse((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys test_executes"          cCstid}t}||_tddhdd<}||_|itddh}||_|i t i |itddhdd<}||_|i t i |idS( Nshttp://example.org/amf-gatewayiss Content-Typesapplication/x-amfiss text/html( sclientsRemotingServicesgwsDummyConnectionsdcs connections DummyResponsesresponses _getResponsesselfs assertRaisessremotings RemotingError(sselfsgwsdcsresponse((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_get_responses       cCstid}|id|ij|idd|id|ij|i|idhdd<dd<|i g}|id|ij|id}|i|id|iddS( Nshttp://example.org/amf-gateways Credentialssspamseggssuseriduspamspasswordueggs( sclientsRemotingServicesgwsselfs assertFalsesheadersssetCredentialss assertTrues assertEqualss getAMFRequestsenvelopescred(sselfsgwscredsenvelope((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_credentialss cCshtid}t}||_tddhdd<}||_|i}|i |i ddS(Nshttp://example.org/amf-gatewayis'AppendToGatewayUrlhellos Content-Typesapplication/x-amfs#http://example.org/amf-gatewayhello( sclientsRemotingServicesgwsDummyConnectionsdcs connections DummyResponsesresponses _getResponsesselfs assertEqualss original_url(sselfsgwsdcsresponse((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_append_url_headers     cCshtid}t}||_tddhdd<}||_|i}|i |i ddS(Nshttp://example.org/amf-gatewayis1ReplaceGatewayUrlhttp://spam.eggss Content-Typesapplication/x-amfshttp://spam.eggs( sclientsRemotingServicesgwsDummyConnectionsdcs connections DummyResponsesresponses _getResponsesselfs assertEqualss original_url(sselfsgwsdcsresponse((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_replace_url_headers     cCsctid}t}||_tddhdd<|_|i|i |ii t dS(Nshttp://example.org/amf-gatewayis1ReplaceGatewayUrlhttp://spam.eggss Content-Typesapplication/x-amf( sclientsRemotingServicesgwsDummyConnectionsdcs connections DummyResponsesresponses _getResponsesselfs assertTruesclosedsTrue(sselfsgwsdc((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_close_http_responses    cCsRtid}|i|ih|idd|i|ihdd<dS(Nshttp://example.org/amf-gatewaysETags29083457239804752309485(sclientsRemotingServicesgwsselfs assertEqualss http_headerss addHTTPHeader(sselfsgw((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_add_http_headerscCs[tid}hdd<|_|id|i|ih|it|iddS(Nshttp://example.org/amf-gateways Set-Cookiesfoo-bar( sclientsRemotingServicesgws http_headerssremoveHTTPHeadersselfs assertEqualss assertRaisessKeyError(sselfsgw((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_remove_http_headers  cCstid}t}||_||_d|_d|_ |i ddhdd<dd<d|i <|_ t d d hdd<|_|i|i|iitdS( Nshttp://example.org/amf-gateways /amf-gatewayssETags29083457239804752309485s Content-Typesapplication/x-amfs User-Agentis1ReplaceGatewayUrlhttp://spam.eggs(sclientsRemotingServicesgwsDummyConnectionsdcs connectionsselfstcs expected_urlsexpected_values addHTTPHeaders user_agentsexpected_headerss DummyResponsesresponsesexecutes assertTruesclosedsTrue(sselfsgwsdc((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_http_request_headerss     '  cCsltid}t}||_tddhdd<dd<}||_|i |i |i dS(Nshttp://example.org/amf-gatewayis1ReplaceGatewayUrlhttp://spam.eggss Content-Typesapplication/x-amfsContent-Lengths( sclientsRemotingServicesgwsDummyConnectionsdcs connections DummyResponses http_responsesresponses _getResponsesselfs assertTruesclosed(sselfsgwsdcs http_response((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_empty_content_length1s     cCsetid}t}||_tddhdd<dd<}||_|i t |i dS(Nshttp://example.org/amf-gatewayis1ReplaceGatewayUrlhttp://spam.eggss Content-Typesapplication/x-amfsContent-Lengthsasdfasdf( sclientsRemotingServicesgwsDummyConnectionsdcs connections DummyResponses http_responsesresponsesselfs assertRaisess ValueErrors _getResponse(sselfsgwsdcs http_response((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pystest_bad_content_lengthAs    (s__name__s __module__s test_creates test_schemess test_portstest_get_servicestest_add_requeststest_remove_requeststest_get_requeststest_get_amf_requeststest_execute_singles test_executestest_get_responsestest_credentialsstest_append_url_headerstest_replace_url_headerstest_close_http_responsestest_add_http_headerstest_remove_http_headerstest_http_request_headersstest_empty_content_lengthstest_bad_content_length(((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pysRemotingServiceTestCases(   #    '       cCslti}|itit|itit|itit|itit|SdS(N( sunittests TestSuitessuitesaddTests makeSuitesServiceMethodProxyTestCasesServiceProxyTestCasesRequestWrapperTestCasesRemotingServiceTestCase(ssuite((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pyssuiteQs  s__main__s defaultTestssuite(s__doc__sunittestspyamfsremotingspyamf.remotingsclientsTestCasesServiceMethodProxyTestCasesServiceProxyTestCasesRequestWrapperTestCasesobjects DummyResponsesDummyConnectionsRemotingServiceTestCasessuites__name__smain( sremotingsServiceMethodProxyTestCasesRequestWrapperTestCasesunittestsDummyConnectionsclients DummyResponsesServiceProxyTestCasessuitespyamfsRemotingServiceTestCase((s@build/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_client.pys? s     ir PKũ:4Y<!pyamf/tests/remoting/__init__.pyc; La^Ic@s dZdS(s Remoting tests. @since: 0.1.0 N(s__doc__(((s=build/bdist.linux-x86_64/egg/pyamf/tests/remoting/__init__.pys?sPKũ:\PҰ22*pyamf/tests/remoting/test_remoteobject.pyc; La^Ic@sdZdkZdkZdklZdklZlZdklZdei fdYZ dei fdYZ d ei fd YZ d Z ed joeid dndS(s" RemoteObject Tests. @since: 0.1 N(sremoting(samf3sgateway(s messagingsRandomIdGeneratorTestCasecBstZdZRS(NcCsMg}x@tdD]2}ti}|i||j|i|qWdS(Ni( sxsrangesisamf3sgenerate_random_idsid_sselfs assertTruesappend(sselfsid_sisx((sFbuild/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_remoteobject.pys test_generates   (s__name__s __module__s test_generate(((sFbuild/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_remoteobject.pysRandomIdGeneratorTestCasess AcknowlegdementGeneratorTestCasecBstZdZdZRS(NcCskti}|it|ti|i|it j |i|i t j |i|i t j dS(N( samf3sgenerate_acknowledgementsacksselfs assertTrues isinstances messagingsAcknowledgeMessages messageIdsNonesclientIds timestamp(sselfsack((sFbuild/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_remoteobject.pys test_generates  cCstitidd}|it|ti |i|i t j |i|i t j |i|i t j |i|iddS(Ns messageIds123123(samf3sgenerate_acknowledgementspyamfsASObjectsacksselfs assertTrues isinstances messagingsAcknowledgeMessages messageIdsNonesclientIds timestamps assertEqualss correlationId(sselfsack((sFbuild/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_remoteobject.pys test_request$s (s__name__s __module__s test_generates test_request(((sFbuild/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_remoteobject.pys AcknowlegdementGeneratorTestCases sRequestProcessorTestCasecBsbtZdZdZdZdZdZdZdZdZ d Z d Z RS( NcCs&tid}|i|iddS(Nsxyz(samf3sRequestProcessorsrpsselfs assertEqualssgateway(sselfsrp((sFbuild/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_remoteobject.pys test_create/scCstidd}tit}tidd|g}||}|i }|it|ti|i|iti|it|ti|i|i tdS(Ns operationisnullsbody(s messagingsCommandMessagesmessagesamf3sRequestProcessorsNonesrpsremotingsRequestsrequestsresponsesbodysacksselfs assertTrues isinstancesResponses assertEqualssstatuss STATUS_OKsAcknowledgeMessagesTrue(sselfsrpsacksrequestsmessagesresponse((sFbuild/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_remoteobject.pys test_ping3s  cCsd}tihd|<}ti|}tiddgdd}t i dd|g}||}|i}|it|t i|i|it i|it|ti|i|iddS(NcCs|SdS(N(sx(sx((sFbuild/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_remoteobject.pysechoAssechosbodys spam.eggss operationsnull(sechosgateways BaseGatewaysgwsamf3sRequestProcessorsrps messagingsRemotingMessagesmessagesremotingsRequestsrequestsresponsesbodysacksselfs assertTrues isinstancesResponses assertEqualssstatuss STATUS_OKsAcknowledgeMessage(sselfsgwsrpsacksrequestsechosresponsesmessage((sFbuild/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_remoteobject.pys test_request@s   cCsd}tihd|<}ti|}tiddgdd}t i dd|g}||}|i}|it|t i|i|it i|it|ti|i|iddS(NcCs tdS(N(s TypeError(sx((sFbuild/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_remoteobject.pysechoRssechosbodys spam.eggss operationsnulls TypeError(sechosgateways BaseGatewaysgwsamf3sRequestProcessorsrps messagingsRemotingMessagesmessagesremotingsRequestsrequestsresponsesbodysacksselfs assertTrues isinstancesResponses assertEqualssstatuss STATUS_ERRORs ErrorMessages faultCode(sselfsgwsrpsacksrequestsechosresponsesmessage((sFbuild/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_remoteobject.pys test_errorQs   cCsd}tihd|<}ti|}tidddgdd}t i dd|g}||}|i}|it|t i|i|it i|it|ti|i|iddS( NcCs|SdS(N(sbar(sbar((sFbuild/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_remoteobject.pysspamcssspamsbodyseggssbazs operationsnulls TypeError(sspamsgateways BaseGatewaysgwsamf3sRequestProcessorsrps messagingsRemotingMessagesmessagesremotingsRequestsrequestsresponsesbodysacksselfs assertTrues isinstancesResponses assertEqualssstatuss STATUS_ERRORs ErrorMessages faultCode(sselfsgwsrpsspamsacksrequestsresponsesmessage((sFbuild/bdist.linux-x86_64/egg/pyamf/tests/remoting/test_remoteobject.pystest_too_many_argsbs   c sd}t_d}tihd|s(s bad_responsesselfsgws assertTruesexecuteds assertRaisessKeyError(sselfs bad_response((sselfs=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pystest_request_methods  csti}|id|iddhdd<dtt|<d|<}d}i ||i i dS(Ns Bad requestisREQUEST_METHODsPOSTsCONTENT_LENGTHs wsgi.inputcsi|dt_dS(Ns400 Bad Request(sselfs assertEqualssstatussTruesexecuted(sstatussheaders(sself(s=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pysstart_response,s( sutilsBufferedByteStreamsrequestswritesseeksstrslensenvsstart_responsesselfsgws assertTruesexecuted(sselfsenvsstart_responsesrequest((sselfs=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pystest_bad_request!s  - csti}|id|iddhdd<dtt|<d|<}d}i ||}t i di|}|d }i|it i|i}it|t ii|id iidS( Ns- test.test/1 aa isREQUEST_METHODsPOSTsCONTENT_LENGTHs wsgi.inputcs6t_i|diddf|jdS(Ns200 OKs Content-Typesapplication/x-amf(sTruesselfsexecuteds assertEqualssstatuss assertTruesheaders(sstatussheaders(sself(s=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pysstart_response@s ss/1sService.ResourceNotFound(sutilsBufferedByteStreamsrequestswritesseeksstrslensenvsstart_responsesselfsgwsresponsesremotingsdecodesjoinsenvelopesmessages assertEqualssstatuss STATUS_ERRORsbodys assertTrues isinstances ErrorFaultscodesexecuted(sselfsbodysenvsstart_responsesenvelopesrequestsmessagesresponse((sselfs=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pystest_unknown_request3s  -   cs~ti}hdd<dtt|<d|<}d}i||}i |dgi i dS(NsREQUEST_METHODsPOSTsCONTENT_LENGTHs wsgi.inputcs6t_i|diddf|jdS(Ns400 Bad Requests Content-Types text/plain(sTruesselfsexecuteds assertEqualssstatuss assertTruesheaders(sstatussheaders(sself(s=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pysstart_responseZs sH400 Bad Request The request body was unable to be successfully decoded.( sutilsBufferedByteStreamsrequestsstrslensenvsstart_responsesselfsgwsresponses assertEqualss assertTruesexecuted(sselfsenvsstart_responsesrequestsresponse((sselfs=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pystest_eof_decodeQs  - cOs |dS(N(se(sselfsesargsskwargs((s=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pys_raiseExceptiondscsti_dt_ti}hdd<dtt|<d|<}d}yi ||}Wnit_nXit_i |dgiidS(Ncsit||S(N(sselfs_raiseExceptions Exceptionsargsskwargs(sargsskwargs(sself(s=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pysissREQUEST_METHODsPOSTsCONTENT_LENGTHs wsgi.inputcs6t_i|diddf|jdS(Ns500 Internal Server Errors Content-Types text/plain(sTruesselfsexecuteds assertEqualssstatuss assertTruesheaders(sstatussheaders(sself(s=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pysstart_responsess sH500 Internal Server Error An unexpected error occurred whilst decoding.(sremotingsdecodesselfs old_methodsutilsBufferedByteStreamsrequestsstrslensenvsstart_responsesgwsresponses assertEqualss assertTruesexecuted(sselfsenvsstart_responsesrequestsresponse((sselfs=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pystest_really_bad_decodegs  -   csti_hdd<dd<dti<}yIxBttfD]4dt_i i |dqCWWnit_nXit_dS(NsREQUEST_METHODsPOSTsCONTENT_LENGTHs0s wsgi.inputcsi||S(N(sselfs_raiseExceptionsxsargsskwargs(sargsskwargs(sxsself(s=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pysscGs|S(N(sargs(sargs((s=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pyss( sremotingsdecodesselfs old_methodsutilsBufferedByteStreamsenvsKeyboardInterrupts SystemExitsxs assertRaisessgw(sselfsenvsx((sselfsxs=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pystest_expected_exceptions_decodes ' $ ( s__name__s __module__ssetUpstest_request_methodstest_bad_requeststest_unknown_requeststest_eof_decodes_raiseExceptionstest_really_bad_decodestest_expected_exceptions_decode(((s=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pysWSGIServerTestCases      cCs*ti}|itit|SdS(N(sunittests TestSuitessuitesaddTests makeSuitesWSGIServerTestCase(ssuite((s=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pyssuites s__main__s defaultTestssuite( s__doc__sunittestspyamfsremotingsutilspyamf.remoting.gateway.wsgis WSGIGatewaysTestCasesWSGIServerTestCasessuites__name__smain(sremotingsWSGIServerTestCasesunittestsutilssuites WSGIGateway((s=build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_wsgi.pys? s    PKũ:9{yy#pyamf/tests/gateway/test_google.pyc; La^Ic@sdZdkZdklZdklZdklZdklZ dei fdYZ dZ e d joeid d ndS( s. Google Web App gateway tests. @since: 0.3.1 N(sStringIO(swebapp(sremoting(sgooglesWebAppGatewayTestCasecBs5tZdZdZdZdZdZRS(NcCstii|ti|_hdt<dt<|_t i |i|_ t i |_ |ii|i |i dS(Ns wsgi.inputs wsgi.output(sunittestsTestCasessetUpsselfs_googles WebAppGatewaysgwsStringIOsenvironswebappsRequestsrequestsResponsesresponses initialize(sself((s?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_google.pyssetUps !cCs/|ii|i|iiddddS(Ns_Response__statusii(sselfsgwsgets assertEqualssresponses__dict__(sself((s?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_google.pystest_get%s cCsZ|idid|ididd|ii|i|iiddddS(Ns wsgi.inputs Bad requestis_Response__statusi( sselfsenvironswritesseeksgwsposts assertEqualssresponses__dict__(sself((s?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_google.pystest_bad_request*s cCs|idid|ididd|ii|i|iidddt i |ii i }|d}|i|it i|i}|it|t i|i|iddS(Ns wsgi.inputs- test.test/1 aa is_Response__statusis/1sService.ResourceNotFound(sselfsenvironswritesseeksgwsposts assertEqualssresponses__dict__sremotingsdecodesoutsgetvaluesenvelopesmessagesstatuss STATUS_ERRORsbodys assertTrues isinstances ErrorFaultscode(sselfsbodysenvelopesmessage((s?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_google.pystest_unknown_request1s   cst_d}ti_ii|didi didi ddii i idS(Ncs ii|t_dS(N(sselfs assertEqualssrequestsTruesexecuted(srequest(sself(s?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_google.pystestHss test.tests wsgi.inputs test.test/1 i( sFalsesselfsexecutedstestsTruesgwsexpose_requests addServicesenvironswritesseeksposts assertTrue(sselfstest((sselfs?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_google.pystest_expose_requestEs    (s__name__s __module__ssetUpstest_getstest_bad_requeststest_unknown_requeststest_expose_request(((s?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_google.pysWebAppGatewayTestCases     cCs*ti}|itit|SdS(N(sunittests TestSuitessuitesaddTests makeSuitesWebAppGatewayTestCase(ssuite((s?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_google.pyssuiteWs s__main__s defaultTestssuite(s__doc__sunittestsStringIOsgoogle.appengine.extswebappspyamfsremotingspyamf.remoting.gatewaysgoogles_googlesTestCasesWebAppGatewayTestCasessuites__name__smain(sremotingsStringIOsWebAppGatewayTestCases_googlessuiteswebappsunittest((s?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_google.pys? s     B  PKũ:_ pyamf/tests/gateway/__init__.pyc; La^Ic@s dZdS(s2 Unit tests for Remoting gateways. @since: 0.1.0 N(s__doc__(((s<build/bdist.linux-x86_64/egg/pyamf/tests/gateway/__init__.pys?sPKũ:\Kx99#pyamf/tests/gateway/test_django.pyc; La^Ic@sdZdkZdkZdkZdklZdklZlZdk lZ dei fdYZ dei fdYZ d Zed joeid d ndS( s& Django gateway tests. @since: 0.1.0 N(shttp(sremotingsutil(sdjangos HttpRequestcBstZdZdZRS(sb Custom C{HttpRequest} to support raw_post_data provided by C{django.core.handlers.*} cOs#tii|||d|_dS(Ns(shttps HttpRequests__init__sselfsargsskwargss raw_post_data(sselfsargsskwargs((s?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_django.pys__init__s(s__name__s __module__s__doc__s__init__(((s?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_django.pys HttpRequests sDjangoGatewayTestCasecBsYtZdZdZdZdZdZdZdZdZ d Z RS( NcCsddk}dtdf|_|i|iti|iussPOSTsis8500 Internal Server Error An unexpected error occurred.(sremotingsdecodesselfs old_methods HttpRequests http_requestsmethods raw_post_datas_djangos DjangoGatewaysgws http_responses assertTrues isinstanceshttpsHttpResponseServerErrors assertEqualss status_codescontent(sselfsgws http_requests http_response((sselfs?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_django.pystest_really_bad_decodess       csti_ti}t}d|_ d|_ y@x9t t fD]+dt_i||qCWWnit_nXit_dS(NsPOSTscsi||S(N(sselfs_raiseExceptionsxsargsskwargs(sargsskwargs(sxsself(s?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_django.pyss(sremotingsdecodesselfs old_methods_djangos DjangoGatewaysgws HttpRequests http_requestsmethods raw_post_datasKeyboardInterrupts SystemExitsxs assertRaises(sselfsgws http_requestsx((sselfsxs?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_django.pystest_expected_exceptions_decodes       ( s__name__s __module__ssetUpstearDownstest_request_methodstest_bad_requeststest_unknown_requeststest_expose_requests_raiseExceptionstest_really_bad_decodestest_expected_exceptions_decode(((s?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_django.pysDjangoGatewayTestCases      cCs*ti}|itit|SdS(N(sunittests TestSuitessuitesaddTests makeSuitesDjangoGatewayTestCase(ssuite((s?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_django.pyssuites s__main__s defaultTestssuite(s__doc__sunittestssyssossdjangoshttpspyamfsremotingsutilspyamf.remoting.gateways_djangos HttpRequestsTestCasesDjangoGatewayTestCasessuites__name__smain( s HttpRequestsutilsremotingshttpsunittestssyssDjangoGatewayTestCases_djangossuitesos((s?build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_django.pys? s     PKũ:OrMM$pyamf/tests/gateway/test_twisted.pyc; HڝIc@sPdZdklZlZdklZdklZlZl Z l Z l Z dk l Z dkZdklZdklZdklZd klZd efd YZd e ifd YZdfdYZde ifdYZde ifdYZde ifdYZdZe djoe i!ddndS(s' Twisted gateway tests. @since: 0.1.0 (sreactorsdefer(sfailure(shttpsserversclientserrorsresource(sunittestN(sremoting(sgateway(s messaging(stwisteds TestServicecBstZdZdZRS(NcCsdSdS(Nsspam((sself((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pysspamscCs|SdS(N(sx(sselfsx((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pysechos(s__name__s __module__sspamsecho(((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pys TestServices sTwistedServerTestCasecBstZdZdZdZdZdZdZdZdZ d Z d Z d Z d Z d ZdZdZRS(NcCsqtidt|_ti}|id|it i dt i |dd|_ |i ii|_dS(Nsexpose_requestsis interfaces 127.0.0.1(s_twistedsTwistedGatewaysFalsesselfsgwsresourcesResourcesrootsputChildsreactors listenTCPsserversSitespsgetHostsport(sselfsroot((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyssetUps  $cCs|iidS(N(sselfsps stopListening(sself((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystearDown%scsItidif}i|ti}|id|SdS(sN A classic GET on the xml server should return a NOT_ALLOWED. shttp://127.0.0.1:%d/cs it|idtiS(Ni(sselfs assertEqualssintsexcsargsshttps NOT_ALLOWED(sexc(sself(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pys/sN( sclientsgetPagesselfsportsds assertFailureserrorsErrors addCallback(sselfsd((sselfs@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_invalid_method(s csUtidifdddd}i|ti}|id|SdS(Nshttp://127.0.0.1:%d/smethodsPOSTspostdatas spamandeggscs it|idtiS(Ni(sselfs assertEqualssintsexcsargsshttps BAD_REQUEST(sexc(sself(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pys8s( sclientsgetPagesselfsportsds assertFailureserrorsErrors addCallback(sselfsd((sselfs@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_bad_content3s csd}ii|tititii }ti dddg}||dss preprocessor(sdefersDeferredsdspps_twistedsTwistedGatewaysgwsgatewaysServiceRequestsNonesservicessselfsservice_requestspreprocessRequest(sselfsgwsppsd((sselfsds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_preprocessors  !cstid}ti|}tihddss preprocessors http_requestshello(sdefersDeferredsdsppsgatewaysexpose_requests_twistedsTwistedGatewaysgwsServiceRequestsNonesservicessselfsservice_requestspreprocessRequest(sselfsgwsppsd((sselfsds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_exposed_preprocessors !cstid}ti|}tihddss preprocessor(sdefersDeferredsdsppsgatewaysexpose_requests_twistedsTwistedGatewaysgwsServiceRequestsNonesservicessselfsservice_requestspreprocessRequest(sselfsgwsppsd((sselfsds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pys$test_exposed_preprocessor_no_requests !csytid}tihddss authenticatorsusp(sdefersDeferredsdsauths_twistedsTwistedGatewaysgwsgatewaysServiceRequestsNonesservicessselfsservice_requestsauthenticateRequest(sselfsgwsdsauth((sselfsds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_authenticates   !cstid}ti|}tihddss authenticatorsusps http_requestsfoo(sdefersDeferredsdsauthsgatewaysexpose_requests_twistedsTwistedGatewaysgwsServiceRequestsNonesservicessselfsservice_requestsauthenticateRequest(sselfsgwsdsauth((sselfsds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_exposed_authenticates  !c stiitd}d}ii|ti t i t i i }tidddg}||dWsssdf(s_twistedsTwistedGatewaysgwsAMF0RequestProcessorsprocsremotingsRequestsrequestsdsselfs assertTrues isinstancesdefersDeferredsresultsresponsesResponsesstatuss STATUS_ERRORsbodys ErrorFault(sselfsgwsdsrequestsprocsresponse((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_unknown_service_requestVs  cCsd}tihddhss authenticatorsenvelopes IndexError(sauths_twistedsTwistedGatewaysgwsAMF0RequestProcessorsprocsremotingsRequestsEnvelopesrequestsdsselfs assertTrues isinstancesdefersDeferredsresultsresponsesResponsesstatuss STATUS_ERRORsbodys ErrorFaults assertEqualsscode(sselfsgwsdsrequestsauthsprocsresponse((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_error_authds !  cCsd}tihddzss authenticatorsenvelopesAuthenticationError(sauths_twistedsTwistedGatewaysgwsAMF0RequestProcessorsprocsremotingsRequestsEnvelopesrequestsdsselfs assertTrues isinstancesdefersDeferredsresultsresponsesResponsesstatuss STATUS_ERRORsbodys ErrorFaults assertEqualsscode(sselfsgwsdsrequestsauthsprocsresponse((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_auth_failvs !  cstid}tihdds(sreactors callLater(susp((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pysauthssechocCs|S(N(sx(sx((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pysss authenticatorsenvelopecsi|itdS(N(sselfs assertTruesresultsdscallbacksNone(sresult(sselfsd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyscbs cs iS(N(sdserrback(sfailure(sd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyss(sdefersDeferredsdsauths_twistedsTwistedGatewaysgwsAMF0RequestProcessorsprocsremotingsRequestsEnvelopesrequestscbs addCallbacks addErrback(sselfsgwsdscbsrequestsauthsproc((sselfsds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_deferred_auths  !"cCsd}tihddss preprocessorsenvelopes IndexError(s preprocessors_twistedsTwistedGatewaysgwsAMF0RequestProcessorsprocsremotingsRequestsEnvelopesrequestsdsselfs assertTrues isinstancesdefersDeferredsresultsresponsesResponsesstatuss STATUS_ERRORsbodys ErrorFaults assertEqualsscode(sselfsgwsdsrequests preprocessorsprocsresponse((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_error_preprocessors !  cstid}tihdds(sreactors callLater(susp((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pys preprocessorssechocCs|S(N(sx(sx((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pysss preprocessorsenvelopecsi|itdS(N(sselfs assertTruesresultsdscallbacksNone(sresult(sselfsd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyscbs cs iS(N(sdserrback(sfailure(sd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyss(sdefersDeferredsds preprocessors_twistedsTwistedGatewaysgwsAMF0RequestProcessorsprocsremotingsRequestsEnvelopesrequestscbs addCallbacks addErrback(sselfsgwsdscbsrequests preprocessorsproc((sselfsds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_deferred_preprocessors  !"cstid}tihddss preprocessorsenvelopecs iS(N(sdserrback(sfailure(sd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyss(sdefersDeferredsds preprocessors_twistedsTwistedGatewaysgwsAMF0RequestProcessorsprocsremotingsRequestsEnvelopesrequests addErrback(sselfsgwsdsrequests preprocessorsproc((sds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_preprocessors  !cstid}ti|}tihdds(sreactors callLater(s http_requestsservice_request((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pys preprocessorssechocCs|S(N(sx(sx((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pysss preprocessorsenvelopecsi|itdS(N(sselfs assertTruesresultsdscallbacksNone(sresult(sselfsd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyscbs cs iS(N(sdserrback(sfailure(sd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyss(sdefersDeferredsds preprocessorsgatewaysexpose_requests_twistedsTwistedGatewaysgwsAMF0RequestProcessorsprocsremotingsRequestsEnvelopesrequestscbs addCallbacks addErrback(sselfsgwsdscbsrequests preprocessorsproc((sselfsds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_exposed_preprocessors  !"cCsd}tihd|<}ti|}tiddti}||}|i t |ti|i}|i t |ti|i |iti|i t |iti|i|iiddS(NcCs tdS(N(sKeyError(sx((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pysechossechosenvelopesKeyError(sechos_twistedsTwistedGatewaysgwsAMF0RequestProcessorsprocsremotingsRequestsEnvelopesrequestsdsselfs assertTrues isinstancesdefersDeferredsresultsresponsesResponsesstatuss STATUS_ERRORsbodys ErrorFaults assertEqualsscode(sselfsgwsdsrequestsechosprocsresponse((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_error_bodys   cstid}tihd|s(sdefersDeferredsd2scbsreactors callLaters addCallback(sxscbsd2((sd2s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pysechos    sechosexpose_requestsenvelopesacsyeit|tii|itiit|iti i |ii dWni nXitdS(Ns IndexError(sselfs assertTrues isinstancesresultsremotingsResponsesstatuss STATUS_ERRORsbodys ErrorFaults assertEqualsscodesdserrbackscallbacksNone(sresult(sdsself(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyscb scs iS(N(sdserrback(sx(sd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyss(sdefersDeferredsdsechos_twistedsTwistedGatewaysFalsesgwsAMF0RequestProcessorsprocsremotingsRequestsEnvelopesrequestsbodyscbs addCallbacks addErrback(sselfsgwsdscbsrequestsechosproc((sselfsds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_error_deferred_bodys    "( s__name__s __module__stest_unknown_service_requeststest_error_authstest_auth_failstest_deferred_authstest_error_preprocessorstest_deferred_preprocessorstest_preprocessorstest_exposed_preprocessorstest_error_bodystest_error_deferred_body(((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pysAMF0RequestProcessorTestCaseUs         sAMF3RequestProcessorTestCasecBsYtZdZdZdZdZdZdZdZdZ d Z RS( NcCstihddssexpose_requestsnullsbodys spam.eggss operationsss(s_twistedsTwistedGatewaysFalsesgwsAMF3RequestProcessorsprocsremotingsRequests messagingsRemotingMessagesrequestsdsselfs assertTrues isinstancesdefersDeferredsresultsresponsesResponsesstatuss STATUS_ERRORsbodys ErrorMessage(sselfsgwsdsrequestsprocsresponse((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_unknown_service_requests!-  cCsd}tihddessexpose_requests preprocessorsnullsbodys spam.eggss operations IndexError(s preprocessors_twistedsTwistedGatewaysFalsesgwsAMF3RequestProcessorsprocsremotingsRequests messagingsRemotingMessagesrequestsdsselfs assertTrues isinstancesdefersDeferredsresultsresponsesResponsesstatuss STATUS_ERRORsbodys ErrorMessages assertEqualss faultCode(sselfsgwsdsrequests preprocessorsprocsresponse((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_error_preprocessoras -  cstid}tihddys(sdefersDeferredsd2sreactors callLater(susargssd2((sd2s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pys preprocessorws sechocCs|S(N(sx(sx((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pys}ssexpose_requests preprocessorsnullsbodys spam.eggss operationcsi|itdS(N(sselfs assertTruesresultsdscallbacksNone(sresult(sselfsd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyscbs cs iS(N(sdserrback(sfailure(sd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyss(sdefersDeferredsds preprocessors_twistedsTwistedGatewaysFalsesgwsAMF3RequestProcessorsprocsremotingsRequests messagingsRemotingMessagesrequestscbs addCallbacks addErrback(sselfsgwsdscbsrequests preprocessorsproc((sselfsds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_deferred_preprocessorts  '-"c stid}tihddssexpose_requests preprocessorsnullsbodys spam.eggss operationcs iS(N(sdserrback(sfailure(sd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyss(sdefersDeferredsds preprocessors_twistedsTwistedGatewaysFalsesgwsAMF3RequestProcessorsprocsremotingsRequests messagingsRemotingMessagesrequests addErrback(sselfsgwsdsrequests preprocessorsproc((sds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_preprocessors  '-cstid}ti|}tihdds(sreactors callLater(s http_requestsservice_request((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pys preprocessorssechocCs|S(N(sx(sx((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pysssexpose_requests preprocessorsnullsbodys spam.eggss operationcs6yi|WninXitdS(N(sselfs assertTruesresultsdserrbackscallbacksNone(sresult(sselfsd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyscbs cs iS(N(sdserrback(sfailure(sd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyss(sdefersDeferredsds preprocessorsgatewaysexpose_requests_twistedsTwistedGatewaysFalsesgwsAMF3RequestProcessorsprocsremotingsRequests messagingsRemotingMessagesrequestscbs addCallbacks addErrback(sselfsgwsdscbsrequests preprocessorsproc((sselfsds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_exposed_preprocessors  '-"cCsd}tihd|s(sdefersDeferredsd2scbsreactors callLaters addCallback(sxscbsd2((sd2s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pysechos    sechosexpose_requestsnullsbodys spam.eggss operationcsyeit|tii|itiit|it i i |ii dWninXitdS(Ns IndexError(sselfs assertTrues isinstancesresultsremotingsResponsesstatuss STATUS_ERRORsbodys messagings ErrorMessages assertEqualss faultCodesdserrbackscallbacksNone(sresult(sdsself(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyscbscs iS(N(sdserrback(sx(sd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyss(sdefersDeferredsdsechos_twistedsTwistedGatewaysFalsesgwsAMF3RequestProcessorsprocsremotingsRequests messagingsRemotingMessagesrequestscbs addCallbacks addErrback(sselfsgwsdscbsrequestsechosproc((sselfsds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_error_deferred_bodys  - "c stitihddssexpose_requestsnullsbodys destinationsspams operationseggscs6yi|WninXitdS(N(sselfs assertTruesresultsdserrbackscallbacksNone(sresult(sselfsd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyscbs cs iS(N(sdserrback(sfailure(sd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyss(sdefersDeferredsds_twistedsTwistedGatewaysFalsesgwsAMF3RequestProcessorsprocsremotingsRequests messagingsRemotingMessagesNonesrequestscbs addCallbacks addErrback(sselfsgwsdscbsrequestsproc((sselfsds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pystest_destinations !3"c stitihddssexpose_requestsnullsbodys destinationsspams operationseggscsK|i}yit|tiWni nXi t dS(N( sresultsbodysmsgsselfs assertTrues isinstances messagingsAcknowledgeMessagesdserrbackscallbacksNone(sresultsmsg(sdsself(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyscbs  cs iS(N(sdserrback(sfailure(sd(s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pys s(sdefersDeferredsds_twistedsTwistedGatewaysFalsesgwsAMF3RequestProcessorsprocsremotingsRequests messagings AsyncMessagesNonesrequestscbs addCallbacks addErrback(sselfsgwsdscbsrequestsproc((sselfsds@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pys test_asyncs !3 "( s__name__s __module__stest_unknown_service_requeststest_error_preprocessorstest_deferred_preprocessorstest_preprocessorstest_exposed_preprocessorstest_error_bodystest_error_deferred_bodystest_destinations test_async(((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pysAMF3RequestProcessorTestCases F      " cCsudk}|i}|i|it|i|it|i|it|i|it|SdS(N( sunittests TestSuitessuitesaddTests makeSuitesTwistedServerTestCasesTwistedGatewayTestCasesAMF0RequestProcessorTestCasesAMF3RequestProcessorTestCase(sunittestssuite((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pyssuites  s__main__s defaultTestssuite("s__doc__stwisted.internetsreactorsdeferstwisted.pythonsfailures twisted.webshttpsserversclientserrorsresources twisted.trialsunittestspyamfsremotingspyamf.remotingsgateways pyamf.flexs messagingspyamf.remoting.gatewaystwisteds_twistedsobjects TestServicesTestCasesTwistedServerTestCasesDummyHTTPRequestsTwistedGatewayTestCasesAMF0RequestProcessorTestCasesAMF3RequestProcessorTestCasessuites__name__smain(sdefersremotingsreactorsAMF0RequestProcessorTestCasesunittests_twistedsgatewayserrorssuitespyamfshttpsAMF3RequestProcessorTestCasesTwistedGatewayTestCasesfailures TestServicesresourcesserversTwistedServerTestCasesclientsDummyHTTPRequests messaging((s@build/bdist.linux-x86_64/egg/pyamf/tests/gateway/test_twisted.pys?s& %       PK7:eTU#pyamf/tests/adapters/test_google.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ PyAMF Google adapter tests. @since: 0.3.1 """ import unittest, datetime, struct from google.appengine.ext import db import pyamf from pyamf import amf3 from pyamf.tests.util import ClassCacheClearingTestCase, Spam from pyamf.adapters import _google_appengine_ext_db as adapter_db # 'borrowed' from http://code.google.com/appengine/docs/datastore/entitiesandmodels.html class PetModel(db.Model): name = db.StringProperty(required=True) type = db.StringProperty(required=True, choices=set(["cat", "dog", "bird"])) birthdate = db.DateProperty() weight_in_pounds = db.IntegerProperty() spayed_or_neutered = db.BooleanProperty() class PetExpando(db.Expando): name = db.StringProperty(required=True) type = db.StringProperty(required=True, choices=set(["cat", "dog", "bird"])) birthdate = db.DateProperty() weight_in_pounds = db.IntegerProperty() spayed_or_neutered = db.BooleanProperty() class EncodingModelTestCase(ClassCacheClearingTestCase): def setUp(self): ClassCacheClearingTestCase.setUp(self) self.jessica = PetModel(name='Jessica', type='cat') self.jessica.birthdate = datetime.date(1986, 10, 2) self.jessica.weight_in_pounds = 5 self.jessica.spayed_or_neutered = False def tearDown(self): ClassCacheClearingTestCase.tearDown(self) try: self.jessica.delete() except: pass def test_amf0(self): encoder = pyamf.get_encoder(pyamf.AMF0) context = encoder.context alias = context.getClassAlias(PetModel) self.assertEquals(alias.__class__, adapter_db.DataStoreClassAlias) encoder.writeElement(self.jessica) self.assertEquals(encoder.stream.getvalue(), '\x03\x00\x10weight_in_pounds\x00@\x14\x00\x00\x00\x00\x00\x00\x00' '\x04name\x02\x00\x07Jessica\x00\x04_key\x05\x00\x04type\x02\x00' '\x03cat\x00\tbirthdate\x0bB^\xc4\xae\xaa\x00\x00\x00\x00\x00\x00' '\x12spayed_or_neutered\x01\x00\x00\x00\t') def test_amf3(self): encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(self.jessica) self.assertEquals(encoder.stream.getvalue(), '\nk\x01\t_key!weight_in_pounds\ttype\tname\x13birthdate%' 'spayed_or_neutered\x01\x04\x05\x06\x07cat\x06\x0fJessica\x08\x01' 'B^\xc4\xae\xaa\x00\x00\x00\x02\x01') def test_save_amf0(self): self.jessica.put() k = str(self.jessica.key()) encoder = pyamf.get_encoder(pyamf.AMF0) encoder.writeElement(self.jessica) self.assertEquals(encoder.stream.getvalue(), '\x03\x00\x10weight_in_pounds\x00@\x14\x00\x00\x00\x00\x00\x00\x00' '\x04name\x02\x00\x07Jessica\x00\x04_key\x02%s%s\x00\x04type\x02' '\x00\x03cat\x00\tbirthdate\x0bB^\xc4\xae\xaa\x00\x00\x00\x00\x00' '\x00\x12spayed_or_neutered\x01\x00\x00\x00\t' % ( struct.pack('>H' ,len(k)), k)) def test_save_amf3(self): self.jessica.put() k = str(self.jessica.key()) encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(self.jessica) self.assertEquals(encoder.stream.getvalue(), '\nk\x01\t_key!weight_in_pounds\ttype\tname\x13birthdate%%' 'spayed_or_neutered\x06%s%s\x04\x05\x06\x07cat\x06\x0fJessica' '\x08\x01B^\xc4\xae\xaa\x00\x00\x00\x02\x01' % ( amf3._encode_int(len(k) << 1 | amf3.REFERENCE_BIT), k )) def test_alias_amf0(self): pyamf.register_class(PetModel, 'Pet') encoder = pyamf.get_encoder(pyamf.AMF0) encoder.writeElement(self.jessica) self.assertEquals(encoder.stream.getvalue(), '\x10\x00\x03Pet\x00\x10weight_in_pounds\x00@\x14\x00\x00\x00\x00' '\x00\x00\x00\x04name\x02\x00\x07Jessica\x00\x04_key\x05\x00\x04' 'type\x02\x00\x03cat\x00\tbirthdate\x0bB^\xc4\xae\xaa\x00\x00\x00' '\x00\x00\x00\x12spayed_or_neutered\x01\x00\x00\x00\t') def test_alias_amf3(self): pyamf.register_class(PetModel, 'Pet') encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(self.jessica) self.assertEquals(encoder.stream.getvalue(), '\nk\x07Pet\t_key!weight_in_pounds\ttype\tname\x13birthdate%' 'spayed_or_neutered\x01\x04\x05\x06\x07cat\x06\x0fJessica\x08\x01' 'B^\xc4\xae\xaa\x00\x00\x00\x02\x01') class EncodingExpandoTestCase(ClassCacheClearingTestCase): def setUp(self): ClassCacheClearingTestCase.setUp(self) self.jessica = PetExpando(name='Jessica', type='cat') self.jessica.birthdate = datetime.date(1986, 10, 2) self.jessica.weight_in_pounds = 5 self.jessica.spayed_or_neutered = False self.jessica.foo = 'bar' def tearDown(self): ClassCacheClearingTestCase.tearDown(self) try: self.jessica.delete() except: pass def test_amf0(self): encoder = pyamf.get_encoder(pyamf.AMF0) encoder.writeElement(self.jessica) self.assertEquals(encoder.stream.getvalue(), '\x03\x00\x10weight_in_pounds\x00@\x14\x00\x00\x00\x00\x00\x00' '\x00\x04name\x02\x00\x07Jessica\x00\x04_key\x05\x00\x03foo\x02' '\x00\x03bar\x00\x04type\x02\x00\x03cat\x00\tbirthdate' '\x0bB^\xc4\xae\xaa\x00\x00\x00\x00\x00\x00\x12spayed_or_neutered' '\x01\x00\x00\x00\t') def test_amf3(self): encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(self.jessica) self.assertEquals(encoder.stream.getvalue(), '\nk\x01\t_key!weight_in_pounds\ttype\tname\x13birthdate%' 'spayed_or_neutered\x01\x04\x05\x06\x07cat\x06\x0fJessica\x08\x01' 'B^\xc4\xae\xaa\x00\x00\x00\x02\x07foo\x06\x07bar\x01') def test_save_amf0(self): self.jessica.put() k = str(self.jessica.key()) encoder = pyamf.get_encoder(pyamf.AMF0) encoder.writeElement(self.jessica) self.assertEquals(encoder.stream.getvalue(), '\x03\x00\x10weight_in_pounds\x00@\x14\x00\x00\x00\x00\x00\x00\x00' '\x04name\x02\x00\x07Jessica\x00\x04_key\x02%s%s\x00\x03foo\x02' '\x00\x03bar\x00\x04type\x02\x00\x03cat\x00\tbirthdate\x0bB^' '\xc4\xae\xaa\x00\x00\x00\x00\x00\x00\x12spayed_or_neutered\x01' '\x00\x00\x00\t' % (struct.pack('>H', len(k)), k)) def test_save_amf3(self): self.jessica.put() k = str(self.jessica.key()) encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(self.jessica) self.assertEquals(encoder.stream.getvalue(), '\nk\x01\t_key!weight_in_pounds\ttype\tname\x13birthdate%%' 'spayed_or_neutered\x06%s%s\x04\x05\x06\x07cat\x06\x0fJessica' '\x08\x01B^\xc4\xae\xaa\x00\x00\x00\x02\x07foo\x06\x07bar\x01' % ( amf3._encode_int(len(k) << 1 | amf3.REFERENCE_BIT), k )) def test_alias_amf0(self): pyamf.register_class(PetExpando, 'Pet') encoder = pyamf.get_encoder(pyamf.AMF0) encoder.writeElement(self.jessica) self.assertEquals(encoder.stream.getvalue(), '\x10\x00\x03Pet\x00\x10weight_in_pounds\x00@\x14\x00\x00\x00\x00' '\x00\x00\x00\x04name\x02\x00\x07Jessica\x00\x04_key\x05\x00\x03' 'foo\x02\x00\x03bar\x00\x04type\x02\x00\x03cat\x00\tbirthdate' '\x0bB^\xc4\xae\xaa\x00\x00\x00\x00\x00\x00\x12spayed_or_neutered' '\x01\x00\x00\x00\t') def test_alias_amf3(self): pyamf.register_class(PetExpando, 'Pet') encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(self.jessica) self.assertEquals(encoder.stream.getvalue(), '\nk\x07Pet\t_key!weight_in_pounds\ttype\tname\x13birthdate%' 'spayed_or_neutered\x01\x04\x05\x06\x07cat\x06\x0fJessica\x08\x01' 'B^\xc4\xae\xaa\x00\x00\x00\x02\x07foo\x06\x07bar\x01') class EncodingReferencesTestCase(ClassCacheClearingTestCase): """ This test case refers to L{db.ReferenceProperty}, not AMF references """ def test_model(self): class Author(db.Model): name = db.StringProperty() class Novel(db.Model): title = db.StringProperty() author = db.ReferenceProperty(Author) a = Author(name='Jane Austen') a.put() k = str(a.key()) b = Novel(title='Sense and Sensibility', author=a) self.assertEquals(b.author, a) try: encoder = pyamf.get_encoder(pyamf.AMF0) encoder.writeElement(b) self.assertEquals(encoder.stream.getvalue(), '\x03\x00\x04_key\x05\x00\x06author\x03\x00\x04_key\x02%s%s' '\x00\x04name\x02\x00\x0bJane Austen\x00\x00\t\x00\x05title' '\x02\x00\x15Sense and Sensibility\x00\x00\t' % ( struct.pack('>H', len(k)), k)) encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(b) self.assertEquals(encoder.stream.getvalue(), '\n;\x01\t_key\rauthor\x0btitle\x01\n+\x01\x00\tname\x06%s%s' '\x06\x17Jane Austen\x01\x06+Sense and Sensibility\x01' % ( amf3._encode_int(len(k) << 1 | amf3.REFERENCE_BIT), k)) # now test with aliases .. pyamf.register_class(Author, 'Author') pyamf.register_class(Novel, 'Novel') encoder = pyamf.get_encoder(pyamf.AMF0) encoder.writeElement(b) self.assertEquals(encoder.stream.getvalue(), '\x10\x00\x05Novel' '\x00\x04_key\x05\x00\x06author\x10\x00\x06Author\x00\x04_key' '\x02%s%s\x00\x04name\x02\x00\x0bJane Austen\x00\x00\t\x00' '\x05title\x02\x00\x15Sense and Sensibility\x00\x00\t' % ( struct.pack('>H', len(k)), k)) encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(b) self.assertEquals(encoder.stream.getvalue(), '\n;\x0bNovel\t_key' '\rauthor\x0btitle\x01\n+\rAuthor\x02\tname\x06%s%s\x06\x17' 'Jane Austen\x01\x06+Sense and Sensibility\x01' % ( amf3._encode_int(len(k) << 1 | amf3.REFERENCE_BIT), k)) except: a.delete() raise a.delete() def test_expando(self): class Author(db.Expando): name = db.StringProperty() class Novel(db.Expando): title = db.StringProperty() author = db.ReferenceProperty(Author) a = Author(name='Jane Austen') a.put() k = str(a.key()) b = Novel(title='Sense and Sensibility', author=a) self.assertEquals(b.author, a) try: encoder = pyamf.get_encoder(pyamf.AMF0) encoder.writeElement(b) self.assertEquals(encoder.stream.getvalue(), '\x03\x00\x04_key\x05\x00\x06author\x03\x00\x04_key\x02%s%s' '\x00\x04name\x02\x00\x0bJane Austen\x00\x00\t\x00\x05title' '\x02\x00\x15Sense and Sensibility\x00\x00\t' % ( struct.pack('>H', len(k)), k)) encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(b) self.assertEquals(encoder.stream.getvalue(), '\n;\x01\t_key\rauthor\x0btitle\x01\n+\x01\x00\tname\x06%s%s' '\x06\x17Jane Austen\x01\x06+Sense and Sensibility\x01' % ( amf3._encode_int(len(k) << 1 | amf3.REFERENCE_BIT), k)) # now test with aliases .. pyamf.register_class(Author, 'Author') pyamf.register_class(Novel, 'Novel') encoder = pyamf.get_encoder(pyamf.AMF0) encoder.writeElement(b) self.assertEquals(encoder.stream.getvalue(), '\x10\x00\x05Novel' '\x00\x04_key\x05\x00\x06author\x10\x00\x06Author\x00\x04_key' '\x02%s%s\x00\x04name\x02\x00\x0bJane Austen\x00\x00\t\x00' '\x05title\x02\x00\x15Sense and Sensibility\x00\x00\t' % ( struct.pack('>H', len(k)), k)) encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(b) self.assertEquals(encoder.stream.getvalue(), '\n;\x0bNovel\t_key\rauthor\x0btitle\x01\n+\rAuthor\x02\tname' '\x06%s%s\x06\x17Jane Austen\x01\x06+Sense and Sensibility' '\x01' % (amf3._encode_int(len(k) << 1 | amf3.REFERENCE_BIT), k)) except: a.delete() raise a.delete() def test_dynamic_property_referenced_object(self): class Author(db.Model): name = db.StringProperty() class Novel(db.Model): title = db.StringProperty() author = db.ReferenceProperty(Author) try: a = Author(name='Jane Austen') a.put() b = Novel(title='Sense and Sensibility', author=a) b.put() x = Novel.all().filter('title = ', 'Sense and Sensibility').get() foo = [1, 2, 3] x.author.bar = foo k = str(x.key()) l = str(x.author.key()) stream = pyamf.encode(x) self.assertEquals(stream.getvalue(), '\x03\x00\x04_key\x02%s%s' '\x00\x06author\x03\x00\x04_key\x02%s%s\x00\x03bar\n\x00' '\x00\x00\x03\x00?\xf0\x00\x00\x00\x00\x00\x00\x00@\x00\x00' '\x00\x00\x00\x00\x00\x00@\x08\x00\x00\x00\x00\x00\x00\x00' '\x04name\x02\x00\x0bJane Austen\x00\x00\t\x00\x05title' '\x02\x00\x15Sense and Sensibility\x00\x00\t' % ( struct.pack('>H', len(k)), k, struct.pack('>H', len(l)), l)) except: a.delete() b.delete() raise a.delete() b.delete() class ListModel(db.Model): numbers = db.ListProperty(long) class ListPropertyTestCase(ClassCacheClearingTestCase): def test_encode(self): obj = ListModel() obj.numbers = [2, 4, 6, 8, 10] encoder = pyamf.get_encoder(pyamf.AMF0) encoder.writeElement(obj) self.assertEquals(encoder.stream.getvalue(), '\x03\x00\x04_key\x05\x00\x07numbers\n\x00\x00\x00\x05\x00@' '\x00\x00\x00\x00\x00\x00\x00\x00@\x10\x00\x00\x00\x00\x00\x00' '\x00@\x18\x00\x00\x00\x00\x00\x00\x00@ \x00\x00\x00\x00\x00\x00' '\x00@$\x00\x00\x00\x00\x00\x00\x00\x00\t') encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(obj) self.assertEquals(encoder.stream.getvalue(), '\n+\x01\t_key\x0fnumbers\x01\t\x0b\x01\x04\x02\x04\x04\x04\x06' '\x04\x08\x04\n\x01') pyamf.register_class(ListModel, 'list-model') encoder = pyamf.get_encoder(pyamf.AMF0) encoder.writeElement(obj) self.assertEquals(encoder.stream.getvalue(), '\x10\x00\nlist-model\x00\x04_key\x05\x00\x07numbers\n\x00\x00' '\x00\x05\x00@\x00\x00\x00\x00\x00\x00\x00\x00@\x10\x00\x00\x00' '\x00\x00\x00\x00@\x18\x00\x00\x00\x00\x00\x00\x00@ \x00\x00\x00' '\x00\x00\x00\x00@$\x00\x00\x00\x00\x00\x00\x00\x00\t') encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(obj) self.assertEquals(encoder.stream.getvalue(), '\n+\x15list-model\t_key\x0fnumbers\x01\t\x0b\x01\x04\x02\x04\x04' '\x04\x06\x04\x08\x04\n\x01') def test_decode(self): pyamf.register_class(ListModel, 'list-model') decoder = pyamf.get_decoder(pyamf.AMF0) decoder.stream.write( '\x10\x00\nlist-model\x00\x07numbers\n\x00\x00' '\x00\x05\x00@\x00\x00\x00\x00\x00\x00\x00\x00@\x10\x00\x00\x00' '\x00\x00\x00\x00@\x18\x00\x00\x00\x00\x00\x00\x00@ \x00\x00' '\x00\x00\x00\x00\x00@$\x00\x00\x00\x00\x00\x00\x00\x00\t') decoder.stream.seek(0) x = decoder.readElement() self.assertTrue(isinstance(x, ListModel)) self.assertTrue(hasattr(x, 'numbers')) self.assertEquals(x.numbers, [2, 4, 6, 8, 10]) decoder = pyamf.get_decoder(pyamf.AMF3) decoder.stream.write( '\n\x0b\x15list-model\x0fnumbers\t\x0b\x01\x04\x02\x04' '\x04\x04\x06\x04\x08\x04\n\x01') decoder.stream.seek(0) x = decoder.readElement() self.assertTrue(isinstance(x, ListModel)) self.assertTrue(hasattr(x, 'numbers')) self.assertEquals(x.numbers, [2, 4, 6, 8, 10]) def test_none(self): pyamf.register_class(ListModel, 'list-model') decoder = pyamf.get_decoder(pyamf.AMF0) decoder.stream.write( '\x10\x00\nlist-model\x00\x07numbers\x05\x00\x00\t') decoder.stream.seek(0) x = decoder.readElement() self.assertEquals(x.numbers, []) class DecodingModelTestCase(ClassCacheClearingTestCase): def setUp(self): ClassCacheClearingTestCase.setUp(self) pyamf.register_class(PetModel, 'Pet') self.jessica = PetModel(name='Jessica', type='cat') self.jessica.birthdate = datetime.date(1986, 10, 2) self.jessica.weight_in_pounds = 5 self.jessica.spayed_or_neutered = False self.jessica.put() self.key = str(self.jessica.key()) def tearDown(self): ClassCacheClearingTestCase.tearDown(self) self.jessica.delete() def test_amf0(self): d = pyamf.get_decoder(pyamf.AMF0) b = d.stream b.write('\x10\x00\x03Pet\x00\x04_key\x02%s%s\x00\x04type\x02\x00\x03' 'cat\x00\x10weight_in_pounds\x00@\x14\x00\x00\x00\x00\x00\x00\x00' '\x04name\x02\x00\x07Jessica\x00\tbirthdate\x0bB^\xc4\xae\xaa\x00' '\x00\x00\x00\x00\x00\x12spayed_or_neutered\x01\x00\x00\x00\t' % ( struct.pack('>H', len(self.key)), self.key)) b.seek(0) x = d.readElement() self.assertTrue(isinstance(x, PetModel)) self.assertEquals(x.__class__, PetModel) self.assertEquals(x.type, self.jessica.type) self.assertEquals(x.weight_in_pounds, self.jessica.weight_in_pounds) self.assertEquals(x.birthdate, self.jessica.birthdate) self.assertEquals(x.spayed_or_neutered, self.jessica.spayed_or_neutered) # now check db.Model internals self.assertEquals(x.key(), self.jessica.key()) self.assertEquals(x.kind(), self.jessica.kind()) self.assertEquals(x.parent(), self.jessica.parent()) self.assertEquals(x.parent_key(), self.jessica.parent_key()) self.assertTrue(x.is_saved()) def test_amf3(self): d = pyamf.get_decoder(pyamf.AMF3) b = d.stream b.write('\n\x0b\x07Pet\tname\x06\x0fJessica\t_key\x06%s%s\x13birthdate' '\x08\x01B^\xc4\xae\xaa\x00\x00\x00!weight_in_pounds\x04\x05\x07' 'foo\x06\x07bar\ttype\x06\x07cat%%spayed_or_neutered\x02\x01' % ( amf3._encode_int(len(self.key) << 1 | amf3.REFERENCE_BIT), self.key)) b.seek(0) x = d.readElement() self.assertTrue(isinstance(x, PetModel)) self.assertEquals(x.__class__, PetModel) self.assertEquals(x.type, self.jessica.type) self.assertEquals(x.weight_in_pounds, self.jessica.weight_in_pounds) self.assertEquals(x.birthdate, self.jessica.birthdate) self.assertEquals(x.spayed_or_neutered, self.jessica.spayed_or_neutered) # now check db.Model internals self.assertEquals(x.key(), self.jessica.key()) self.assertEquals(x.kind(), self.jessica.kind()) self.assertEquals(x.parent(), self.jessica.parent()) self.assertEquals(x.parent_key(), self.jessica.parent_key()) self.assertTrue(x.is_saved()) class DecodingExpandoTestCase(ClassCacheClearingTestCase): def setUp(self): ClassCacheClearingTestCase.setUp(self) pyamf.register_class(PetExpando, 'Pet') self.jessica = PetExpando(name='Jessica', type='cat') #self.jessica.birthdate = datetime.date(1986, 10, 2) self.jessica.weight_in_pounds = 5 self.jessica.spayed_or_neutered = False self.jessica.foo = 'bar' self.jessica.put() self.key = str(self.jessica.key()) def tearDown(self): ClassCacheClearingTestCase.tearDown(self) self.jessica.delete() def test_amf0(self): d = pyamf.get_decoder(pyamf.AMF0) b = d.stream b.write('\x10\x00\x03Pet\x00\x04_key\x02%s%s\x00\x04type\x02\x00\x03' 'cat\x00\x10weight_in_pounds\x00@\x14\x00\x00\x00\x00\x00\x00\x00' '\x04name\x02\x00\x07Jessica\x00\tbirthdate\x0bB^\xc4\xae\xaa\x00' '\x00\x00\x00\x00\x00\x12spayed_or_neutered\x01\x00\x00\x00\t' % ( struct.pack('>H', len(self.key)), self.key)) b.seek(0) x = d.readElement() self.assertTrue(isinstance(x, PetExpando)) self.assertEquals(x.__class__, PetExpando) self.assertEquals(x.type, self.jessica.type) self.assertEquals(x.weight_in_pounds, self.jessica.weight_in_pounds) self.assertEquals(x.birthdate, datetime.date(1986, 10, 2)) self.assertEquals(x.spayed_or_neutered, self.jessica.spayed_or_neutered) # now check db.Expando internals self.assertEquals(x.key(), self.jessica.key()) self.assertEquals(x.kind(), self.jessica.kind()) self.assertEquals(x.parent(), self.jessica.parent()) self.assertEquals(x.parent_key(), self.jessica.parent_key()) self.assertTrue(x.is_saved()) def test_amf3(self): d = pyamf.get_decoder(pyamf.AMF3) b = d.stream b.write('\n\x0b\x07Pet\tname\x06\x0fJessica\t_key\x06%s%s\x13birthdate' '\x08\x01B^\xc4\xae\xaa\x00\x00\x00!weight_in_pounds\x04\x05\x07' 'foo\x06\x07bar\ttype\x06\x07cat%%spayed_or_neutered\x02\x01' % ( amf3._encode_int(len(self.key) << 1 | amf3.REFERENCE_BIT), self.key)) b.seek(0) x = d.readElement() self.assertTrue(isinstance(x, PetExpando)) self.assertEquals(x.__class__, PetExpando) self.assertEquals(x.type, self.jessica.type) self.assertEquals(x.weight_in_pounds, self.jessica.weight_in_pounds) self.assertEquals(x.birthdate, datetime.date(1986, 10, 2)) self.assertEquals(x.spayed_or_neutered, self.jessica.spayed_or_neutered) # now check db.Expando internals self.assertEquals(x.key(), self.jessica.key()) self.assertEquals(x.kind(), self.jessica.kind()) self.assertEquals(x.parent(), self.jessica.parent()) self.assertEquals(x.parent_key(), self.jessica.parent_key()) self.assertTrue(x.is_saved()) class ClassAliasTestCase(unittest.TestCase): def setUp(self): self.alias = adapter_db.DataStoreClassAlias(PetModel, 'foo.bar') self.jessica = PetModel(name='Jessica', type='cat') self.jessica_expando = PetExpando(name='Jessica', type='cat') self.jessica_expando.foo = 'bar' def tearDown(self): try: self.jessica.delete() except: pass if self.jessica_expando.is_saved(): self.jessica_expando.delete() def test_create_instance(self): x = self.alias.createInstance() self.assertTrue(isinstance(x, adapter_db.ModelStub)) #for y in adapter_db.DataStoreClassAlias.INTERNAL_ATTRS: # self.assertEquals(None, getattr(x, y)) self.assertTrue(hasattr(x, 'klass')) self.assertEquals(x.klass, self.alias.klass) # test some stub functions self.assertEquals(x.properties(), self.alias.klass.properties()) self.assertEquals(x.dynamic_properties(), []) def test_apply(self): x = self.alias.createInstance() self.assertTrue(hasattr(x, 'klass')) self.alias.applyAttributes(x, { adapter_db.DataStoreClassAlias.KEY_ATTR: None, 'name': 'Jessica', 'type': 'cat' }) self.assertFalse(hasattr(x, 'klass')) def test_get_attrs(self): self.assertEquals(self.alias.getAttrs(self.jessica), ( # static attributes ['_key', 'weight_in_pounds', 'type', 'name', 'birthdate', 'spayed_or_neutered'], # dynamic attributes [] )) def test_get_attrs_expando(self): self.assertEquals(self.alias.getAttrs(self.jessica_expando), ( # static attributes ['_key', 'weight_in_pounds', 'type', 'name', 'birthdate', 'spayed_or_neutered'], # dynamic attributes ['foo'] )) def test_get_attributes(self): sa, da = self.alias.getAttributes(self.jessica) self.assertEquals(sa, { 'name': 'Jessica', '_key': None, 'birthdate': None, 'weight_in_pounds': None, 'type': 'cat', 'spayed_or_neutered': None }) self.assertEquals(da, {}) def test_get_attributes_saved(self): self.jessica.put() sa, da = self.alias.getAttributes(self.jessica) self.assertEquals(sa, { 'name': 'Jessica', '_key': str(self.jessica.key()), 'birthdate': None, 'weight_in_pounds': None, 'type': 'cat', 'spayed_or_neutered': None }) self.assertEquals(da, {}) def test_get_attributes_expando(self): sa, da = self.alias.getAttributes(self.jessica_expando) self.assertEquals(sa, { 'name': 'Jessica', '_key': None, 'birthdate': None, 'weight_in_pounds': None, 'type': 'cat', 'spayed_or_neutered': None }) self.assertEquals(da, { 'foo': 'bar' }) def test_get_attributes_saved_expando(self): self.jessica_expando.put() sa, da = self.alias.getAttributes(self.jessica_expando) self.assertEquals(sa, { 'name': 'Jessica', '_key': str(self.jessica_expando.key()), 'birthdate': None, 'weight_in_pounds': None, 'type': 'cat', 'spayed_or_neutered': None }) self.assertEquals(da, { 'foo': 'bar' }) def test_arbitrary_properties(self): self.jessica.foo = 'bar' sa, da = self.alias.getAttributes(self.jessica) self.assertEquals(sa, { 'name': 'Jessica', '_key': None, 'birthdate': None, 'weight_in_pounds': None, 'type': 'cat', 'spayed_or_neutered': None }) self.assertEquals(da, { 'foo': 'bar' }) def test_property_type(self): class PropertyTypeModel(db.Model): @property def readonly(self): return True def _get_prop(self): return False def _set_prop(self, v): self.prop = v read_write = property(_get_prop, _set_prop) alias = adapter_db.DataStoreClassAlias(PropertyTypeModel, 'foo.bar') obj = PropertyTypeModel() sa, da = alias.getAttrs(obj) self.assertEquals(sa, ['_key', 'readonly', 'read_write']) self.assertEquals(da, []) sa, da = alias.getAttributes(obj) self.assertEquals(sa, { '_key': None, 'readonly': True, 'read_write': False }) self.assertEquals(da, {}) self.assertFalse(hasattr(obj, 'prop')) alias.applyAttributes(obj, { '_key': None, 'readonly': True, 'read_write': 'foo' }) self.assertEquals(obj.prop, 'foo') class ReferencesTestCase(ClassCacheClearingTestCase): def setUp(self): ClassCacheClearingTestCase.setUp(self) self.jessica = PetModel(name='Jessica', type='cat') self.jessica.birthdate = datetime.date(1986, 10, 2) self.jessica.weight_in_pounds = 5 self.jessica.spayed_or_neutered = False self.jessica.save() self.jessica2 = PetModel.all().filter('name', 'Jessica').get() self.assertNotEquals(id(self.jessica), id(self.jessica2)) self.assertEquals(str(self.jessica.key()), str(self.jessica2.key())) def tearDown(self): ClassCacheClearingTestCase.tearDown(self) self.jessica.delete() def test_amf0(self): encoder = pyamf.get_encoder(pyamf.AMF0) context = encoder.context stream = encoder.stream s = str(self.jessica.key()) self.assertFalse(hasattr(context, 'gae_objects')) encoder.writeObject(self.jessica) self.assertTrue(hasattr(context, 'gae_objects')) self.assertEquals(context.gae_objects, {PetModel: {s: self.jessica}}) self.assertEquals(stream.getvalue(), '\x03\x00\x10weight_in_pounds' '\x00@\x14\x00\x00\x00\x00\x00\x00\x00\x04name\x02\x00\x07Jessica' '\x00\x04_key\x02%s%s\x00\x04type\x02\x00\x03cat\x00\tbirthdate' '\x0bB^\xc4\xae\xaa\x00\x00\x00\x00\x00\x00\x12spayed_or_neutered' '\x01\x00\x00\x00\t' % (struct.pack('>H', len(s)), s)) stream.truncate() encoder.writeObject(self.jessica2) self.assertTrue(hasattr(context, 'gae_objects')) self.assertEquals(context.gae_objects, {PetModel: {s: self.jessica}}) self.assertEquals(stream.getvalue(), '\x07\x00\x00') stream.truncate() # check a non referenced object toby = PetModel(name='Toby', type='cat') toby.put() try: encoder.writeObject(toby) finally: toby.delete() def test_amf3(self): encoder = pyamf.get_encoder(pyamf.AMF3) context = encoder.context stream = encoder.stream s = str(self.jessica.key()) self.assertFalse(hasattr(context, 'gae_objects')) encoder.writeObject(self.jessica) self.assertTrue(hasattr(context, 'gae_objects')) self.assertEquals(context.gae_objects, {PetModel: {s: self.jessica}}) self.assertEquals(stream.getvalue(), '\nk\x01\t_key!weight_in_pounds' '\ttype\tname\x13birthdate%%spayed_or_neutered\x06%s%s\x04\x05\x06' '\x07cat\x06\x0fJessica\x08\x01B^\xc4\xae\xaa' '\x00\x00\x00\x02\x01' % ( amf3._encode_int(len(s) << 1 | amf3.REFERENCE_BIT), s)) stream.truncate() encoder.writeObject(self.jessica2) self.assertTrue(hasattr(context, 'gae_objects')) self.assertEquals(context.gae_objects, {PetModel: {s: self.jessica}}) self.assertEquals(stream.getvalue(), '\n\x00') def test_decode(self): pyamf.register_class(PetModel, 'Pet') k = str(self.jessica.key()) bytes = '\x10\x00\x03Pet\x00\x04_key\x02%s%s\x00\x04type\x02\x00' + \ '\x03cat\x00\x10weight_in_pounds\x00@\x14\x00\x00\x00\x00\x00' + \ '\x00\x00\x04name\x02\x00\x07Jessica\x00\tbirthdate\x0bB^\xc4' + \ '\xae\xaa\x00\x00\x00\x00\x00\x00\x12spayed_or_neutered' + \ '\x01\x00\x00\x00\t' bytes = bytes % (struct.pack('>H', len(k)), k) decoder = pyamf.get_decoder(pyamf.AMF0) context = decoder.context stream = decoder.stream stream.write(bytes * 2) stream.seek(0) j = decoder.readElement() alias = context.getClassAlias(PetModel) self.assertTrue(isinstance(j, PetModel)) self.assertTrue(isinstance(alias, adapter_db.DataStoreClassAlias)) self.assertEquals(context.gae_objects, {PetModel: {k: j}}) j2 = decoder.readElement() self.assertTrue(isinstance(j2, PetModel)) self.assertEquals(context.gae_objects, {PetModel: {k: j}}) def test_cached_reference_properties(self): class Author(db.Model): name = db.StringProperty() class Novel(db.Model): title = db.StringProperty() author = db.ReferenceProperty(Author) a = Author(name='Jane Austen') a.put() k = str(a.key()) b = Novel(title='Sense and Sensibility', author=a) b.put() c = Novel(title='Pride and Prejudice', author=a) c.put() try: s, p = Novel.all().order('-title').fetch(2) encoder = pyamf.get_encoder(pyamf.AMF3) stream = encoder.stream context = encoder.context self.assertFalse(hasattr(context, 'gae_objects')) encoder.writeElement(s) self.assertTrue(hasattr(context, 'gae_objects')) self.assertEquals(context.gae_objects, { Novel: {str(s.key()): s}, Author: {k: a} }) encoder.writeElement(p) self.assertEquals(context.gae_objects, { Novel: { str(s.key()): s, str(p.key()): p, }, Author: {k: a} }) finally: a.delete() b.delete() c.delete() c = Novel(title='Pride and Prejudice', author=None) c.put() encoder = pyamf.get_encoder(encoding=pyamf.AMF3) alias = adapter_db.DataStoreClassAlias(Novel, None) self.assertEquals(alias.getAttributes(c, codec=encoder), ( { '_key': str(c.key()), 'title': 'Pride and Prejudice', 'author': None }, {} )) class GAEReferenceCollectionTestCase(unittest.TestCase): def setUp(self): self.klass = adapter_db.GAEReferenceCollection def test_init(self): x = self.klass() self.assertEquals(x, {}) def test_get(self): x = self.klass() # not a class type self.assertRaises(TypeError, x.getClassKey, chr, '') # not a subclass of db.Model/db.Expando self.assertRaises(TypeError, x.getClassKey, Spam, '') # wrong type for key self.assertRaises(TypeError, x.getClassKey, PetModel, 3) x = self.klass() self.assertRaises(KeyError, x.getClassKey, PetModel, 'foo') self.assertEquals(x, {PetModel: {}}) obj = object() x[PetModel]['foo'] = obj obj2 = x.getClassKey(PetModel, 'foo') self.assertEquals(id(obj), id(obj2)) self.assertEquals(x, {PetModel: {'foo': obj}}) def test_add(self): x = self.klass() # not a class type self.assertRaises(TypeError, x.addClassKey, chr, '') # not a subclass of db.Model/db.Expando self.assertRaises(TypeError, x.addClassKey, Spam, '') # wrong type for key self.assertRaises(TypeError, x.addClassKey, PetModel, 3) x = self.klass() pm1 = PetModel(type='cat', name='Jessica') pm2 = PetModel(type='dog', name='Sam') pe1 = PetExpando(type='cat', name='Toby') self.assertEquals(x, {}) x.addClassKey(PetModel, 'foo', pm1) self.assertEquals(x, {PetModel: {'foo': pm1}}) x.addClassKey(PetModel, 'bar', pm2) self.assertEquals(x, {PetModel: {'foo': pm1, 'bar': pm2}}) x.addClassKey(PetExpando, 'baz', pe1) self.assertEquals(x, { PetModel: {'foo': pm1, 'bar': pm2}, PetExpando: {'baz': pe1} }) class GettableModelStub(db.Model): gets = [] @staticmethod def get(*args, **kwargs): GettableModelStub.gets.append([args, kwargs]) class HelperTestCase(unittest.TestCase): def test_getGAEObjects(self): context = Spam() self.assertFalse(hasattr(context, 'gae_objects')) x = adapter_db.getGAEObjects(context) self.assertTrue(isinstance(x, adapter_db.GAEReferenceCollection)) self.assertTrue(hasattr(context, 'gae_objects')) self.assertEquals(id(x), id(context.gae_objects)) def test_loadInstanceFromDatastore(self): # not a class type self.assertRaises(TypeError, adapter_db.loadInstanceFromDatastore, chr, '') # not a subclass of db.Model/db.Expando self.assertRaises(TypeError, adapter_db.loadInstanceFromDatastore, Spam, '') # not a valid key type self.assertRaises(TypeError, adapter_db.loadInstanceFromDatastore, GettableModelStub, 2) self.assertEquals(GettableModelStub.gets, []) adapter_db.loadInstanceFromDatastore(GettableModelStub, 'foo', codec=None) self.assertEquals(GettableModelStub.gets, [[('foo',), {}]]) codec = Spam() codec.context = Spam() GettableModelStub.gets = [] self.assertFalse(hasattr(codec.context, 'gae_objects')) adapter_db.loadInstanceFromDatastore(GettableModelStub, 'foo', codec=codec) self.assertTrue(hasattr(codec.context, 'gae_objects')) self.assertEquals(GettableModelStub.gets, [[('foo',), {}]]) gae_objects = codec.context.gae_objects self.assertTrue(isinstance(gae_objects, adapter_db.GAEReferenceCollection)) self.assertEquals(gae_objects, {GettableModelStub: {'foo': None}}) def test_Query_type(self): """ L{db.Query} instances get converted to lists .. """ q = PetModel.all() self.assertTrue(isinstance(q, db.Query)) self.assertEquals(pyamf.encode(q).getvalue(), '\n\x00\x00\x00\x00') def suite(): suite = unittest.TestSuite() test_cases = [ EncodingModelTestCase, EncodingExpandoTestCase, EncodingReferencesTestCase, ListPropertyTestCase, DecodingModelTestCase, DecodingExpandoTestCase, ClassAliasTestCase, ReferencesTestCase, GAEReferenceCollectionTestCase, HelperTestCase ] for tc in test_cases: suite.addTest(unittest.makeSuite(tc)) return suite if __name__ == '__main__': unittest.main(defaultTest='suite') PK":5uhh pyamf/tests/adapters/__init__.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ File included to make the directory a Python package. The test_*.py files are special in this directory in that they refer to the top level module names of the adapter to test. An attempt will be made to import that module but ignored if it fails (not available on the system). """ PKp:E//#pyamf/tests/adapters/test_django.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ PyAMF Django adapter tests. @since: 0.3.1 """ import unittest, sys, os, new import datetime import pyamf from pyamf.tests import util class ModelsBaseTestCase(unittest.TestCase): def setUp(self): self.old_env = os.environ.copy() self.mods = sys.modules.copy() if 'DJANGO_SETTINGS_MODULE' in os.environ.keys(): from django import conf import copy self.mod = copy.deepcopy(conf.settings) mod = conf.settings self.existing = True else: os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' mod = new.module('settings') sys.modules['settings'] = mod self.existing = False app = new.module('adapters') app_models = new.module('adapters.models') setattr(app, 'models', app_models) setattr(app, '__file__', '') setattr(app_models, '__file__', '') sys.modules['adapters'] = app sys.modules['adapters.models'] = app_models self.app = app self.models = app_models setattr(mod, 'DATABASE_ENGINE', 'sqlite3') setattr(mod, 'DATABASE_NAME', ':memory:') setattr(mod, 'INSTALLED_APPS', ('adapters',)) setattr(mod, 'USE_I18N', False) from pyamf.adapters import _django_db_models_base as models_adapter self.adapter = models_adapter def tearDown(self): util.replace_dict(os.environ, self.old_env) util.replace_dict(sys.modules, self.mods) if self.existing: from django import conf conf.settings = self.mod def resetDB(self): from django.db import connection import sys old_stderr = sys.stderr sys.stderr = util.NullFileDescriptor() self.db_name = connection.creation.create_test_db(0, autoclobber=True) sys.stderr = old_stderr class TypeMapTestCase(ModelsBaseTestCase): def test_objects_all(self): from django.db import models class Spam(models.Model): pass self.resetDB() encoder = pyamf.get_encoder(pyamf.AMF0) encoder.writeElement(Spam.objects.all()) self.assertEquals(encoder.stream.getvalue(), '\n\x00\x00\x00\x00') encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(Spam.objects.all()) self.assertEquals(encoder.stream.getvalue(), '\t\x01\x01') def test_NOT_PROVIDED(self): from django.db.models import fields encoder = pyamf.get_encoder(pyamf.AMF0) encoder.writeElement(fields.NOT_PROVIDED) self.assertEquals(encoder.stream.getvalue(), '\x06') encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(fields.NOT_PROVIDED) self.assertEquals(encoder.stream.getvalue(), '\x00') class ClassAliasTestCase(ModelsBaseTestCase): def test_time(self): from django.db import models class TestClass(models.Model): t = models.TimeField() d = models.DateField() dt = models.DateTimeField() x = TestClass() x.t = datetime.time(12, 12, 12) x.d = datetime.date(2008, 3, 12) x.dt = datetime.datetime(2008, 3, 12, 12, 12, 12) alias = self.adapter.DjangoClassAlias(TestClass, None) sa, da = alias.getAttributes(x) self.assertEquals(sa, { 'id': None, 'd': datetime.datetime(2008, 3, 12, 0, 0), 'dt': datetime.datetime(2008, 3, 12, 12, 12, 12), 't': datetime.datetime(1970, 1, 1, 12, 12, 12) }) self.assertEquals(da, {}) y = TestClass() alias.applyAttributes(y, { 'id': None, 'd': datetime.datetime(2008, 3, 12, 0, 0), 'dt': datetime.datetime(2008, 3, 12, 12, 12, 12), 't': datetime.datetime(1970, 1, 1, 12, 12, 12) }) self.assertEquals(y.id, None) self.assertEquals(y.d, datetime.date(2008, 3, 12)) self.assertEquals(y.dt, datetime.datetime(2008, 3, 12, 12, 12, 12)) self.assertEquals(y.t, datetime.time(12, 12, 12)) def test_undefined(self): from django.db import models from django.db.models import fields class UndefinedClass(models.Model): pass alias = self.adapter.DjangoClassAlias(UndefinedClass, None) x = UndefinedClass() alias.applyAttributes(x, { 'id': pyamf.Undefined }) self.assertEquals(x.id, fields.NOT_PROVIDED) x.id = fields.NOT_PROVIDED sa, da = alias.getAttributes(x) self.assertEquals(da, {}) self.assertEquals(sa, {'id': pyamf.Undefined}) def test_non_field_prop(self): from django.db import models class Book(models.Model): def _get_number_of_odd_pages(self): return 234 # note the lack of a setter callable .. numberOfOddPages = property(_get_number_of_odd_pages) alias = self.adapter.DjangoClassAlias(Book, 'Book') x = Book() self.assertEquals(alias.getAttrs(x), ( ['id', 'numberOfOddPages'], [] )) self.assertEquals(alias.getAttributes(x), ( {'numberOfOddPages': 234, 'id': None}, {} )) # now we test sending the numberOfOddPages attribute alias.applyAttributes(x, {'numberOfOddPages': 24, 'id': None}) # test it hasn't been set self.assertEquals(x.numberOfOddPages, 234) class ForeignKeyTestCase(ModelsBaseTestCase): def test_one_to_many(self): from django.db import models class Reporter(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30) email = models.EmailField() def __unicode__(self): return u"%s %s" % (self.first_name, self.last_name) class Article(models.Model): headline = models.CharField(max_length=100) pub_date = models.DateField() reporter = models.ForeignKey(Reporter) def __unicode__(self): return self.headline self.resetDB() # initialise the db .. r = Reporter(first_name='John', last_name='Smith', email='john@example.com') r.save() r2 = Reporter(first_name='Paul', last_name='Jones', email='paul@example.com') r2.save() a = Article(headline="This is a test", pub_date=datetime.date(2005, 7, 27), reporter=r) a.save() self.assertEquals(a.id, 1) del a a = Article.objects.filter(pk=1)[0] self.assertFalse('_reporter_cache' in a.__dict__) a.reporter self.assertTrue('_reporter_cache' in a.__dict__) del a a = Article.objects.filter(pk=1)[0] alias = self.adapter.DjangoClassAlias(Reporter, None) self.assertFalse(hasattr(alias, 'fields')) self.assertEquals(alias.getAttrs(a), ( ['id', 'headline', 'pub_date', 'reporter'], [] )) self.assertTrue(hasattr(alias, 'fields')) self.assertEquals(alias.fields.keys(), ['headline', 'pub_date', 'id', 'reporter']) self.assertEquals(alias.getAttributes(a), ( { 'headline': u'This is a test', 'pub_date': datetime.datetime(2005, 7, 27, 0, 0), 'id': 1, 'reporter': None, }, {} )) self.assertFalse('_reporter_cache' in a.__dict__) self.assertEquals(pyamf.encode(a, encoding=pyamf.AMF3).getvalue(), '\nK\x01\x05id\x11headline\x11pub_date\x11reporter\x04\x01\x06' '\x1dThis is a test\x08\x01BpUYj@\x00\x00\x01\x01') del a # now with select_related to pull in the reporter object a = Article.objects.select_related().filter(pk=1)[0] alias = self.adapter.DjangoClassAlias(Reporter, None) self.assertFalse(hasattr(alias, 'fields')) self.assertEquals(alias.getAttrs(a), ( ['id', 'headline', 'pub_date', 'reporter'], [] )) self.assertTrue(hasattr(alias, 'fields')) self.assertEquals(alias.fields.keys(), ['headline', 'pub_date', 'id', 'reporter']) self.assertEquals(alias.getAttributes(a), ( { 'headline': u'This is a test', 'pub_date': datetime.datetime(2005, 7, 27, 0, 0), 'id': 1, 'reporter': r, }, {} )) self.assertTrue('_reporter_cache' in a.__dict__) self.assertEquals(pyamf.encode(a, encoding=pyamf.AMF3).getvalue(), '\nK\x01\x05id\x11headline\x11pub_date\x11reporter' '\x04\x01\x06\x1dThis is a test\x08\x01BpUYj@\x00\x00\nK' '\x01\x00\x15first_name\x13last_name\x0bemail\x04\x01\x06\tJohn' '\x06\x0bSmith\x06!john@example.com\x01\x01') def test_many_to_many(self): from django.db import models class Publication(models.Model): title = models.CharField(max_length=30) def __unicode__(self): return self.title class Meta: ordering = ('title',) class Article2(models.Model): headline = models.CharField(max_length=100) publications = models.ManyToManyField(Publication) def __unicode__(self): return self.headline class Meta: ordering = ('headline',) self.resetDB() # install some test data - taken from # http://www.djangoproject.com/documentation/models/many_to_many/ p1 = Publication(id=None, title='The Python Journal') p1.save() p2 = Publication(id=None, title='Science News') p2.save() p3 = Publication(id=None, title='Science Weekly') p3.save() # Create an Article. a1 = Article2(id=None, headline='Django lets you build Web apps easily') a1.save() self.assertEquals(a1.id, 1) # Associate the Article with a Publication. a1.publications.add(p1) pub_alias = self.adapter.DjangoClassAlias(Publication, None) art_alias = self.adapter.DjangoClassAlias(Article2, None) test_publication = Publication.objects.filter(pk=1)[0] test_article = Article2.objects.filter(pk=1)[0] self.assertEquals(pub_alias.getAttrs(test_publication), ( ['id', 'title'], [] )) self.assertEquals(art_alias.getAttrs(test_article), ( ['id', 'headline', 'publications'], [] )) self.assertEquals(pub_alias.getAttributes(test_publication), ( {'id': 1, 'title': u'The Python Journal'}, {} )) self.assertEquals(art_alias.getAttributes(test_article), ( { 'headline': u'Django lets you build Web apps easily', 'id': 1, 'publications': [p1] }, {}, )) x = Article2() art_alias.applyAttributes(x, { 'headline': u'Test', 'id': 1, 'publications': [p1] }) self.assertEquals(x.headline, u'Test') self.assertEquals(x.id, 1) p = x.publications.all() self.assertEquals(len(p), 1) self.assertEquals(p[0], p1) class I18NTestCase(ModelsBaseTestCase): def test_encode(self): from django.utils.translation import ugettext_lazy self.assertEquals(pyamf.encode(ugettext_lazy('Hello')).getvalue(), '\x02\x00\x05Hello') def suite(): suite = unittest.TestSuite() try: import django except ImportError, e: return suite test_cases = [ TypeMapTestCase, ClassAliasTestCase, ForeignKeyTestCase, I18NTestCase ] for tc in test_cases: suite.addTest(unittest.makeSuite(tc)) return suite if __name__ == '__main__': unittest.main(defaultTest='suite') PK:FU.4.4'pyamf/tests/adapters/test_sqlalchemy.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ PyAMF SQLAlchemy adapter tests. @since 0.4 """ import unittest import sqlalchemy from sqlalchemy import MetaData, Table, Column, Integer, String, ForeignKey, \ create_engine from sqlalchemy.orm import mapper, relation, sessionmaker, clear_mappers, attributes import pyamf.flex from pyamf.tests.util import Spam from pyamf.adapters import _sqlalchemy as adapter class BaseObject(object): def __init__(self, **kwargs): self.__dict__.update(kwargs) class User(BaseObject): def __init__(self, **kwargs): BaseObject.__init__(self, **kwargs) self.lazy_loaded = [LazyLoaded()] class Address(BaseObject): pass class LazyLoaded(BaseObject): pass class AnotherLazyLoaded(BaseObject): pass class BaseTestCase(unittest.TestCase): """ Initialise up all table/mappers. """ def setUp(self): # Create DB and map objects self.metadata = MetaData() self.engine = create_engine('sqlite:///:memory:', echo=False) Session = sessionmaker(bind=self.engine) self.session = Session() self.tables = {} self.tables['users'] = Table('users', self.metadata, Column('id', Integer, primary_key=True), Column('name', String(64))) self.tables['addresses'] = Table('addresses', self.metadata, Column('id', Integer, primary_key=True), Column('user_id', Integer, ForeignKey('users.id')), Column('email_address', String(128))) self.tables['lazy_loaded'] = Table('lazy_loaded', self.metadata, Column('id', Integer, primary_key=True), Column('user_id', Integer, ForeignKey('users.id'))) self.tables['another_lazy_loaded'] = Table('another_lazy_loaded', self.metadata, Column('id', Integer, primary_key=True), Column('user_id', Integer, ForeignKey('users.id'))) self.mappers = {} self.mappers['user'] = mapper(User, self.tables['users'], properties={ 'addresses': relation(Address, backref='user', lazy=False), 'lazy_loaded': relation(LazyLoaded, lazy=True), 'another_lazy_loaded': relation(AnotherLazyLoaded, lazy=True) }) self.mappers['addresses'] = mapper(Address, self.tables['addresses']) self.mappers['lazy_loaded'] = mapper(LazyLoaded, self.tables['lazy_loaded']) self.mappers['another_lazy_loaded'] = mapper(AnotherLazyLoaded, self.tables['another_lazy_loaded']) self.metadata.create_all(self.engine) pyamf.register_class(User, 'server.User') pyamf.register_class(Address, 'server.Address') pyamf.register_class(LazyLoaded, 'server.LazyLoaded') def tearDown(self): clear_mappers() pyamf.unregister_class(User) pyamf.unregister_class(Address) pyamf.unregister_class(LazyLoaded) def _build_obj(self): user = User() user.name = "test_user" user.addresses.append(Address(email_address="test@example.org")) return user def _save(self, obj): # this covers deprecation warnings etc. if hasattr(self.session, 'add'): self.session.add(obj) elif hasattr(self.session, 'save'): self.session.save(obj) else: raise AttributeError('Don\'t know how to save an object') def _clear(self): # this covers deprecation warnings etc. if hasattr(self.session, 'expunge_all'): self.session.expunge_all() elif hasattr(self.session, 'clear'): self.session.clear() else: raise AttributeError('Don\'t know how to clear session') class SATestCase(BaseTestCase): def _test_obj(self, encoded, decoded): self.assertEquals(User, decoded.__class__) self.assertEquals(encoded.name, decoded.name) self.assertEquals(encoded.addresses[0].email_address, decoded.addresses[0].email_address) def test_encode_decode_transient(self): user = self._build_obj() encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(user) encoded = encoder.stream.getvalue() decoded = pyamf.get_decoder(pyamf.AMF3, encoded).readElement() self._test_obj(user, decoded) def test_encode_decode_persistent(self): user = self._build_obj() self._save(user) self.session.commit() self.session.refresh(user) encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(user) encoded = encoder.stream.getvalue() decoded = pyamf.get_decoder(pyamf.AMF3, encoded).readElement() self._test_obj(user, decoded) def test_encode_decode_list(self): max = 5 for i in range(0, max): user = self._build_obj() user.name = "%s" % i self._save(user) self.session.commit() users = self.session.query(User).all() encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(users) encoded = encoder.stream.getvalue() decoded = pyamf.get_decoder(pyamf.AMF3, encoded).readElement() self.assertEquals([].__class__, decoded.__class__) for i in range(0, max): self._test_obj(users[i], decoded[i]) def test_sa_merge(self): user = self._build_obj() for i, string in enumerate(['one', 'two', 'three']): addr = Address(email_address="%s@example.org" % string) user.addresses.append(addr) self._save(user) self.session.commit() self.session.refresh(user) encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(user) encoded = encoder.stream.getvalue() decoded = pyamf.get_decoder(pyamf.AMF3, encoded).readElement() del decoded.addresses[0] del decoded.addresses[1] merged_user = self.session.merge(decoded) self.assertEqual(len(merged_user.addresses), 2) def test_lazy_load_attributes(self): user = self._build_obj() self._save(user) self.session.commit() self._clear() user = self.session.query(User).first() encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(user) encoded = encoder.stream.getvalue() decoded = pyamf.get_decoder(pyamf.AMF3, encoded).readElement() self.assertFalse(decoded.__dict__.has_key('lazy_loaded')) if hasattr(attributes, 'instance_state'): obj_state = attributes.instance_state(decoded) self.assertFalse(obj_state.committed_state.has_key('lazy_loaded')) self.assertFalse(obj_state.dict.has_key('lazy_loaded')) def test_merge_with_lazy_loaded_attrs(self): user = self._build_obj() self._save(user) self.session.commit() self._clear() user = self.session.query(User).first() encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(user) encoded = encoder.stream.getvalue() decoded = pyamf.get_decoder(pyamf.AMF3, encoded).readElement() self.assertFalse(decoded.__dict__.has_key('lazy_loaded')) self.session.merge(user) self.session.commit() user = self.session.query(User).first() self.assertTrue(len(user.lazy_loaded) == 1) def test_encode_decode_with_references(self): user = self._build_obj() self._save(user) self.session.commit() self.session.refresh(user) max = 5 users = [] for i in range(0, max): users.append(user) encoder = pyamf.get_encoder(pyamf.AMF3) encoder.writeElement(users) encoded = encoder.stream.getvalue() decoded = pyamf.get_decoder(pyamf.AMF3, encoded).readElement() for i in range(0, max): self.assertEquals(id(decoded[0]), id(decoded[i])) class BaseClassAliasTestCase(BaseTestCase): def setUp(self): BaseTestCase.setUp(self) self.alias = pyamf.get_class_alias(User) class ClassAliasTestCase(BaseClassAliasTestCase): def test_type(self): self.assertEquals(self.alias.__class__, adapter.SaMappedClassAlias) def test_get_mapper(self): self.assertFalse(hasattr(self.alias, 'primary_mapper')) mapper = self.alias._getMapper(User()) self.assertTrue(hasattr(self.alias, 'primary_mapper')) self.assertEquals(id(mapper), id(self.alias.primary_mapper)) def test_get_attrs(self): u = self._build_obj() static, dynamic = self.alias.getAttrs(u) self.assertEquals(static, [ 'sa_key', 'sa_lazy', 'lazy_loaded', 'addresses', 'another_lazy_loaded', 'id', 'name' ]) self.assertEquals(dynamic, []) def test_get_attributes(self): u = self._build_obj() self.assertFalse(u in self.session) self.assertEquals([None], self.mappers['user'].primary_key_from_instance(u)) static, dynamic = self.alias.getAttributes(u) self.assertEquals(static, { 'sa_lazy': ['another_lazy_loaded'], 'sa_key': [None], 'addresses': u.addresses, 'lazy_loaded': u.lazy_loaded, 'another_lazy_loaded': pyamf.Undefined, 'id': None, 'name': 'test_user' }) self.assertEquals(dynamic, {}) def test_property(self): class Person(object): foo = 'bar' baz = 'gak' def _get_rw_property(self): return self.foo def _set_rw_property(self, val): self.foo = val def _get_ro_property(self): return self.baz rw = property(_get_rw_property, _set_rw_property) ro = property(_get_ro_property) self.mappers['person'] = mapper(Person, self.tables['users']) alias = adapter.SaMappedClassAlias(Person, 'person') obj = Person() sa, da = alias.getAttrs(obj) self.assertEquals(sa, ['sa_key', 'sa_lazy', 'id', 'name', 'rw', 'ro']) self.assertEquals(da, []) sa, da = alias.getAttributes(obj) self.assertEquals(sa, { 'sa_lazy': ['name'], 'rw': 'bar', 'name': pyamf.Undefined, 'sa_key': [None], 'ro': 'gak', 'id': None }) self.assertEquals(da, {}) self.assertEquals(obj.ro, 'gak') alias.applyAttributes(obj, {'ro': 'baz'}) self.assertEquals(obj.ro, 'gak') class ApplyAttributesTestCase(BaseClassAliasTestCase): def test_undefined(self): u = self.alias.createInstance() attrs = { 'sa_lazy': ['another_lazy_loaded'], 'sa_key': [None], 'addresses': [], 'lazy_loaded': [], 'another_lazy_loaded': pyamf.Undefined, # <-- the important bit 'id': None, 'name': 'test_user' } self.alias.applyAttributes(u, attrs) d = u.__dict__.copy() if sqlalchemy.__version__.startswith('0.4'): self.assertTrue('_state' in d) del d['_state'] elif sqlalchemy.__version__.startswith('0.5'): self.assertTrue('_sa_instance_state' in d) del d['_sa_instance_state'] self.assertEquals(d, { 'lazy_loaded': [], 'addresses': [], 'name': 'test_user', 'id': None }) def test_decode_unaliased(self): u = self.alias.createInstance() attrs = { 'sa_lazy': [], 'sa_key': [None], 'addresses': [], 'lazy_loaded': [], # this is important because we haven't registered AnotherLazyLoaded # as an alias and the decoded object for an untyped object is an # instance of pyamf.ASObject 'another_lazy_loaded': [pyamf.ASObject({'id': 1, 'user_id': None})], 'id': None, 'name': 'test_user' } # sqlalchemy can't find any state to work with self.assertRaises(AttributeError, self.alias.applyAttributes, u, attrs) class AdapterTestCase(BaseTestCase): """ Checks to see if the adapter will actually intercept a class correctly """ def test_mapped(self): self.assertNotEquals(None, adapter.class_mapper(User)) self.assertTrue(adapter.is_class_sa_mapped(User)) def test_instance(self): u = User() self.assertTrue(adapter.is_class_sa_mapped(u)) def test_not_mapped(self): self.assertRaises(adapter.UnmappedInstanceError, adapter.class_mapper, Spam) self.assertFalse(adapter.is_class_sa_mapped(Spam)) def suite(): suite = unittest.TestSuite() try: import pysqlite2 except ImportError: return suite classes = [ SATestCase, AdapterTestCase, ClassAliasTestCase, ApplyAttributesTestCase ] for x in classes: suite.addTest(unittest.makeSuite(x)) return suite if __name__ == '__main__': unittest.main(defaultTest='suite') PKũ:C!pyamf/tests/adapters/__init__.pyc; La^Ic@s dZdS(s File included to make the directory a Python package. The test_*.py files are special in this directory in that they refer to the top level module names of the adapter to test. An attempt will be made to import that module but ignored if it fails (not available on the system). N(s__doc__(((s=build/bdist.linux-x86_64/egg/pyamf/tests/adapters/__init__.pys? sPKũ:BR]AA$pyamf/tests/adapters/test_django.pyc; Ic@sdZdkZdkZdkZdkZdkZdkZdklZdei fdYZ de fdYZ de fdYZ d e fd YZ d e fd YZd ZedjoeiddndS(s, PyAMF Django adapter tests. @since: 0.3.1 N(sutilsModelsBaseTestCasecBs#tZdZdZdZRS(NcCstii|_tii|_dtiijoAdk l }dk}|i |i |_ |i }t|_n3dtiddkldifdY}|}tiddd|_tiddd|_ tidddddd|_ |i i |t}|i|\}}|i|hdt<dtidddd d <d tidddddd<d tid d d ddd<|i|h|}|i|hdt<dtidddd d <d tidddddd<d tid d d ddd<|i|it|i|i tiddd|i|i tidddddd|i|itiddddS(N(smodelss TestClasscs,tZiZiZiZRS(N( s__name__s __module__smodelss TimeFieldsts DateFieldsds DateTimeFieldsdt((smodels(s@build/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_django.pys TestClassns  i iisidsdisdtstii(s django.dbsmodelssModels TestClasssxsdatetimestimestsdatesdsdtsselfsadaptersDjangoClassAliassNonesaliass getAttributesssasdas assertEqualssysapplyAttributessid(sselfsmodelss TestClasssaliassysxssasda((smodelss@build/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_django.pys test_timeks   !y y"+cCsdkl}dkl}d|ifdY}|ii|t }|}|i |hdt i<|i|i|i|i|_|i|\}}|i|h|i|hdt i<dS(N(smodels(sfieldssUndefinedClasscBstZRS(N(s__name__s __module__(((s@build/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_django.pysUndefinedClassssid(s django.dbsmodelssdjango.db.modelssfieldssModelsUndefinedClasssselfsadaptersDjangoClassAliassNonesaliassxsapplyAttributesspyamfs Undefineds assertEqualssids NOT_PROVIDEDs getAttributesssasda(sselfssasmodelssfieldssdasaliassxsUndefinedClass((s@build/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_django.pystest_undefineds    cCsdkl}d|ifdY}|ii|d}|}|i |i |ddggf|i |i |hdd<dt tZiddZiZiZ dZ RS(Ns max_lengthidcCs |iSdS(N(sselfsheadline(sself((s@build/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_django.pys __unicode__s( s__name__s __module__smodelss CharFieldsheadlines DateFieldspub_dates ForeignKeysReportersreporters __unicode__((sReportersmodels(s@build/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_django.pysArticles s first_namesJohns last_namesSmithsemailsjohn@example.comsPaulsJonesspaul@example.comsheadlinesThis is a testspub_dateiiisreporterispkis_reporter_cachesfieldssiduThis is a testsencodings? Kidheadlinepub_datereporterThis is a testBpUYj@s Kidheadlinepub_datereporterThis is a testBpUYj@ Kfirst_namelast_name email John Smith!john@example.com(#s django.dbsmodelssModelsReportersArticlesselfsresetDBsrssavesr2sdatetimesdatesas assertEqualssidsobjectssfilters assertFalses__dict__sreporters assertTruesadaptersDjangoClassAliassNonesaliasshasattrsgetAttrssfieldsskeyss getAttributesspyamfsencodesAMF3sgetvaluesselect_related(sselfsasr2sReportersmodelssaliassrsArticle((sReportersmodelss@build/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_django.pystest_one_to_manysP    * +X !+X !csdkldifdYdifdY}|idtdd}|i dtdd }|i dtdd }|i |dtd d }|i |i |id |ii||iit} |ii|t} iidd d} |iidd d} |i | i| ddggf|i | i| dd dggf|i | i| hdd <dds sidstitlesThe Python Journals Science NewssScience Weeklysheadlines%Django lets you build Web apps easilyispkis publicationsuThe Python Journalu%Django lets you build Web apps easilyuTest(!s django.dbsmodelssModels PublicationsArticle2sselfsresetDBsNonesp1ssavesp2sp3sa1s assertEqualssids publicationssaddsadaptersDjangoClassAliass pub_aliass art_aliassobjectssfilterstest_publications test_articlesgetAttrss getAttributessxsapplyAttributessheadlinesallspslen(sselfsArticle2sp2sp1s Publicationsp3smodelssa1spstest_publications pub_aliass art_aliassxs test_article((s Publicationsmodelss@build/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_django.pystest_many_to_many2s:       %(1= .(s__name__s __module__stest_one_to_manystest_many_to_many(((s@build/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_django.pysForeignKeyTestCases gs I18NTestCasecBstZdZRS(NcCs6dkl}|iti|diddS(N(s ugettext_lazysHellosHello(sdjango.utils.translations ugettext_lazysselfs assertEqualsspyamfsencodesgetvalue(sselfs ugettext_lazy((s@build/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_django.pys test_encodes (s__name__s __module__s test_encode(((s@build/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_django.pys I18NTestCasescCsvti}y dk}Wntj o }|SnXtttt g}x$|D]}|i ti |qNW|SdS(N(sunittests TestSuitessuitesdjangos ImportErrorsesTypeMapTestCasesClassAliasTestCasesForeignKeyTestCases I18NTestCases test_casesstcsaddTests makeSuite(sesdjangossuites test_casesstc((s@build/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_django.pyssuites   s__main__s defaultTestssuite(s__doc__sunittestssyssossnewsdatetimespyamfs pyamf.testssutilsTestCasesModelsBaseTestCasesTypeMapTestCasesClassAliasTestCasesForeignKeyTestCases I18NTestCasessuites__name__smain( sutilsModelsBaseTestCases I18NTestCasesunittestsForeignKeyTestCasesTypeMapTestCasesdatetimessyssClassAliasTestCasessuitesnewsosspyamf((s@build/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_django.pys?s$   =`  PKũ:WGTT(pyamf/tests/adapters/test_sqlalchemy.pyc; JIc@sdZdkZdkZdklZlZlZlZlZlZl Z dk l Z l Z l Z lZlZdkZdklZdklZdefdYZdefd YZd efd YZd efd YZdefdYZdeifdYZdefdYZdefdYZ de fdYZ!de fdYZ"defdYZ#dZ$e%djoei&ddndS( s- PyAMF SQLAlchemy adapter tests. @since 0.4 N(sMetaDatasTablesColumnsIntegersStrings ForeignKeys create_engine(smappersrelations sessionmakers clear_mapperss attributes(sSpam(s _sqlalchemys BaseObjectcBstZdZRS(NcKs|ii|dS(N(sselfs__dict__supdateskwargs(sselfskwargs((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pys__init__s(s__name__s __module__s__init__(((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pys BaseObjectssUsercBstZdZRS(NcKs#ti||tg|_dS(N(s BaseObjects__init__sselfskwargss LazyLoadeds lazy_loaded(sselfskwargs((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pys__init__s(s__name__s __module__s__init__(((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pysUserssAddresscBstZRS(N(s__name__s __module__(((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pysAddressss LazyLoadedcBstZRS(N(s__name__s __module__(((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pys LazyLoaded"ssAnotherLazyLoadedcBstZRS(N(s__name__s __module__(((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pysAnotherLazyLoaded%ss BaseTestCasecBs;tZdZdZdZdZdZdZRS(s* Initialise up all table/mappers. c Csft|_tddt|_td|i}||_h|_ t d|it dt dt t dtd|i ds( s__name__s __module__sfoosbazs_get_rw_propertys_set_rw_propertys_get_ro_propertyspropertysrwsro(((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pysPerson4s   susersspersonssa_keyssa_lazysidsnamesrwsrosbarsgaksbaz(sobjectsPersonsmappersselfstablessmapperssadaptersSaMappedClassAliassaliassobjsgetAttrsssasdas assertEqualss getAttributesspyamfs UndefinedsNonesrosapplyAttributes(sselfsobjsPersonsdasaliasssa((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pys test_property3s "O(s__name__s __module__s test_typestest_get_mapperstest_get_attrsstest_get_attributess test_property(((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pysClassAliasTestCases     sApplyAttributesTestCasecBstZdZdZRS(NcCs|ii}hddg<dtg<dg<dg<dti<dt<dd<}|ii|||i i }t i id o|id |j|d =n2t i id o|id |j|d =n|i|hdg<dg<dd<dt<dS( Nssa_lazysanother_lazy_loadedssa_keys addressess lazy_loadedsidsnames test_users0.4s_states0.5s_sa_instance_state(sselfsaliasscreateInstancesusNonespyamfs UndefinedsattrssapplyAttributess__dict__scopysds sqlalchemys __version__s startswiths assertTrues assertEquals(sselfsdsusattrs((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pystest_undefined^sN   cCs|ii}hdg<dtg<dg<dg<dtihdd<dt<g<dt<d d <}|it |ii ||dS( Nssa_lazyssa_keys addressess lazy_loadedsanother_lazy_loadedsidisuser_idsnames test_user( sselfsaliasscreateInstancesusNonespyamfsASObjectsattrss assertRaisessAttributeErrorsapplyAttributes(sselfsusattrs((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pystest_decode_unaliased}sf(s__name__s __module__stest_undefinedstest_decode_unaliased(((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pysApplyAttributesTestCase]s sAdapterTestCasecBs)tZdZdZdZdZRS(sP Checks to see if the adapter will actually intercept a class correctly cCs3|ittit|ititdS(N(sselfsassertNotEqualssNonesadapters class_mappersUsers assertTruesis_class_sa_mapped(sself((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pys test_mappedscCs#t}|iti|dS(N(sUsersusselfs assertTruesadaptersis_class_sa_mapped(sselfsu((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pys test_instances cCs3|ititit|ititdS(N(sselfs assertRaisessadaptersUnmappedInstanceErrors class_mappersSpams assertFalsesis_class_sa_mapped(sself((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pystest_not_mappeds(s__name__s __module__s__doc__s test_mappeds test_instancestest_not_mapped(((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pysAdapterTestCases   cCstti}y dk}Wntj o |SnXttttg}x$|D]}|i ti |qLW|SdS(N( sunittests TestSuitessuites pysqlite2s ImportErrors SATestCasesAdapterTestCasesClassAliasTestCasesApplyAttributesTestCasesclassessxsaddTests makeSuite(s pysqlite2sclassessxssuite((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pyssuites   s__main__s defaultTestssuite('s__doc__sunittests sqlalchemysMetaDatasTablesColumnsIntegersStrings ForeignKeys create_enginessqlalchemy.ormsmappersrelations sessionmakers clear_mapperss attributess pyamf.flexspyamfspyamf.tests.utilsSpamspyamf.adapterss _sqlalchemysadaptersobjects BaseObjectsUsersAddresss LazyLoadedsAnotherLazyLoadedsTestCases BaseTestCases SATestCasesBaseClassAliasTestCasesClassAliasTestCasesApplyAttributesTestCasesAdapterTestCasessuites__name__smain(sSpamsunittestsrelationsStrings ForeignKeys create_enginesUsersAddresssIntegersAdapterTestCasespyamfsMetaDatasAnotherLazyLoadeds sqlalchemys BaseObjectsBaseClassAliasTestCasesColumnsApplyAttributesTestCases attributess clear_mapperssmappersadapters BaseTestCases sessionmakers LazyLoadedssuitesClassAliasTestCasesTables SATestCase((sDbuild/bdist.linux-x86_64/egg/pyamf/tests/adapters/test_sqlalchemy.pys?s*  1%   TX3  PKxK:$[H#pyamf/tests/modules/test_decimal.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Tests for the C{decimal} module integration. """ import unittest import decimal import pyamf class DecimalTestCase(unittest.TestCase): def test_amf0_encode(self): x = decimal.Decimal('1.23456463452345') self.assertEquals(pyamf.encode(x, encoding=pyamf.AMF0, strict=False).getvalue(), '\x00?\xf3\xc0\xc6\xd8\xa18\xfa') self.assertRaises(pyamf.EncodeError, pyamf.encode, x, encoding=pyamf.AMF0, strict=True) def test_amf3_encode(self): x = decimal.Decimal('1.23456463452345') self.assertEquals(pyamf.encode(x, encoding=pyamf.AMF3, strict=False).getvalue(), '\x05?\xf3\xc0\xc6\xd8\xa18\xfa') self.assertRaises(pyamf.EncodeError, pyamf.encode, x, encoding=pyamf.AMF3, strict=True) def suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(DecimalTestCase)) return suite if __name__ == '__main__': unittest.main(defaultTest='suite') PKxK:ص6XX pyamf/tests/modules/test_sets.py# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Tests for the C{sets} module integration. """ import unittest import sets import pyamf from pyamf.tests.util import check_buffer class ImmutableSetTestCase(unittest.TestCase): def test_amf0_encode(self): x = sets.ImmutableSet(['1', '2', '3']) self.assertTrue(check_buffer( pyamf.encode(x, encoding=pyamf.AMF0).getvalue(), ( '\n\x00\x00\x00\x03', ( '\x02\x00\x011', '\x02\x00\x013', '\x02\x00\x012' )) )) def test_amf3_encode(self): x = sets.ImmutableSet(['1', '2', '3']) self.assertTrue(check_buffer( pyamf.encode(x, encoding=pyamf.AMF3).getvalue(), ( '\t\x07\x01', ( '\x06\x031', '\x06\x033', '\x06\x032' )) )) def suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(ImmutableSetTestCase)) return suite if __name__ == '__main__': unittest.main(defaultTest='suite') PKxK:pyamf/tests/modules/__init__.pyPKũ:%ft$pyamf/tests/modules/test_decimal.pyc; Ic@shdZdkZdkZdkZdeifdYZdZedjoeiddndS(s. Tests for the C{decimal} module integration. NsDecimalTestCasecBstZdZdZRS(NcCsitid}|iti|dtidti d|i ti ti|dtidt dS(Ns1.23456463452345sencodingsstricts ?ء8( sdecimalsDecimalsxsselfs assertEqualsspyamfsencodesAMF0sFalsesgetvalues assertRaisess EncodeErrorsTrue(sselfsx((s@build/bdist.linux-x86_64/egg/pyamf/tests/modules/test_decimal.pystest_amf0_encodes'cCsitid}|iti|dtidti d|i ti ti|dtidt dS(Ns1.23456463452345sencodingsstricts ?ء8( sdecimalsDecimalsxsselfs assertEqualsspyamfsencodesAMF3sFalsesgetvalues assertRaisess EncodeErrorsTrue(sselfsx((s@build/bdist.linux-x86_64/egg/pyamf/tests/modules/test_decimal.pystest_amf3_encodes'(s__name__s __module__stest_amf0_encodestest_amf3_encode(((s@build/bdist.linux-x86_64/egg/pyamf/tests/modules/test_decimal.pysDecimalTestCase s cCs*ti}|itit|SdS(N(sunittests TestSuitessuitesaddTests makeSuitesDecimalTestCase(ssuite((s@build/bdist.linux-x86_64/egg/pyamf/tests/modules/test_decimal.pyssuites s__main__s defaultTestssuite( s__doc__sunittestsdecimalspyamfsTestCasesDecimalTestCasessuites__name__smain(sunittestssuitesDecimalTestCasesdecimalspyamf((s@build/bdist.linux-x86_64/egg/pyamf/tests/modules/test_decimal.pys?s     PKũ:ٗ!pyamf/tests/modules/test_sets.pyc; Ic@sudZdkZdkZdkZdklZdeifdYZdZe djoei ddndS( s+ Tests for the C{sets} module integration. N(s check_buffersImmutableSetTestCasecBstZdZdZRS(NcCsYtidddg}|itti|dtii ddddffdS( Ns1s2s3sencodings s1s3s2( ssetss ImmutableSetsxsselfs assertTrues check_bufferspyamfsencodesAMF0sgetvalue(sselfsx((s=build/bdist.linux-x86_64/egg/pyamf/tests/modules/test_sets.pystest_amf0_encodescCsYtidddg}|itti|dtii ddddffdS( Ns1s2s3sencodings s1s3s2( ssetss ImmutableSetsxsselfs assertTrues check_bufferspyamfsencodesAMF3sgetvalue(sselfsx((s=build/bdist.linux-x86_64/egg/pyamf/tests/modules/test_sets.pystest_amf3_encodes(s__name__s __module__stest_amf0_encodestest_amf3_encode(((s=build/bdist.linux-x86_64/egg/pyamf/tests/modules/test_sets.pysImmutableSetTestCases cCs*ti}|itit|SdS(N(sunittests TestSuitessuitesaddTests makeSuitesImmutableSetTestCase(ssuite((s=build/bdist.linux-x86_64/egg/pyamf/tests/modules/test_sets.pyssuite's s__main__s defaultTestssuite( s__doc__sunittestssetsspyamfspyamf.tests.utils check_buffersTestCasesImmutableSetTestCasessuites__name__smain(sImmutableSetTestCasesunittests check_bufferssetsssuitespyamf((s=build/bdist.linux-x86_64/egg/pyamf/tests/modules/test_sets.pys?s      PKũ:" pyamf/tests/modules/__init__.pyc; Ic@sdS(N((((s<build/bdist.linux-x86_64/egg/pyamf/tests/modules/__init__.pys?sPK©:M-1 EGG-INFO/PKG-INFOMetadata-Version: 1.0 Name: PyAMF Version: 0.4.2 Summary: AMF support for Python Home-page: http://pyamf.org Author: The PyAMF Project Author-email: dev@pyamf.org License: MIT License Description: PyAMF provides Action Message Format (AMF) support for Python that is compatible with the Flash Player. It includes integration with Python web frameworks like Django, Pylons, Twisted, SQLAlchemy and more. The Adobe Integrated Runtime and Flash Player use AMF to communicate between an application and a remote server. AMF encodes remote procedure calls (RPC) into a compact binary representation that can be transferred over HTTP/HTTPS or the RTMP/RTMPS protocol. Objects and data values are serialized into this binary format, which increases performance, allowing applications to load data up to 10 times faster than with text-based formats such as XML or SOAP. AMF3, the default serialization for ActionScript 3.0, provides various advantages over AMF0, which is used for ActionScript 1.0 and 2.0. AMF3 sends data over the network more efficiently than AMF0. AMF3 supports sending int and uint objects as integers and supports data types that are available only in ActionScript 3.0, such as ByteArray, ArrayCollection, and ObjectProxy. Keywords: amf amf0 amf3 flex flash remoting rpc http flashplayer air bytearray objectproxy arraycollection recordset actionscript decoder encoder gateway remoteobject twisted pylons django sharedobject lso sol Platform: any Classifier: Development Status :: 5 - Production/Stable Classifier: Framework :: Django Classifier: Framework :: Pylons Classifier: Framework :: Turbogears Classifier: Framework :: Twisted Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Information Technology Classifier: License :: OSI Approved :: MIT License Classifier: Natural Language :: English Classifier: Operating System :: OS Independent Classifier: Programming Language :: C Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.3 Classifier: Programming Language :: Python :: 2.4 Classifier: Programming Language :: Python :: 2.5 Classifier: Programming Language :: Python :: 2.6 Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application Classifier: Topic :: Software Development :: Libraries :: Python Modules PK©:((EGG-INFO/SOURCES.txtREADME.txt setup.cfg setup.py PyAMF.egg-info/PKG-INFO PyAMF.egg-info/SOURCES.txt PyAMF.egg-info/dependency_links.txt PyAMF.egg-info/requires.txt PyAMF.egg-info/top_level.txt PyAMF.egg-info/zip-safe cpyamf/__init__.py cpyamf/amf3.c cpyamf/util.c pyamf/__init__.py pyamf/amf0.py pyamf/amf3.py pyamf/logging.py pyamf/sol.py pyamf/adapters/__init__.py pyamf/adapters/_decimal.py pyamf/adapters/_django_db_models_base.py pyamf/adapters/_django_db_models_fields.py pyamf/adapters/_django_db_models_query.py pyamf/adapters/_django_utils_translation.py pyamf/adapters/_google_appengine_ext_db.py pyamf/adapters/_sets.py pyamf/adapters/_sqlalchemy.py pyamf/adapters/util.py pyamf/flex/__init__.py pyamf/flex/data.py pyamf/flex/messaging.py pyamf/remoting/__init__.py pyamf/remoting/amf0.py pyamf/remoting/amf3.py pyamf/remoting/client/__init__.py pyamf/remoting/gateway/__init__.py pyamf/remoting/gateway/django.py pyamf/remoting/gateway/google.py pyamf/remoting/gateway/twisted.py pyamf/remoting/gateway/wsgi.py pyamf/tests/adapters/__init__.py pyamf/tests/adapters/test_django.py pyamf/tests/adapters/test_google.py pyamf/tests/adapters/test_sqlalchemy.py pyamf/tests/gateway/__init__.py pyamf/tests/gateway/test_django.py pyamf/tests/gateway/test_google.py pyamf/tests/gateway/test_twisted.py pyamf/tests/gateway/test_wsgi.py pyamf/tests/modules/__init__.py pyamf/tests/modules/test_decimal.py pyamf/tests/modules/test_sets.py pyamf/tests/remoting/__init__.py pyamf/tests/remoting/test_client.py pyamf/tests/remoting/test_remoteobject.py pyamf/util/__init__.py pyamf/util/imports.pyPK©:2EGG-INFO/dependency_links.txt PK©:+/jEGG-INFO/requires.txtelementtree >= 1.2.6 uuid>=1.30 fpconst>=0.7.2 [cython] Cython>=0.10 [wsgi] wsgiref [sqlalchemy] SQLAlchemy>=0.4 [twisted] Twisted>=2.5.0 [django] Django>=0.96PK©: EGG-INFO/top_level.txtcpyamf pyamf PK©:2EGG-INFO/zip-safe PKũ:V z!EGG-INFO/native_libs.txtcpyamf/util.so cpyamf/amf3.so PK":P݇cpyamf/__init__.pyPKĩ:U3  cpyamf/util.soPKĩ:pAcpyamf/amf3.soPKĩ:K:cpyamf/__init__.pycPKũ:%cpyamf/util.pyPKũ:GPcpyamf/amf3.pyPKũ:0,,cpyamf/util.pycPKũ:j',,cpyamf/amf3.pycPK":$ @pyamf/sol.pyPKݥ:![d՟՟Epyamf/__init__.pyPKS:dfnn INpyamf/amf0.pyPKp:ޝqq pyamf/amf3.pyPK":w?8pyamf/logging.pyPKĩ:x~~ pyamf/sol.pycPKũ:vZpyamf/__init__.pycPKũ: 늂pyamf/amf0.pycPKũ:6= = Apyamf/amf3.pycPKũ:E^^ pyamf/logging.pycPKxK:o@  7$ pyamf/adapters/_decimal.pyPK":0^^|( pyamf/adapters/_sets.pyPKxK:p* pyamf/adapters/util.pyPKS:C(vv)7- pyamf/adapters/_django_db_models_query.pyPK[K:6Qف. pyamf/adapters/__init__.pyPK[K:p*7 pyamf/adapters/_django_db_models_fields.pyPK,j: >((+9 pyamf/adapters/_django_utils_translation.pyPKi:kWRR< pyamf/adapters/_sqlalchemy.pyPK,j: (U pyamf/adapters/_django_db_models_base.pyPK,j:ӶQ/Q/*d pyamf/adapters/_google_appengine_ext_db.pyPKũ:/DDR pyamf/adapters/_decimal.pycPKũ:_7]ϙ pyamf/adapters/_sets.pycPKũ:n pyamf/adapters/util.pycPKũ:)%99*4 pyamf/adapters/_django_db_models_query.pycPKũ: ܱ7 7  pyamf/adapters/__init__.pycPKũ:++% pyamf/adapters/_django_db_models_fields.pycPKũ:=fU,% pyamf/adapters/_django_utils_translation.pycPKũ:Nuu# pyamf/adapters/_sqlalchemy.pycPKũ:e) pyamf/adapters/_django_db_models_base.pycPK:SA;L;L pyamf/remoting/__init__.pyPK":gsN2 pyamf/remoting/amf0.pyPK::|袻rA pyamf/remoting/amf3.pyPKũ:@mmaW pyamf/remoting/__init__.pycPKũ:> pyamf/remoting/amf0.pycPKũ:bl) pyamf/remoting/amf3.pycPK":55U pyamf/remoting/gateway/wsgi.pyPK":FF pyamf/remoting/gateway/google.pyPK":? FF"J pyamf/remoting/gateway/__init__.pyPK":D e pyamf/remoting/gateway/django.pyPKɨ.:e22!x pyamf/remoting/gateway/twisted.pyPKũ:RY6 pyamf/remoting/gateway/wsgi.pycPKũ:>}}! pyamf/remoting/gateway/google.pycPKũ:P)`\`\# pyamf/remoting/gateway/__init__.pycPKũ:M!81 pyamf/remoting/gateway/django.pycPKũ:[CNCN"E pyamf/remoting/gateway/twisted.pycPKY:lۋ>>! pyamf/remoting/client/__init__.pyPKũ:j;RR"F pyamf/remoting/client/__init__.pycPKS:lyՎ&&p& pyamf/util/imports.pyPKmGl:WReRe1M pyamf/util/__init__.pyPKũ:0.. pyamf/util/imports.pycPKũ:\f  pyamf/util/__init__.pycPK":FO#~pyamf/flex/data.pyPK":Cf'f'/pyamf/flex/messaging.pyPK:I\vOʵpyamf/flex/__init__.pyPKũ:INpyamf/flex/data.pycPKũ:NQ##Hpyamf/flex/messaging.pycPKũ:uɎQ)Q)pyamf/flex/__init__.pycPK:!@K@K#0pyamf/tests/remoting/test_client.pyPK":uUpp |pyamf/tests/remoting/__init__.pyPK":m}=)|pyamf/tests/remoting/test_remoteobject.pyPKũ:حoo$Ҙpyamf/tests/remoting/test_client.pycPKũ:4Y<!pyamf/tests/remoting/__init__.pycPKũ:\PҰ22* pyamf/tests/remoting/test_remoteobject.pycPK":nW\ <pyamf/tests/gateway/test_wsgi.pyPK":W0  "Opyamf/tests/gateway/test_google.pyPK":XwLZpyamf/tests/gateway/__init__.pyPK":"Zpyamf/tests/gateway/test_django.pyPKS: a?d?d#mpyamf/tests/gateway/test_twisted.pyPKũ:85 !pyamf/tests/gateway/test_wsgi.pycPKũ:9{yy#pyamf/tests/gateway/test_google.pycPKũ:_ pyamf/tests/gateway/__init__.pycPKũ:\Kx99#pyamf/tests/gateway/test_django.pycPKũ:OrMM$3$pyamf/tests/gateway/test_twisted.pycPK7:eTU#pyamf/tests/adapters/test_google.pyPK":5uhh ~pyamf/tests/adapters/__init__.pyPKp:E//#9pyamf/tests/adapters/test_django.pyPK:FU.4.4'ypyamf/tests/adapters/test_sqlalchemy.pyPKũ:C!pyamf/tests/adapters/__init__.pycPKũ:BR]AA$pyamf/tests/adapters/test_django.pycPKũ:WGTT((pyamf/tests/adapters/test_sqlalchemy.pycPKxK:$[H#O}pyamf/tests/modules/test_decimal.pyPKxK:ص6XX pyamf/tests/modules/test_sets.pyPKxK:,pyamf/tests/modules/__init__.pyPKũ:%ft$ipyamf/tests/modules/test_decimal.pycPKũ:ٗ!pyamf/tests/modules/test_sets.pycPKũ:" Җpyamf/tests/modules/__init__.pycPK©:M-1 EGG-INFO/PKG-INFOPK©:((QEGG-INFO/SOURCES.txtPK©:2EGG-INFO/dependency_links.txtPK©:+/jEGG-INFO/requires.txtPK©: EGG-INFO/top_level.txtPK©:2EGG-INFO/zip-safePKũ:V z!/EGG-INFO/native_libs.txtPKee$