3 _=\D@sddlmZmZddlZddlZddlZddlZddlmZddl m Z ddl m Z ddl Z ddlZddlmZddlmZddlmZdd lmZeZd ZGd d d eZGd ddeZGdddeZdS))absolute_importprint_functionN)Timeout)Thread)sleep)Status)API) TweepError)import_simplejsonz1.1c@seZdZd ddZddZddZdd Zd d Zd d ZddZ ddZ ddZ ddZ ddZ ddZddZddZddZdS)!StreamListenerNcCs|pt|_dS)N)rapi)selfr rh/private/var/folders/47/550316q90kl84vt_jn5ctz8chwmm0c/T/pip-install-yoigbb1v/tweepy/tweepy/streaming.py__init__!szStreamListener.__init__cCsdS)zCalled once connected to streaming server. This will be invoked once a successful response is received from the server. Allows the listener to perform some work prior to entering the read loop. Nr)r rrr on_connect$szStreamListener.on_connectcCsbtj|}d|kr6tj|j|}|j|dkr2dSn(d|krh|dd}|j|d|ddkrfdSnd|krtj|j|}|j|dkrdSnd|krtj|j|}|j|dkrdSnd |kr|j |d dkrdSnd |kr|j |d d dkr^dSnZd |kr(|j |d dkr^dSn6d |krL|j |d dkr^dSnt jdt|dS)zCalled when raw data is received from connection. Override this method if you wish to manually handle the stream data. Return False to stop stream and close connection. Zin_reply_to_status_idFdeletestatusiduser_ideventZdirect_messagefriendslimittrack disconnectwarningzUnknown message type: N)jsonloadsrparser on_status on_deleteon_eventon_direct_message on_friendson_limit on_disconnect on_warningloggingerrorstr)r Zraw_datadatarrrrron_data-s<     zStreamListener.on_datacCsdS)z Called when a keep-alive arrivedNr)r rrr keep_aliveTszStreamListener.keep_alivecCsdS)z Called when a new status arrivesNr)r rrrrrXszStreamListener.on_statuscCsdS)z*Called when an unhandled exception occurs.Nr)r exceptionrrr on_exception\szStreamListener.on_exceptioncCsdS)z0Called when a delete notice arrives for a statusNr)r Z status_idrrrrr `szStreamListener.on_deletecCsdS)zCalled when a new event arrivesNr)r rrrrr!dszStreamListener.on_eventcCsdS)z(Called when a new direct message arrivesNr)r rrrrr"hsz StreamListener.on_direct_messagecCsdS)z]Called when a friends list arrives. friends is a list that contains user_id Nr)r rrrrr#lszStreamListener.on_friendscCsdS)z'Called when a limitation notice arrivesNr)r rrrrr$sszStreamListener.on_limitcCsdS)z-Called when a non-200 status code is returnedFr)r status_coderrron_errorwszStreamListener.on_errorcCsdS)z'Called when stream connection times outNr)r rrr on_timeout{szStreamListener.on_timeoutcCsdS)zCalled when twitter sends a disconnect notice Disconnect codes are listed here: https://dev.twitter.com/docs/streaming-apis/messages#Disconnect_messages_disconnect Nr)r noticerrrr%szStreamListener.on_disconnectcCsdS)z3Called when a disconnection warning message arrivesNr)r r2rrrr&szStreamListener.on_warning)N)__name__ __module__ __qualname__rrr+r,rr.r r!r"r#r$r0r1r%r&rrrrr s  'r c@s<eZdZdZd ddZddZejdfdd Zd d Z d S) ReadBufferaBuffer data from the response in a smarter way than httplib/requests can. Tweets are roughly in the 2-12kb range, averaging around 3kb. Requests/urllib3/httplib/socket all use socket.read, which blocks until enough data is returned. On some systems (eg google appengine), socket reads are quite slow. To combat this latency we can read big chunks, but the blocking part means we won't get results until enough tweets have arrived. That may not be a big deal for high throughput systems. For low throughput systems we don't want to sacrafice latency, so we use small chunks so it can read the length and the tweet in 2 read calls. utf-8cCs"||_tjd|_||_||_dS)N)_streamsixb_buffer _chunk_size _encoding)r stream chunk_sizeencodingrrrrs zReadBuffer.__init__cCs\xP|jjsPt|j|kr"|j|St|j|t|j}|j|jj|7_qWtj dS)Nr8) r9closedlenr<_popmaxr=readr:r;)r lengthread_lenrrrrHs   zReadBuffer.read_len cCsfd}xV|jjsZ|jj||}|dkr6|j|t|St|j}|j|jj|j7_qWtj dS)zRead the data stream until a given separator is found (default ) :param sep: Separator to read until. Must by of the bytes type (str in python 2, bytes in python 3) :return: The str of the data read until sep rr8) r9rBr<findrDrCrFr=r:r;)r sepstartlocrrr read_lines  zReadBuffer.read_linecCs*|jd|}|j|d|_|j|jS)N)r<decoder>)r rGrrrrrDszReadBuffer._popN)r7) r3r4r5__doc__rrHr:r;rNrDrrrrr6s   r6c@seZdZddZddZddZddZd d Zd d Zd dZ d!ddZ d"ddZ d#ddZ d$ddZ d%ddZd&ddZdd ZdS)'StreamcKs||_||_d|_|jdd|_|jd|_|jdd|_|jdd|_|jd d |_|jd d |_ |jd d|_ |jdd|_ |jdd|_ t |_|jdpi|_|jd|_|j|_|j |_|jd|_|jdd|_dS)NFtimeoutgr@ retry_count retry_timeg@Z retry_420gN@retry_time_capgt@ snooze_timeg?snooze_time_capr@iverifyTheadersproxieshostzstream.twitter.com)authlistenerrunninggetrSrTretry_time_startretry_420_startrVsnooze_time_steprXr@rZrr r[ new_sessionbodyrUrWr\r])r r^r_optionsrrrrs(  zStream.__init__cCs tj|_|j|j_d|j_dS)N)requestsSessionsessionr[params)r rrrres  zStream.new_sessioncCsd|j|jf}d}d}d}x|jr|jdk r>||jkr>Py|jj}|jjd||j|j d||j |j d}|j dkr|j j|j dkrP|d7}|j d krt|j|j|_t|jt|jd |j|_n(d}|j|_|j|_|j j|j|Wq ttjfk r}zzt|tjrF|jo8d t|jdksFt j!}P|j j"dkrXP|jdkrfPt|jt|j|j|j#|_WYdd}~Xq t$k r}zt j!}PWYdd}~Xq Xq Wd|_|r|j%|j&|r|j j'|dt(j)|dS) Nz https://%s%srPOSTT)r*rSr?r^rZr\Fiz timed out)*r]urlr`rTr^Z apply_authrjrequestrfrSrZr\r/r_r0rErcrUrminrVrbrdrWr _read_looprsslSSLError isinstanceargsr)sysexc_infor1rX Exceptioncloserer.r:reraise)r rpZ error_counterrespryr^excrrr_runsn               z Stream._runcCs|jj|dkrd|_dS)NF)r_r+r`)r r*rrr_data.sz Stream._datac Cs|jjddd}tjd|}|dk r0|jd}nd}t|j|j|d}x|jr|jj rd}xP|jj s|j }|rz|j n|}|s|j j q^|jrt|}Pq^td q^W|j|} |jrH| rH|j| qHW|jj r|j|dS) Nz content-typer8)defaultzcharset=(?P\S*)enczutf-8)rArz(Expecting length, unexpected value found)r[raresearchgroupr6rawr@r`rBrNstripr_r,isdigitintr rHr on_closed) r r}charsetZ enc_searchrAbufrGlineZ stripped_lineZnext_status_objrrrrs2s,       zStream._read_loopcCs0d|_|r$t|jd|_|jjn|jdS)NT)target)r`rr_threadrL)r is_asyncrrr_startjs  z Stream._startcCsdS)z5 Called when the response has been closed by Twitter Nr)r r}rrrrrszStream.on_closedFNutf8cCsddi|j_|jrtddt|_d|_|r:||jjd<|rJ||jjd<|rZ||jjd<|rt|d krt|d d krtd d jd d|D|jjd<|rd j|j ||jjd<|j |dS)N delimitedrGz Stream object already connected!z /%s/user.jsonzuserstream.twitter.comstall_warningswithrepliesrz>Wrong number of locations points, it has to be a multiple of 4,cSsg|] }d|qS)z%.2fr).0lrrr sz%Stream.userstream.. locationsr) rjrkr`r STREAM_VERSIONrpr]rCjoinencoder)r rZ_withrrrrrArrr userstreamvs$     zStream.userstreamcCsHddi|j_|jrtddt|_|r:|jd|7_|j|dS)NrrGz Stream object already connected!z/%s/statuses/firehose.jsonz &count=%s)rjrkr`r rrpr)r countrrrrfirehoses  zStream.firehosecCs2ddi|j_|jrtddt|_|j|dS)NrrGz Stream object already connected!z/%s/statuses/retweet.json)rjrkr`r rrpr)r rrrrretweets   zStream.retweetcCs^ddi|j_|jrtddt|_|r@djtt||jjd<|rPd|jjd<|j |dS) NrrGz Stream object already connected!z/%s/statuses/sample.jsonrlanguagetruer) rjrkr`r rrprmapr)r)r r languagesrrrrsamples   z Stream.samplec Csi|_d|jjd<|jr tddt|_|rDdj|j||jd<|r^dj|j||jd<|rt |dkrt |d dkrtd djd d |D|jd <|r||jd<|rdjt t ||jd<|r|j||jd<ddi|j_ |j |dS)Nz!application/x-www-form-urlencodedz Content-typez Stream object already connected!z/%s/statuses/filter.jsonrfollowrrrz>Wrong number of locations points, it has to be a multiple of 4cSsg|] }d|qS)z%.4fr)rrrrrrsz!Stream.filter..rrr filter_levelrrG)rfrjr[r`r rrprrrCrr)rkr) r rrrrrrrArrrrfilters*    z Stream.filterusercCsxi|_|jrtddt|_djttj||jd<d|jd<|rN||jd<|r\||jd<|rj||jd <|j |dS) Nz Stream object already connected!z /%s/site.jsonrrrGrrrr) rfr`r rrprrr: text_typer)r rrZwith_rrrrr sitestreams     zStream.sitestreamcCs|jdkrdSd|_dS)NF)r`)r rrrrs zStream.disconnect)FNNNNFr)NF)F)FNF)NNFNFNrN)FrFF)r3r4r5rrerrrsrrrrrrrrrrrrrrRs,"G8     rR) __future__rrr'rrhrxZrequests.exceptionsr threadingrtimerr:rtZ tweepy.modelsrZ tweepy.apirZ tweepy.errorr Z tweepy.utilsr rrobjectr r6rRrrrrs$       m2