3 f#~@sbdZddddddddd d d d d dgZddlZddlZddlZddlZddlZddlmZddl Z ddl Z ddl Z ddl Z ddl mZddlmZejddedZejejGdddeZGdddeZejddZGdddeZddZddZddZd dZ Gd!ddZ!d"Z"e j#d#Z$dPd%d&Z%d'd(Z&e j#d)e j'Z(d*d+Z)d,d-Z*d.d/Z+Gd0d1d1Z,Gd2d3d3Z-Gd4d5d5e-Z.d6d7Z/Gd8dde0Z1d9d:d;dd?d?Z5d@dAZ6e7e8e9eje:fZ;GdBdCdCe3Zee/e,e.dFe?ee=e5edGdKdLdMd ZCe>dKdGdNdOdZDdS)Qaplistlib.py -- a tool to generate and parse MacOSX .plist files. The property list (.plist) file format is a simple XML pickle supporting basic object types, like dictionaries, lists, numbers and strings. Usually the top level object is a dictionary. To write out a plist file, use the dump(value, file) function. 'value' is the top level object, 'file' is a (writable) file object. To parse a plist from a file, use the load(file) function, with a (readable) file object as the only argument. It returns the top level object (again, usually a dictionary). To work with plist data in bytes objects, you can use loads() and dumps(). Values can be strings, integers, floats, booleans, tuples, lists, dictionaries (but only with string keys), Data, bytes, bytearray, or datetime.datetime objects. Generate Plist example: pl = dict( aString = "Doodah", aList = ["A", "B", 12, 32.1, [1, 2, 3]], aFloat = 0.1, anInt = 728, aDict = dict( anotherString = "", aUnicodeValue = "M\xe4ssig, Ma\xdf", aTrueValue = True, aFalseValue = False, ), someData = b"", someMoreData = b"" * 10, aDate = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())), ) with open(fileName, 'wb') as fp: dump(pl, fp) Parse Plist example: with open(fileName, 'rb') as fp: pl = load(fp) print(pl["aKey"]) readPlist writePlistreadPlistFromByteswritePlistToBytesPlistDataDictInvalidFileExceptionFMT_XML FMT_BINARYloaddumploadsdumpsN)BytesIO)warn) ParserCreate PlistFormatzFMT_XML FMT_BINARY)modulec@s(eZdZfZddZddZddZdS) _InternalDictc Cs:y ||}Wntk r(t|YnXtdtd|S)NzLAttribute access from plist dicts is deprecated, use d[key] notation instead)KeyErrorAttributeErrorrDeprecationWarning)selfattrvaluer /usr/lib64/python3.6/plistlib.py __getattr__Vs z_InternalDict.__getattr__cCstdtd|||<dS)NzLAttribute access from plist dicts is deprecated, use d[key] notation insteadr)rr)rrrrrr __setattr___sz_InternalDict.__setattr__c Cs8y ||=Wntk r&t|YnXtdtddS)NzLAttribute access from plist dicts is deprecated, use d[key] notation insteadr)rrrr)rrrrr __delattr__ds  z_InternalDict.__delattr__N)__name__ __module__ __qualname__ __slots__rr r!rrrrrOs rcseZdZfddZZS)rc stdtdtjf|dS)Nz?The plistlib.Dict class is deprecated, use builtin dict insteadr)rrsuper__init__)rkwargs) __class__rrr'osz Dict.__init__)r"r#r$r' __classcell__rr)r)rrmsc cs2t|tr(t|| }|VWdQRXn|VdS)N) isinstancestropen) pathOrFilemodefprrr _maybe_openus  r1cs4eZdZdZfddZeddZddZZS)rzuThis class has been deprecated. Use dump() and load() functions instead, together with regular dict objects. c stdtdtjf|dS)NzJThe Plist class is deprecated, use the load() and dump() functions insteadr)rrr&r')rr()r)rrr'szPlist.__init__c Cs2t|d}t|}WdQRX|}|j||S)z,Deprecated. Use the load() function instead.rbN)r1r update)clsr.r0rZplistrrrfromFiles   zPlist.fromFilec Cs$t|d}t||WdQRXdS)z,Deprecated. Use the dump() function instead.wbN)r1r )rr.r0rrrwrites z Plist.write) r"r#r$__doc__r' classmethodr5r7r*rr)r)rrs  c Cs2tdtdt|d}t|ddtdSQRXdS)z Read a .plist from a path or file. pathOrFile should either be a file name, or a readable binary file object. This function is deprecated, use load instead. z8The readPlist function is deprecated, use load() insteadrr2NF)fmtuse_builtin_types dict_type)rrr1r r)r.r0rrrrs  cCs8tdtdt|d}t||tdddWdQRXdS)z Write 'value' to a .plist file. 'pathOrFile' may either be a file name or a (writable) file object. This function is deprecated, use dump instead. z9The writePlist function is deprecated, use dump() insteadrr6TF)r: sort_keysskipkeysN)rrr1r r )rr.r0rrrrs cCs tdtdtt|ddtdS)z} Read a plist data from a bytes object. Return the root object. This function is deprecated, use loads instead. zBThe readPlistFromBytes function is deprecated, use loads() insteadrNF)r:r;r<)rrr rr)datarrrrs cCs,tdtdt}t||tddd|jS)zp Return 'value' as a plist-formatted bytes object. This function is deprecated, use dumps instead. zAThe writePlistToBytes function is deprecated, use dumps() insteadrTF)r:r=r>)rrrr r getvalue)rfrrrrs c@s>eZdZdZddZeddZdddZd d Zd d Z d S)rz] Wrapper for binary data. This class is deprecated, use a bytes object instead. cCst|tstd||_dS)Nzdata must be as bytes)r+bytes TypeErrorr?)rr?rrrr's z Data.__init__cCs |t|S)N)_decode_base64)r4r?rrr fromBase64szData.fromBase64LcCs t|j|S)N)_encode_base64r?)r maxlinelengthrrrasBase64sz Data.asBase64cCs4t||jr|j|jkSt|tr,|j|kStSdS)N)r+r)r?rBNotImplemented)rotherrrr__eq__s     z Data.__eq__cCsd|jjt|jfS)Nz%s(%s))r)r"reprr?)rrrr__repr__sz Data.__repr__N)rF) r"r#r$r8r'r9rErIrLrNrrrrrs   s zv[\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f]rFcCsT|dd}g}x8tdt||D]$}||||}|jtj|q"Wdj|S)Nr)rangelenappendbinasciiZ b2a_base64join)srHZ maxbinsizepiecesichunkrrrrGs  rGcCs(t|trtj|jdStj|SdS)Nzutf-8)r+r,rUZ a2b_base64encode)rWrrrrD s rDz{(?P\d\d\d\d)(?:-(?P\d\d)(?:-(?P\d\d)(?:T(?P\d\d)(?::(?P\d\d)(?::(?P\d\d))?)?)?)?)?ZcCsNd}tj|j}g}x,|D]$}||}|dkr2P|jt|qWtj|S)Nyearmonthdayhourminutesecond)r\r]r^r_r`ra) _dateParsermatch groupdictrTintdatetime)rWorderZgdZlstkeyvalrrr_date_from_strings rjcCs d|j|j|j|j|j|jfS)Nz%04d-%02d-%02dT%02d:%02d:%02dZ)r\r]r^r_r`ra)drrr_date_to_string&s rlcCsZtj|}|dk rtd|jdd}|jdd}|jdd}|jdd}|jd d }|S) Nzz>)_controlCharPatsearch ValueErrorreplace)textmrrr_escape,s      rxc@seZdZddZddZddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ ddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zd'S)( _PlistParsercCs"g|_d|_d|_||_||_dS)N)stack current_keyroot_use_builtin_types _dict_type)rr;r<rrrr'9s z_PlistParser.__init__cCs8t|_|j|j_|j|j_|j|j_|jj||j S)N) rparserhandle_begin_elementZStartElementHandlerhandle_end_elementZEndElementHandler handle_dataZCharacterDataHandlerZ ParseFiler|)rZfileobjrrrparse@s     z_PlistParser.parsecCs*g|_t|d|d}|dk r&||dS)NZbegin_)r?getattr)relementattrshandlerrrrrHsz!_PlistParser.handle_begin_elementcCs"t|d|d}|dk r|dS)NZend_)r)rrrrrrrNsz_PlistParser.handle_end_elementcCs|jj|dS)N)r?rT)rr?rrrrSsz_PlistParser.handle_datacCs|jdk rFt|jdtis.td|jj||jd|j<d|_nB|jsT||_n4t|jdtgsxtd|jj|jdj|dS)Nzunexpected element at line %drrr) r{r+rztypertrCurrentLineNumberr|rT)rrrrr add_objectVs   z_PlistParser.add_objectcCsdj|j}g|_|S)N)rVr?)rr?rrrget_datafs z_PlistParser.get_datacCs"|j}|j||jj|dS)N)r~rrzrT)rrrkrrr begin_dictms z_PlistParser.begin_dictcCs*|jrtd|j|jjf|jjdS)Nz%missing value for key '%s' at line %d)r{rtrrrzpop)rrrrend_dictrsz_PlistParser.end_dictcCs:|jst|jdti r,td|jj|j|_dS)Nrzunexpected key at line %dr)r{r+rzrrtrrr)rrrrend_keyxs z_PlistParser.end_keycCsg}|j||jj|dS)N)rrzrT)rrarrr begin_array~s z_PlistParser.begin_arraycCs|jjdS)N)rzr)rrrr end_arraysz_PlistParser.end_arraycCs|jddS)NT)r)rrrrend_truesz_PlistParser.end_truecCs|jddS)NF)r)rrrr end_falsesz_PlistParser.end_falsecCs|jt|jdS)N)rrer)rrrr end_integersz_PlistParser.end_integercCs|jt|jdS)N)rfloatr)rrrrend_realsz_PlistParser.end_realcCs|j|jdS)N)rr)rrrr end_stringsz_PlistParser.end_stringcCs2|jr|jt|jn|jtj|jdS)N)r}rrDrrrE)rrrrend_datasz_PlistParser.end_datacCs|jt|jdS)N)rrjr)rrrrend_datesz_PlistParser.end_dateN)r"r#r$r'rrrrrrrrrrrrrrrrrrrrrrry8s&ryc@s8eZdZdddZddZddZdd d Zd d Zd S)_DumbXMLWriterr cCs||_g|_||_||_dS)N)filerz _indent_levelindent)rr indent_levelrrrrr'sz_DumbXMLWriter.__init__cCs,|jj||jd||jd7_dS)Nz<%s>r)rzrTwritelnr)rrrrr begin_elements z_DumbXMLWriter.begin_elementcCs |jd8_|jd|dS)Nrz)rr)rrrrr end_elementsz_DumbXMLWriter.end_elementNcCs8|dk r&t|}|jd|||fn|jd|dS)Nz <%s>%sz<%s/>)rxr)rrrrrrsimple_elementsz_DumbXMLWriter.simple_elementcCsH|r8t|tr|jd}|jj|j|j|jj||jjddS)Nzutf-8 )r+r,r[rr7rr)rlinerrrrs    z_DumbXMLWriter.writeln)rr)N)r"r#r$r'rrrrrrrrrs   rc@sFeZdZdddZdd Zd d Zd d ZddZddZddZ dS) _PlistWriterr rTFcCs.|r|jttj||||||_||_dS)N)r7 PLISTHEADERrr' _sort_keys _skipkeys)rrrrZ writeHeaderr=r>rrrr's  z_PlistWriter.__init__cCs"|jd|j||jddS)Nzz)r write_value)rrrrrr7s  z_PlistWriter.writecCs4t|tr|jd|n|dkr0|jdn|dkrD|jdnt|trd|ko`dknrx|jd d |nt|nt|tr|jd t|nt|tr|j|n|t|t r|j |nft|t t fr|j |nLt|tjr|jd t|n,t|ttfr |j|ntd t|dS)NstringTtrueFZfalser?@Zintegerz%drealZdatezunsupported type: %srll)r+r,rre OverflowErrorrrMdict write_dictr write_datarB bytearray write_bytesrfrltuplelist write_arrayrCr)rrrrrrs.           z_PlistWriter.write_valuecCs|j|jdS)N)rr?)rr?rrrrsz_PlistWriter.write_datacCs~|jd|jd8_tddt|jjdd |j}x&t||jdD]}|rL|j|qLW|jd7_|j ddS) Nr?rrFr rs ) rrmaxrSrrurGsplitrr)rr?rHrrrrrs z_PlistWriter.write_bytescCs|rx|jd|jr"t|j}n|j}x@|D]8\}}t|tsR|jrJq0td|jd||j |q0W|j dn |jddS)Nrzkeys must be stringsrh) rrsorteditemsr+r,rrCrrr)rrkrrhrrrrr s    z_PlistWriter.write_dictcCs@|r2|jdx|D]}|j|qW|jdn |jddS)Narray)rrrr)rrrrrrrs    z_PlistWriter.write_arrayN)rrrTF) r"r#r$r'r7rrrrrrrrrrs % rcCsd }x|D]}|j|r dSq WxntjdftjdftjdffD]N\}}|j|sRq>x8|D]0}||jdj|}|dt||krXdSqXWq>WdS) N6xBBQQQi)_fpseekosSEEK_ENDreadrSrstructunpack _ref_size _read_ints_object_offsets _undefined_objects _read_objectOSError IndexErrorerrorrrt)rr0trailer offset_size num_objects top_objectoffset_table_offsetrrrr_s      z_BinaryPlistParser.parsecCsL|dkrH|jjddd@}d|>}dt|}tj||jj|dS|S)z$ return the size of the next object.rrrPrq)rr_BINARY_FORMATrr)rtokenLrwrWrArrr _get_sizexs  z_BinaryPlistParser._get_sizecsv|jj|tkr2tjd|tS sHt|krNttfddtd|DSdS)Nrqc3s&|]}tj||dVqdS)bigN)re from_bytes).0rY)r?sizerr sz0_BinaryPlistParser._read_ints..r) rrrrrrSrrrR)rnrr)r?rrrsz_BinaryPlistParser._read_intscCs|j||jS)N)rr)rrrrr _read_refssz_BinaryPlistParser._read_refsc sj|}|tk r|Sj|}jj|jjdd}|d@|d@}}|dkr^d}n|dkrnd}n||dkr~d }nl|dkrd }n\|d krtjjjd|>d |d kd}n0|dkrtj djjdd}n |dkrtj djjdd}n|dkrDtj djjdd}t j dddt j |d}n|dkrj |}jj|}t ||krxtjst|}n^|dkrΈj |}jj|} t | |krt| jd}n|dkrj |d}jj|} t | |krt| jd}n|dkrXj |}j|} g}|j|<|jfdd| Dn|d krj |}j|} j|} j}|j|<y2x,t| | D]\} } j| |j| <qWWntk rtYnXnt|j|<|S)!zx read the object by reference. May recursively read sub-objects (content of an array/dict/set) rrrNrF TrQrrrP)signed"z>frO#z>d3i)ZsecondsrPr`rzutf-16bec3s|]}j|VqdS)N)r)rx)rrrrsz2_BinaryPlistParser._read_object..)rrrrrrrerrrrfZ timedeltarrSrr}rrrextendr~ziprrC)rrefresultoffsettokenZtokenHrrArWr?Zobj_refsZkey_refskor)rrrs                          z_BinaryPlistParser._read_objectN) r"r#r$r8r'rrrrrrrrrrSs  rcCs0|dkr dS|dkrdS|d>d>r(dSdSdS) NrrrrrrOir)countrrr_count_to_sizes rc@s<eZdZddZddZddZddZd d Zd d Zd S)_BinaryPlistWritercCs||_||_||_dS)N)rrr)rr0r=r>rrrr'sz_BinaryPlistWriter.__init__c Csg|_i|_i|_|j|t|j}dg||_t||_t|j|_ |j j dx|jD]}|j |q\W|j |}|j j}t|}dt||}|j j tj|f|jd}|||j|||f} |j j tjd| dS)Nrsbplist00rq >5xBBBQQQ)r)_objlist _objtable _objidtable_flattenrSrrrr _ref_formatrr7 _write_object _getrefnumtellrpack) rrrobjrrrZ offset_formatZ sort_versionrrrrr7 s(          z_BinaryPlistWriter.writec Cs~t|tr"t||f|jkrZdSn8t|trHt|j|jf|jkrZdSnt||jkrZdSt|j }|j j |t|tr||jt||f<n0t|tr||jt|j|jf<n||jt|<t|t rPg}g}|j }|j rt|}xB|D]:\}}t|ts|jr qtd|j ||j |qWxLtj||D]}|j|q:Wn*t|ttfrzx|D]}|j|qfWdS)Nzkeys must be strings)r+_scalarsrrrr?idrrSrrTrrrrr,rrC itertoolschainrrr) rrZrefnumkeysvaluesrrvrrrrr7sB          z_BinaryPlistWriter._flattencCsNt|tr|jt||fSt|tr<|jt|j|jfS|jt|SdS)N)r+rrrrr?rr )rrrrrrgs   z_BinaryPlistWriter._getrefnumcCs|dkr"|jjtjd||Bn|dkrH|jjtjd|dBd|nh|dkrn|jjtjd|dBd|nB|dkr|jjtjd |dBd |n|jjtjd |dBd |dS)Nrz>Brrz>BBBrz>BBHrz>BBLz>BBQril)rr7rr)rr rrrr _write_sizeosz_BinaryPlistWriter._write_sizec sj|}jjj|<|dkr2jjdn|dkrJjjdn|dkrbjjdnt|trl|dkryjjtjdd|Wn tj k rt |dYnXn|d'krԈjjtjd d |n|d(krjjtjd d|nt|d)krjjtjdd|nR|d*kr8jjtjdd|n0|d+kr`jjd|j d dddnt |nxt|t rjjtjdd|nRt|t j r|t j dd d j}jjtjdd|nt|trjdt|jjj|jnt|ttfr0jdt|jj|nt|try|jd}jdt|Wn4tk r|jd}jdt|d YnXjj|nDt|ttfrfd!d"|D}t|}jd#|jjtjd$j|f|nt|trgg}}jr&t|j} n|j} xR| D]J\} } t| ts\jrTq4t d%|j!j| |j!j| q4Wt|}jd&|jjtjd$j|f|jjtjd$j|f|nt |dS),NFTrrz>Bqr(rrz>BBrz>BHr&rz>BLr'rz>BQrr)rz>Bdrirrrzutf-16berrcsg|]}j|qSr)r)rr)rrr sz4_BinaryPlistWriter._write_object..rrqzkeys must be stringsrrilll)"rrrrr7r+rerrrrto_bytesrrfZ total_secondsrr)rSr?rBrr,r[UnicodeEncodeErrorrrrrrrrrrCrT) rrr rAtZrefsrWZkeyRefsZvalRefsZ rootItemsrr%r)rrrs            $    "$z _BinaryPlistWriter._write_objectN) r"r#r$r'r7rrr)rrrrrrs -0rcCs|dddkS)Nrsbplist00r)rrrr_is_fmt_binarysr1)detectrwriterT)r:r;r<cCsn|dkrL|jd}|jdx:tjD]}|d|r&|d}Pq&Wtn t|d}|||d}|j|S)zRead a .plist file. 'fp' should be (readable) file object. Return the unpacked root object (which usually is a dictionary). Nrrr2r)r;r<)rr_FORMATSr$rr)r0r:r;r<rinfoPprrrr s     cCst|}t||||dS)zqRead a .plist file from a bytes object. Return the unpacked root object (which usually is a dictionary). )r:r;r<)rr )rr:r;r<r0rrrr sF)r:r=r>cCs:|tkrtd|ft|d|||d}|j|dS)zQWrite 'value' to a .plist file. 'fp' should be a (writable) file object. zUnsupported format: %rr3)r=r>N)r4rtr7)rr0r:r=r>r3rrrr s)r:r>r=cCs t}t|||||d|jS)z?Return a bytes object with the contents for a .plist file. )r:r>r=)rr r@)rr:r>r=r0rrrrs)rF)Er8__all__rUr contextlibrfenumiorr!rrerwarningsrZxml.parsers.expatrEnumr"rglobalsr3 __members__rrrcontextmanagerr1rrrrrrrcompilerrrGrDASCIIrbrjrlrxryrrrrtrrobjectrrrr,rerrBrrr1r r r4r r r rrrrr/sz          0    h&d!# S