12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829 |
- #!/usr/bin/env python
- #
- # vim: sw=2 ts=2 sts=2
- #
- # Copyright 2007 The Python-Twitter Developers
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- '''A library that provides a Python interface to the Twitter API'''
- __author__ = 'python-twitter@googlegroups.com'
- __version__ = '1.0.1'
- import calendar
- import datetime
- import httplib
- import os
- import rfc822
- import sys
- import tempfile
- import textwrap
- import time
- import urllib
- import urllib2
- import urlparse
- import gzip
- import StringIO
- try:
- # Python >= 2.6
- import json as simplejson
- except ImportError:
- try:
- # Python < 2.6
- import simplejson
- except ImportError:
- try:
- # Google App Engine
- from django.utils import simplejson
- except ImportError:
- raise ImportError, "Unable to load a json library"
- # parse_qsl moved to urlparse module in v2.6
- try:
- from urlparse import parse_qsl, parse_qs
- except ImportError:
- from cgi import parse_qsl, parse_qs
- try:
- from hashlib import md5
- except ImportError:
- from md5 import md5
- import oauth2 as oauth
- CHARACTER_LIMIT = 140
- # A singleton representing a lazily instantiated FileCache.
- DEFAULT_CACHE = object()
- class TwitterError(Exception):
- '''Base class for Twitter errors'''
- @property
- def message(self):
- '''Returns the first argument used to construct this error.'''
- return self.args[0]
- class Status(object):
- '''A class representing the Status structure used by the twitter API.
- The Status structure exposes the following properties:
- status.created_at
- status.created_at_in_seconds # read only
- status.favorited
- status.favorite_count
- status.in_reply_to_screen_name
- status.in_reply_to_user_id
- status.in_reply_to_status_id
- status.truncated
- status.source
- status.id
- status.text
- status.location
- status.relative_created_at # read only
- status.user
- status.urls
- status.user_mentions
- status.hashtags
- status.geo
- status.place
- status.coordinates
- status.contributors
- '''
- def __init__(self,
- created_at=None,
- favorited=None,
- favorite_count=None,
- id=None,
- text=None,
- location=None,
- user=None,
- in_reply_to_screen_name=None,
- in_reply_to_user_id=None,
- in_reply_to_status_id=None,
- truncated=None,
- source=None,
- now=None,
- urls=None,
- user_mentions=None,
- hashtags=None,
- media=None,
- geo=None,
- place=None,
- coordinates=None,
- contributors=None,
- retweeted=None,
- retweeted_status=None,
- current_user_retweet=None,
- retweet_count=None,
- possibly_sensitive=None,
- scopes=None,
- withheld_copyright=None,
- withheld_in_countries=None,
- withheld_scope=None):
- '''An object to hold a Twitter status message.
- This class is normally instantiated by the twitter.Api class and
- returned in a sequence.
- Note: Dates are posted in the form "Sat Jan 27 04:17:38 +0000 2007"
- Args:
- created_at:
- The time this status message was posted. [Optional]
- favorited:
- Whether this is a favorite of the authenticated user. [Optional]
- favorite_count:
- Number of times this status message has been favorited. [Optional]
- id:
- The unique id of this status message. [Optional]
- text:
- The text of this status message. [Optional]
- location:
- the geolocation string associated with this message. [Optional]
- relative_created_at:
- A human readable string representing the posting time. [Optional]
- user:
- A twitter.User instance representing the person posting the
- message. [Optional]
- now:
- The current time, if the client chooses to set it.
- Defaults to the wall clock time. [Optional]
- urls:
- user_mentions:
- hashtags:
- geo:
- place:
- coordinates:
- contributors:
- retweeted:
- retweeted_status:
- current_user_retweet:
- retweet_count:
- possibly_sensitive:
- scopes:
- withheld_copyright:
- withheld_in_countries:
- withheld_scope:
- '''
- self.created_at = created_at
- self.favorited = favorited
- self.favorite_count = favorite_count
- self.id = id
- self.text = text
- self.location = location
- self.user = user
- self.now = now
- self.in_reply_to_screen_name = in_reply_to_screen_name
- self.in_reply_to_user_id = in_reply_to_user_id
- self.in_reply_to_status_id = in_reply_to_status_id
- self.truncated = truncated
- self.retweeted = retweeted
- self.source = source
- self.urls = urls
- self.user_mentions = user_mentions
- self.hashtags = hashtags
- self.media = media
- self.geo = geo
- self.place = place
- self.coordinates = coordinates
- self.contributors = contributors
- self.retweeted_status = retweeted_status
- self.current_user_retweet = current_user_retweet
- self.retweet_count = retweet_count
- self.possibly_sensitive = possibly_sensitive
- self.scopes = scopes
- self.withheld_copyright = withheld_copyright
- self.withheld_in_countries = withheld_in_countries
- self.withheld_scope = withheld_scope
- def GetCreatedAt(self):
- '''Get the time this status message was posted.
- Returns:
- The time this status message was posted
- '''
- return self._created_at
- def SetCreatedAt(self, created_at):
- '''Set the time this status message was posted.
- Args:
- created_at:
- The time this status message was created
- '''
- self._created_at = created_at
- created_at = property(GetCreatedAt, SetCreatedAt,
- doc='The time this status message was posted.')
- def GetCreatedAtInSeconds(self):
- '''Get the time this status message was posted, in seconds since the epoch.
- Returns:
- The time this status message was posted, in seconds since the epoch.
- '''
- return calendar.timegm(rfc822.parsedate(self.created_at))
- created_at_in_seconds = property(GetCreatedAtInSeconds,
- doc="The time this status message was "
- "posted, in seconds since the epoch")
- def GetFavorited(self):
- '''Get the favorited setting of this status message.
- Returns:
- True if this status message is favorited; False otherwise
- '''
- return self._favorited
- def SetFavorited(self, favorited):
- '''Set the favorited state of this status message.
- Args:
- favorited:
- boolean True/False favorited state of this status message
- '''
- self._favorited = favorited
- favorited = property(GetFavorited, SetFavorited,
- doc='The favorited state of this status message.')
- def GetFavoriteCount(self):
- '''Get the favorite count of this status message.
- Returns:
- number of times this status message has been favorited
- '''
- return self._favorite_count
- def SetFavoriteCount(self, favorite_count):
- '''Set the favorited state of this status message.
- Args:
- favorite_count:
- int number of favorites for this status message
- '''
- self._favorite_count = favorite_count
- favorite_count = property(GetFavoriteCount, SetFavoriteCount,
- doc='The number of favorites for this status message.')
- def GetId(self):
- '''Get the unique id of this status message.
- Returns:
- The unique id of this status message
- '''
- return self._id
- def SetId(self, id):
- '''Set the unique id of this status message.
- Args:
- id:
- The unique id of this status message
- '''
- self._id = id
- id = property(GetId, SetId,
- doc='The unique id of this status message.')
- def GetInReplyToScreenName(self):
- return self._in_reply_to_screen_name
- def SetInReplyToScreenName(self, in_reply_to_screen_name):
- self._in_reply_to_screen_name = in_reply_to_screen_name
- in_reply_to_screen_name = property(GetInReplyToScreenName, SetInReplyToScreenName,
- doc='')
- def GetInReplyToUserId(self):
- return self._in_reply_to_user_id
- def SetInReplyToUserId(self, in_reply_to_user_id):
- self._in_reply_to_user_id = in_reply_to_user_id
- in_reply_to_user_id = property(GetInReplyToUserId, SetInReplyToUserId,
- doc='')
- def GetInReplyToStatusId(self):
- return self._in_reply_to_status_id
- def SetInReplyToStatusId(self, in_reply_to_status_id):
- self._in_reply_to_status_id = in_reply_to_status_id
- in_reply_to_status_id = property(GetInReplyToStatusId, SetInReplyToStatusId,
- doc='')
- def GetTruncated(self):
- return self._truncated
- def SetTruncated(self, truncated):
- self._truncated = truncated
- truncated = property(GetTruncated, SetTruncated,
- doc='')
- def GetRetweeted(self):
- return self._retweeted
- def SetRetweeted(self, retweeted):
- self._retweeted = retweeted
- retweeted = property(GetRetweeted, SetRetweeted,
- doc='')
- def GetSource(self):
- return self._source
- def SetSource(self, source):
- self._source = source
- source = property(GetSource, SetSource,
- doc='')
- def GetText(self):
- '''Get the text of this status message.
- Returns:
- The text of this status message.
- '''
- return self._text
- def SetText(self, text):
- '''Set the text of this status message.
- Args:
- text:
- The text of this status message
- '''
- self._text = text
- text = property(GetText, SetText,
- doc='The text of this status message')
- def GetLocation(self):
- '''Get the geolocation associated with this status message
- Returns:
- The geolocation string of this status message.
- '''
- return self._location
- def SetLocation(self, location):
- '''Set the geolocation associated with this status message
- Args:
- location:
- The geolocation string of this status message
- '''
- self._location = location
- location = property(GetLocation, SetLocation,
- doc='The geolocation string of this status message')
- def GetRelativeCreatedAt(self):
- '''Get a human readable string representing the posting time
- Returns:
- A human readable string representing the posting time
- '''
- fudge = 1.25
- delta = long(self.now) - long(self.created_at_in_seconds)
- if delta < (1 * fudge):
- return 'about a second ago'
- elif delta < (60 * (1/fudge)):
- return 'about %d seconds ago' % (delta)
- elif delta < (60 * fudge):
- return 'about a minute ago'
- elif delta < (60 * 60 * (1/fudge)):
- return 'about %d minutes ago' % (delta / 60)
- elif delta < (60 * 60 * fudge) or delta / (60 * 60) == 1:
- return 'about an hour ago'
- elif delta < (60 * 60 * 24 * (1/fudge)):
- return 'about %d hours ago' % (delta / (60 * 60))
- elif delta < (60 * 60 * 24 * fudge) or delta / (60 * 60 * 24) == 1:
- return 'about a day ago'
- else:
- return 'about %d days ago' % (delta / (60 * 60 * 24))
- relative_created_at = property(GetRelativeCreatedAt,
- doc='Get a human readable string representing '
- 'the posting time')
- def GetUser(self):
- '''Get a twitter.User representing the entity posting this status message.
- Returns:
- A twitter.User representing the entity posting this status message
- '''
- return self._user
- def SetUser(self, user):
- '''Set a twitter.User representing the entity posting this status message.
- Args:
- user:
- A twitter.User representing the entity posting this status message
- '''
- self._user = user
- user = property(GetUser, SetUser,
- doc='A twitter.User representing the entity posting this '
- 'status message')
- def GetNow(self):
- '''Get the wallclock time for this status message.
- Used to calculate relative_created_at. Defaults to the time
- the object was instantiated.
- Returns:
- Whatever the status instance believes the current time to be,
- in seconds since the epoch.
- '''
- if self._now is None:
- self._now = time.time()
- return self._now
- def SetNow(self, now):
- '''Set the wallclock time for this status message.
- Used to calculate relative_created_at. Defaults to the time
- the object was instantiated.
- Args:
- now:
- The wallclock time for this instance.
- '''
- self._now = now
- now = property(GetNow, SetNow,
- doc='The wallclock time for this status instance.')
- def GetGeo(self):
- return self._geo
- def SetGeo(self, geo):
- self._geo = geo
- geo = property(GetGeo, SetGeo,
- doc='')
- def GetPlace(self):
- return self._place
- def SetPlace(self, place):
- self._place = place
- place = property(GetPlace, SetPlace,
- doc='')
- def GetCoordinates(self):
- return self._coordinates
- def SetCoordinates(self, coordinates):
- self._coordinates = coordinates
- coordinates = property(GetCoordinates, SetCoordinates,
- doc='')
- def GetContributors(self):
- return self._contributors
- def SetContributors(self, contributors):
- self._contributors = contributors
- contributors = property(GetContributors, SetContributors,
- doc='')
- def GetRetweeted_status(self):
- return self._retweeted_status
- def SetRetweeted_status(self, retweeted_status):
- self._retweeted_status = retweeted_status
- retweeted_status = property(GetRetweeted_status, SetRetweeted_status,
- doc='')
- def GetRetweetCount(self):
- return self._retweet_count
- def SetRetweetCount(self, retweet_count):
- self._retweet_count = retweet_count
- retweet_count = property(GetRetweetCount, SetRetweetCount,
- doc='')
- def GetCurrent_user_retweet(self):
- return self._current_user_retweet
- def SetCurrent_user_retweet(self, current_user_retweet):
- self._current_user_retweet = current_user_retweet
- current_user_retweet = property(GetCurrent_user_retweet, SetCurrent_user_retweet,
- doc='')
- def GetPossibly_sensitive(self):
- return self._possibly_sensitive
- def SetPossibly_sensitive(self, possibly_sensitive):
- self._possibly_sensitive = possibly_sensitive
- possibly_sensitive = property(GetPossibly_sensitive, SetPossibly_sensitive,
- doc='')
- def GetScopes(self):
- return self._scopes
- def SetScopes(self, scopes):
- self._scopes = scopes
- scopes = property(GetScopes, SetScopes, doc='')
- def GetWithheld_copyright(self):
- return self._withheld_copyright
- def SetWithheld_copyright(self, withheld_copyright):
- self._withheld_copyright = withheld_copyright
- withheld_copyright = property(GetWithheld_copyright, SetWithheld_copyright,
- doc='')
- def GetWithheld_in_countries(self):
- return self._withheld_in_countries
- def SetWithheld_in_countries(self, withheld_in_countries):
- self._withheld_in_countries = withheld_in_countries
- withheld_in_countries = property(GetWithheld_in_countries, SetWithheld_in_countries,
- doc='')
- def GetWithheld_scope(self):
- return self._withheld_scope
- def SetWithheld_scope(self, withheld_scope):
- self._withheld_scope = withheld_scope
- withheld_scope = property(GetWithheld_scope, SetWithheld_scope,
- doc='')
- def __ne__(self, other):
- return not self.__eq__(other)
- def __eq__(self, other):
- try:
- return other and \
- self.created_at == other.created_at and \
- self.id == other.id and \
- self.text == other.text and \
- self.location == other.location and \
- self.user == other.user and \
- self.in_reply_to_screen_name == other.in_reply_to_screen_name and \
- self.in_reply_to_user_id == other.in_reply_to_user_id and \
- self.in_reply_to_status_id == other.in_reply_to_status_id and \
- self.truncated == other.truncated and \
- self.retweeted == other.retweeted and \
- self.favorited == other.favorited and \
- self.favorite_count == other.favorite_count and \
- self.source == other.source and \
- self.geo == other.geo and \
- self.place == other.place and \
- self.coordinates == other.coordinates and \
- self.contributors == other.contributors and \
- self.retweeted_status == other.retweeted_status and \
- self.retweet_count == other.retweet_count and \
- self.current_user_retweet == other.current_user_retweet and \
- self.possibly_sensitive == other.possibly_sensitive and \
- self.scopes == other.scopes and \
- self.withheld_copyright == other.withheld_copyright and \
- self.withheld_in_countries == other.withheld_in_countries and \
- self.withheld_scope == other.withheld_scope
- except AttributeError:
- return False
- def __str__(self):
- '''A string representation of this twitter.Status instance.
- The return value is the same as the JSON string representation.
- Returns:
- A string representation of this twitter.Status instance.
- '''
- return self.AsJsonString()
- def AsJsonString(self):
- '''A JSON string representation of this twitter.Status instance.
- Returns:
- A JSON string representation of this twitter.Status instance
- '''
- return simplejson.dumps(self.AsDict(), sort_keys=True)
- def AsDict(self):
- '''A dict representation of this twitter.Status instance.
- The return value uses the same key names as the JSON representation.
- Return:
- A dict representing this twitter.Status instance
- '''
- data = {}
- if self.created_at:
- data['created_at'] = self.created_at
- if self.favorited:
- data['favorited'] = self.favorited
- if self.favorite_count:
- data['favorite_count'] = self.favorite_count
- if self.id:
- data['id'] = self.id
- if self.text:
- data['text'] = self.text
- if self.location:
- data['location'] = self.location
- if self.user:
- data['user'] = self.user.AsDict()
- if self.in_reply_to_screen_name:
- data['in_reply_to_screen_name'] = self.in_reply_to_screen_name
- if self.in_reply_to_user_id:
- data['in_reply_to_user_id'] = self.in_reply_to_user_id
- if self.in_reply_to_status_id:
- data['in_reply_to_status_id'] = self.in_reply_to_status_id
- if self.truncated is not None:
- data['truncated'] = self.truncated
- if self.retweeted is not None:
- data['retweeted'] = self.retweeted
- if self.favorited is not None:
- data['favorited'] = self.favorited
- if self.source:
- data['source'] = self.source
- if self.geo:
- data['geo'] = self.geo
- if self.place:
- data['place'] = self.place
- if self.coordinates:
- data['coordinates'] = self.coordinates
- if self.contributors:
- data['contributors'] = self.contributors
- if self.hashtags:
- data['hashtags'] = [h.text for h in self.hashtags]
- if self.retweeted_status:
- data['retweeted_status'] = self.retweeted_status.AsDict()
- if self.retweet_count:
- data['retweet_count'] = self.retweet_count
- if self.urls:
- data['urls'] = dict([(url.url, url.expanded_url) for url in self.urls])
- if self.user_mentions:
- data['user_mentions'] = [um.AsDict() for um in self.user_mentions]
- if self.current_user_retweet:
- data['current_user_retweet'] = self.current_user_retweet
- if self.possibly_sensitive:
- data['possibly_sensitive'] = self.possibly_sensitive
- if self.scopes:
- data['scopes'] = self.scopes
- if self.withheld_copyright:
- data['withheld_copyright'] = self.withheld_copyright
- if self.withheld_in_countries:
- data['withheld_in_countries'] = self.withheld_in_countries
- if self.withheld_scope:
- data['withheld_scope'] = self.withheld_scope
- return data
- @staticmethod
- def NewFromJsonDict(data):
- '''Create a new instance based on a JSON dict.
- Args:
- data: A JSON dict, as converted from the JSON in the twitter API
- Returns:
- A twitter.Status instance
- '''
- if 'user' in data:
- user = User.NewFromJsonDict(data['user'])
- else:
- user = None
- if 'retweeted_status' in data:
- retweeted_status = Status.NewFromJsonDict(data['retweeted_status'])
- else:
- retweeted_status = None
- if 'current_user_retweet' in data:
- current_user_retweet = data['current_user_retweet']['id']
- else:
- current_user_retweet = None
- urls = None
- user_mentions = None
- hashtags = None
- media = None
- if 'entities' in data:
- if 'urls' in data['entities']:
- urls = [Url.NewFromJsonDict(u) for u in data['entities']['urls']]
- if 'user_mentions' in data['entities']:
- user_mentions = [User.NewFromJsonDict(u) for u in data['entities']['user_mentions']]
- if 'hashtags' in data['entities']:
- hashtags = [Hashtag.NewFromJsonDict(h) for h in data['entities']['hashtags']]
- if 'media' in data['entities']:
- media = data['entities']['media']
- else:
- media = []
- return Status(created_at=data.get('created_at', None),
- favorited=data.get('favorited', None),
- favorite_count=data.get('favorite_count', None),
- id=data.get('id', None),
- text=data.get('text', None),
- location=data.get('location', None),
- in_reply_to_screen_name=data.get('in_reply_to_screen_name', None),
- in_reply_to_user_id=data.get('in_reply_to_user_id', None),
- in_reply_to_status_id=data.get('in_reply_to_status_id', None),
- truncated=data.get('truncated', None),
- retweeted=data.get('retweeted', None),
- source=data.get('source', None),
- user=user,
- urls=urls,
- user_mentions=user_mentions,
- hashtags=hashtags,
- media=media,
- geo=data.get('geo', None),
- place=data.get('place', None),
- coordinates=data.get('coordinates', None),
- contributors=data.get('contributors', None),
- retweeted_status=retweeted_status,
- current_user_retweet=current_user_retweet,
- retweet_count=data.get('retweet_count', None),
- possibly_sensitive=data.get('possibly_sensitive', None),
- scopes=data.get('scopes', None),
- withheld_copyright=data.get('withheld_copyright', None),
- withheld_in_countries=data.get('withheld_in_countries', None),
- withheld_scope=data.get('withheld_scope', None))
- class User(object):
- '''A class representing the User structure used by the twitter API.
- The User structure exposes the following properties:
- user.id
- user.name
- user.screen_name
- user.location
- user.description
- user.profile_image_url
- user.profile_background_tile
- user.profile_background_image_url
- user.profile_sidebar_fill_color
- user.profile_background_color
- user.profile_link_color
- user.profile_text_color
- user.protected
- user.utc_offset
- user.time_zone
- user.url
- user.status
- user.statuses_count
- user.followers_count
- user.friends_count
- user.favourites_count
- user.geo_enabled
- user.verified
- user.lang
- user.notifications
- user.contributors_enabled
- user.created_at
- user.listed_count
- '''
- def __init__(self,
- id=None,
- name=None,
- screen_name=None,
- location=None,
- description=None,
- profile_image_url=None,
- profile_background_tile=None,
- profile_background_image_url=None,
- profile_sidebar_fill_color=None,
- profile_background_color=None,
- profile_link_color=None,
- profile_text_color=None,
- protected=None,
- utc_offset=None,
- time_zone=None,
- followers_count=None,
- friends_count=None,
- statuses_count=None,
- favourites_count=None,
- url=None,
- status=None,
- geo_enabled=None,
- verified=None,
- lang=None,
- notifications=None,
- contributors_enabled=None,
- created_at=None,
- listed_count=None):
- self.id = id
- self.name = name
- self.screen_name = screen_name
- self.location = location
- self.description = description
- self.profile_image_url = profile_image_url
- self.profile_background_tile = profile_background_tile
- self.profile_background_image_url = profile_background_image_url
- self.profile_sidebar_fill_color = profile_sidebar_fill_color
- self.profile_background_color = profile_background_color
- self.profile_link_color = profile_link_color
- self.profile_text_color = profile_text_color
- self.protected = protected
- self.utc_offset = utc_offset
- self.time_zone = time_zone
- self.followers_count = followers_count
- self.friends_count = friends_count
- self.statuses_count = statuses_count
- self.favourites_count = favourites_count
- self.url = url
- self.status = status
- self.geo_enabled = geo_enabled
- self.verified = verified
- self.lang = lang
- self.notifications = notifications
- self.contributors_enabled = contributors_enabled
- self.created_at = created_at
- self.listed_count = listed_count
- def GetId(self):
- '''Get the unique id of this user.
- Returns:
- The unique id of this user
- '''
- return self._id
- def SetId(self, id):
- '''Set the unique id of this user.
- Args:
- id: The unique id of this user.
- '''
- self._id = id
- id = property(GetId, SetId,
- doc='The unique id of this user.')
- def GetName(self):
- '''Get the real name of this user.
- Returns:
- The real name of this user
- '''
- return self._name
- def SetName(self, name):
- '''Set the real name of this user.
- Args:
- name: The real name of this user
- '''
- self._name = name
- name = property(GetName, SetName,
- doc='The real name of this user.')
- def GetScreenName(self):
- '''Get the short twitter name of this user.
- Returns:
- The short twitter name of this user
- '''
- return self._screen_name
- def SetScreenName(self, screen_name):
- '''Set the short twitter name of this user.
- Args:
- screen_name: the short twitter name of this user
- '''
- self._screen_name = screen_name
- screen_name = property(GetScreenName, SetScreenName,
- doc='The short twitter name of this user.')
- def GetLocation(self):
- '''Get the geographic location of this user.
- Returns:
- The geographic location of this user
- '''
- return self._location
- def SetLocation(self, location):
- '''Set the geographic location of this user.
- Args:
- location: The geographic location of this user
- '''
- self._location = location
- location = property(GetLocation, SetLocation,
- doc='The geographic location of this user.')
- def GetDescription(self):
- '''Get the short text description of this user.
- Returns:
- The short text description of this user
- '''
- return self._description
- def SetDescription(self, description):
- '''Set the short text description of this user.
- Args:
- description: The short text description of this user
- '''
- self._description = description
- description = property(GetDescription, SetDescription,
- doc='The short text description of this user.')
- def GetUrl(self):
- '''Get the homepage url of this user.
- Returns:
- The homepage url of this user
- '''
- return self._url
- def SetUrl(self, url):
- '''Set the homepage url of this user.
- Args:
- url: The homepage url of this user
- '''
- self._url = url
- url = property(GetUrl, SetUrl,
- doc='The homepage url of this user.')
- def GetProfileImageUrl(self):
- '''Get the url of the thumbnail of this user.
- Returns:
- The url of the thumbnail of this user
- '''
- return self._profile_image_url
- def SetProfileImageUrl(self, profile_image_url):
- '''Set the url of the thumbnail of this user.
- Args:
- profile_image_url: The url of the thumbnail of this user
- '''
- self._profile_image_url = profile_image_url
- profile_image_url= property(GetProfileImageUrl, SetProfileImageUrl,
- doc='The url of the thumbnail of this user.')
- def GetProfileBackgroundTile(self):
- '''Boolean for whether to tile the profile background image.
- Returns:
- True if the background is to be tiled, False if not, None if unset.
- '''
- return self._profile_background_tile
- def SetProfileBackgroundTile(self, profile_background_tile):
- '''Set the boolean flag for whether to tile the profile background image.
- Args:
- profile_background_tile: Boolean flag for whether to tile or not.
- '''
- self._profile_background_tile = profile_background_tile
- profile_background_tile = property(GetProfileBackgroundTile, SetProfileBackgroundTile,
- doc='Boolean for whether to tile the background image.')
- def GetProfileBackgroundImageUrl(self):
- return self._profile_background_image_url
- def SetProfileBackgroundImageUrl(self, profile_background_image_url):
- self._profile_background_image_url = profile_background_image_url
- profile_background_image_url = property(GetProfileBackgroundImageUrl, SetProfileBackgroundImageUrl,
- doc='The url of the profile background of this user.')
- def GetProfileSidebarFillColor(self):
- return self._profile_sidebar_fill_color
- def SetProfileSidebarFillColor(self, profile_sidebar_fill_color):
- self._profile_sidebar_fill_color = profile_sidebar_fill_color
- profile_sidebar_fill_color = property(GetProfileSidebarFillColor, SetProfileSidebarFillColor)
- def GetProfileBackgroundColor(self):
- return self._profile_background_color
- def SetProfileBackgroundColor(self, profile_background_color):
- self._profile_background_color = profile_background_color
- profile_background_color = property(GetProfileBackgroundColor, SetProfileBackgroundColor)
- def GetProfileLinkColor(self):
- return self._profile_link_color
- def SetProfileLinkColor(self, profile_link_color):
- self._profile_link_color = profile_link_color
- profile_link_color = property(GetProfileLinkColor, SetProfileLinkColor)
- def GetProfileTextColor(self):
- return self._profile_text_color
- def SetProfileTextColor(self, profile_text_color):
- self._profile_text_color = profile_text_color
- profile_text_color = property(GetProfileTextColor, SetProfileTextColor)
- def GetProtected(self):
- return self._protected
- def SetProtected(self, protected):
- self._protected = protected
- protected = property(GetProtected, SetProtected)
- def GetUtcOffset(self):
- return self._utc_offset
- def SetUtcOffset(self, utc_offset):
- self._utc_offset = utc_offset
- utc_offset = property(GetUtcOffset, SetUtcOffset)
- def GetTimeZone(self):
- '''Returns the current time zone string for the user.
- Returns:
- The descriptive time zone string for the user.
- '''
- return self._time_zone
- def SetTimeZone(self, time_zone):
- '''Sets the user's time zone string.
- Args:
- time_zone:
- The descriptive time zone to assign for the user.
- '''
- self._time_zone = time_zone
- time_zone = property(GetTimeZone, SetTimeZone)
- def GetStatus(self):
- '''Get the latest twitter.Status of this user.
- Returns:
- The latest twitter.Status of this user
- '''
- return self._status
- def SetStatus(self, status):
- '''Set the latest twitter.Status of this user.
- Args:
- status:
- The latest twitter.Status of this user
- '''
- self._status = status
- status = property(GetStatus, SetStatus,
- doc='The latest twitter.Status of this user.')
- def GetFriendsCount(self):
- '''Get the friend count for this user.
- Returns:
- The number of users this user has befriended.
- '''
- return self._friends_count
- def SetFriendsCount(self, count):
- '''Set the friend count for this user.
- Args:
- count:
- The number of users this user has befriended.
- '''
- self._friends_count = count
- friends_count = property(GetFriendsCount, SetFriendsCount,
- doc='The number of friends for this user.')
- def GetListedCount(self):
- '''Get the listed count for this user.
- Returns:
- The number of lists this user belongs to.
- '''
- return self._listed_count
- def SetListedCount(self, count):
- '''Set the listed count for this user.
- Args:
- count:
- The number of lists this user belongs to.
- '''
- self._listed_count = count
- listed_count = property(GetListedCount, SetListedCount,
- doc='The number of lists this user belongs to.')
- def GetFollowersCount(self):
- '''Get the follower count for this user.
- Returns:
- The number of users following this user.
- '''
- return self._followers_count
- def SetFollowersCount(self, count):
- '''Set the follower count for this user.
- Args:
- count:
- The number of users following this user.
- '''
- self._followers_count = count
- followers_count = property(GetFollowersCount, SetFollowersCount,
- doc='The number of users following this user.')
- def GetStatusesCount(self):
- '''Get the number of status updates for this user.
- Returns:
- The number of status updates for this user.
- '''
- return self._statuses_count
- def SetStatusesCount(self, count):
- '''Set the status update count for this user.
- Args:
- count:
- The number of updates for this user.
- '''
- self._statuses_count = count
- statuses_count = property(GetStatusesCount, SetStatusesCount,
- doc='The number of updates for this user.')
- def GetFavouritesCount(self):
- '''Get the number of favourites for this user.
- Returns:
- The number of favourites for this user.
- '''
- return self._favourites_count
- def SetFavouritesCount(self, count):
- '''Set the favourite count for this user.
- Args:
- count:
- The number of favourites for this user.
- '''
- self._favourites_count = count
- favourites_count = property(GetFavouritesCount, SetFavouritesCount,
- doc='The number of favourites for this user.')
- def GetGeoEnabled(self):
- '''Get the setting of geo_enabled for this user.
- Returns:
- True/False if Geo tagging is enabled
- '''
- return self._geo_enabled
- def SetGeoEnabled(self, geo_enabled):
- '''Set the latest twitter.geo_enabled of this user.
- Args:
- geo_enabled:
- True/False if Geo tagging is to be enabled
- '''
- self._geo_enabled = geo_enabled
- geo_enabled = property(GetGeoEnabled, SetGeoEnabled,
- doc='The value of twitter.geo_enabled for this user.')
- def GetVerified(self):
- '''Get the setting of verified for this user.
- Returns:
- True/False if user is a verified account
- '''
- return self._verified
- def SetVerified(self, verified):
- '''Set twitter.verified for this user.
- Args:
- verified:
- True/False if user is a verified account
- '''
- self._verified = verified
- verified = property(GetVerified, SetVerified,
- doc='The value of twitter.verified for this user.')
- def GetLang(self):
- '''Get the setting of lang for this user.
- Returns:
- language code of the user
- '''
- return self._lang
- def SetLang(self, lang):
- '''Set twitter.lang for this user.
- Args:
- lang:
- language code for the user
- '''
- self._lang = lang
- lang = property(GetLang, SetLang,
- doc='The value of twitter.lang for this user.')
- def GetNotifications(self):
- '''Get the setting of notifications for this user.
- Returns:
- True/False for the notifications setting of the user
- '''
- return self._notifications
- def SetNotifications(self, notifications):
- '''Set twitter.notifications for this user.
- Args:
- notifications:
- True/False notifications setting for the user
- '''
- self._notifications = notifications
- notifications = property(GetNotifications, SetNotifications,
- doc='The value of twitter.notifications for this user.')
- def GetContributorsEnabled(self):
- '''Get the setting of contributors_enabled for this user.
- Returns:
- True/False contributors_enabled of the user
- '''
- return self._contributors_enabled
- def SetContributorsEnabled(self, contributors_enabled):
- '''Set twitter.contributors_enabled for this user.
- Args:
- contributors_enabled:
- True/False contributors_enabled setting for the user
- '''
- self._contributors_enabled = contributors_enabled
- contributors_enabled = property(GetContributorsEnabled, SetContributorsEnabled,
- doc='The value of twitter.contributors_enabled for this user.')
- def GetCreatedAt(self):
- '''Get the setting of created_at for this user.
- Returns:
- created_at value of the user
- '''
- return self._created_at
- def SetCreatedAt(self, created_at):
- '''Set twitter.created_at for this user.
- Args:
- created_at:
- created_at value for the user
- '''
- self._created_at = created_at
- created_at = property(GetCreatedAt, SetCreatedAt,
- doc='The value of twitter.created_at for this user.')
- def __ne__(self, other):
- return not self.__eq__(other)
- def __eq__(self, other):
- try:
- return other and \
- self.id == other.id and \
- self.name == other.name and \
- self.screen_name == other.screen_name and \
- self.location == other.location and \
- self.description == other.description and \
- self.profile_image_url == other.profile_image_url and \
- self.profile_background_tile == other.profile_background_tile and \
- self.profile_background_image_url == other.profile_background_image_url and \
- self.profile_sidebar_fill_color == other.profile_sidebar_fill_color and \
- self.profile_background_color == other.profile_background_color and \
- self.profile_link_color == other.profile_link_color and \
- self.profile_text_color == other.profile_text_color and \
- self.protected == other.protected and \
- self.utc_offset == other.utc_offset and \
- self.time_zone == other.time_zone and \
- self.url == other.url and \
- self.statuses_count == other.statuses_count and \
- self.followers_count == other.followers_count and \
- self.favourites_count == other.favourites_count and \
- self.friends_count == other.friends_count and \
- self.status == other.status and \
- self.geo_enabled == other.geo_enabled and \
- self.verified == other.verified and \
- self.lang == other.lang and \
- self.notifications == other.notifications and \
- self.contributors_enabled == other.contributors_enabled and \
- self.created_at == other.created_at and \
- self.listed_count == other.listed_count
- except AttributeError:
- return False
- def __str__(self):
- '''A string representation of this twitter.User instance.
- The return value is the same as the JSON string representation.
- Returns:
- A string representation of this twitter.User instance.
- '''
- return self.AsJsonString()
- def AsJsonString(self):
- '''A JSON string representation of this twitter.User instance.
- Returns:
- A JSON string representation of this twitter.User instance
- '''
- return simplejson.dumps(self.AsDict(), sort_keys=True)
- def AsDict(self):
- '''A dict representation of this twitter.User instance.
- The return value uses the same key names as the JSON representation.
- Return:
- A dict representing this twitter.User instance
- '''
- data = {}
- if self.id:
- data['id'] = self.id
- if self.name:
- data['name'] = self.name
- if self.screen_name:
- data['screen_name'] = self.screen_name
- if self.location:
- data['location'] = self.location
- if self.description:
- data['description'] = self.description
- if self.profile_image_url:
- data['profile_image_url'] = self.profile_image_url
- if self.profile_background_tile is not None:
- data['profile_background_tile'] = self.profile_background_tile
- if self.profile_background_image_url:
- data['profile_sidebar_fill_color'] = self.profile_background_image_url
- if self.profile_background_color:
- data['profile_background_color'] = self.profile_background_color
- if self.profile_link_color:
- data['profile_link_color'] = self.profile_link_color
- if self.profile_text_color:
- data['profile_text_color'] = self.profile_text_color
- if self.protected is not None:
- data['protected'] = self.protected
- if self.utc_offset:
- data['utc_offset'] = self.utc_offset
- if self.time_zone:
- data['time_zone'] = self.time_zone
- if self.url:
- data['url'] = self.url
- if self.status:
- data['status'] = self.status.AsDict()
- if self.friends_count:
- data['friends_count'] = self.friends_count
- if self.followers_count:
- data['followers_count'] = self.followers_count
- if self.statuses_count:
- data['statuses_count'] = self.statuses_count
- if self.favourites_count:
- data['favourites_count'] = self.favourites_count
- if self.geo_enabled:
- data['geo_enabled'] = self.geo_enabled
- if self.verified:
- data['verified'] = self.verified
- if self.lang:
- data['lang'] = self.lang
- if self.notifications:
- data['notifications'] = self.notifications
- if self.contributors_enabled:
- data['contributors_enabled'] = self.contributors_enabled
- if self.created_at:
- data['created_at'] = self.created_at
- if self.listed_count:
- data['listed_count'] = self.listed_count
- return data
- @staticmethod
- def NewFromJsonDict(data):
- '''Create a new instance based on a JSON dict.
- Args:
- data:
- A JSON dict, as converted from the JSON in the twitter API
- Returns:
- A twitter.User instance
- '''
- if 'status' in data:
- status = Status.NewFromJsonDict(data['status'])
- else:
- status = None
- return User(id=data.get('id', None),
- name=data.get('name', None),
- screen_name=data.get('screen_name', None),
- location=data.get('location', None),
- description=data.get('description', None),
- statuses_count=data.get('statuses_count', None),
- followers_count=data.get('followers_count', None),
- favourites_count=data.get('favourites_count', None),
- friends_count=data.get('friends_count', None),
- profile_image_url=data.get('profile_image_url_https', data.get('profile_image_url', None)),
- profile_background_tile = data.get('profile_background_tile', None),
- profile_background_image_url = data.get('profile_background_image_url', None),
- profile_sidebar_fill_color = data.get('profile_sidebar_fill_color', None),
- profile_background_color = data.get('profile_background_color', None),
- profile_link_color = data.get('profile_link_color', None),
- profile_text_color = data.get('profile_text_color', None),
- protected = data.get('protected', None),
- utc_offset = data.get('utc_offset', None),
- time_zone = data.get('time_zone', None),
- url=data.get('url', None),
- status=status,
- geo_enabled=data.get('geo_enabled', None),
- verified=data.get('verified', None),
- lang=data.get('lang', None),
- notifications=data.get('notifications', None),
- contributors_enabled=data.get('contributors_enabled', None),
- created_at=data.get('created_at', None),
- listed_count=data.get('listed_count', None))
- class List(object):
- '''A class representing the List structure used by the twitter API.
- The List structure exposes the following properties:
- list.id
- list.name
- list.slug
- list.description
- list.full_name
- list.mode
- list.uri
- list.member_count
- list.subscriber_count
- list.following
- '''
- def __init__(self,
- id=None,
- name=None,
- slug=None,
- description=None,
- full_name=None,
- mode=None,
- uri=None,
- member_count=None,
- subscriber_count=None,
- following=None,
- user=None):
- self.id = id
- self.name = name
- self.slug = slug
- self.description = description
- self.full_name = full_name
- self.mode = mode
- self.uri = uri
- self.member_count = member_count
- self.subscriber_count = subscriber_count
- self.following = following
- self.user = user
- def GetId(self):
- '''Get the unique id of this list.
- Returns:
- The unique id of this list
- '''
- return self._id
- def SetId(self, id):
- '''Set the unique id of this list.
- Args:
- id:
- The unique id of this list.
- '''
- self._id = id
- id = property(GetId, SetId,
- doc='The unique id of this list.')
- def GetName(self):
- '''Get the real name of this list.
- Returns:
- The real name of this list
- '''
- return self._name
- def SetName(self, name):
- '''Set the real name of this list.
- Args:
- name:
- The real name of this list
- '''
- self._name = name
- name = property(GetName, SetName,
- doc='The real name of this list.')
- def GetSlug(self):
- '''Get the slug of this list.
- Returns:
- The slug of this list
- '''
- return self._slug
- def SetSlug(self, slug):
- '''Set the slug of this list.
- Args:
- slug:
- The slug of this list.
- '''
- self._slug = slug
- slug = property(GetSlug, SetSlug,
- doc='The slug of this list.')
- def GetDescription(self):
- '''Get the description of this list.
- Returns:
- The description of this list
- '''
- return self._description
- def SetDescription(self, description):
- '''Set the description of this list.
- Args:
- description:
- The description of this list.
- '''
- self._description = description
- description = property(GetDescription, SetDescription,
- doc='The description of this list.')
- def GetFull_name(self):
- '''Get the full_name of this list.
- Returns:
- The full_name of this list
- '''
- return self._full_name
- def SetFull_name(self, full_name):
- '''Set the full_name of this list.
- Args:
- full_name:
- The full_name of this list.
- '''
- self._full_name = full_name
- full_name = property(GetFull_name, SetFull_name,
- doc='The full_name of this list.')
- def GetMode(self):
- '''Get the mode of this list.
- Returns:
- The mode of this list
- '''
- return self._mode
- def SetMode(self, mode):
- '''Set the mode of this list.
- Args:
- mode:
- The mode of this list.
- '''
- self._mode = mode
- mode = property(GetMode, SetMode,
- doc='The mode of this list.')
- def GetUri(self):
- '''Get the uri of this list.
- Returns:
- The uri of this list
- '''
- return self._uri
- def SetUri(self, uri):
- '''Set the uri of this list.
- Args:
- uri:
- The uri of this list.
- '''
- self._uri = uri
- uri = property(GetUri, SetUri,
- doc='The uri of this list.')
- def GetMember_count(self):
- '''Get the member_count of this list.
- Returns:
- The member_count of this list
- '''
- return self._member_count
- def SetMember_count(self, member_count):
- '''Set the member_count of this list.
- Args:
- member_count:
- The member_count of this list.
- '''
- self._member_count = member_count
- member_count = property(GetMember_count, SetMember_count,
- doc='The member_count of this list.')
- def GetSubscriber_count(self):
- '''Get the subscriber_count of this list.
- Returns:
- The subscriber_count of this list
- '''
- return self._subscriber_count
- def SetSubscriber_count(self, subscriber_count):
- '''Set the subscriber_count of this list.
- Args:
- subscriber_count:
- The subscriber_count of this list.
- '''
- self._subscriber_count = subscriber_count
- subscriber_count = property(GetSubscriber_count, SetSubscriber_count,
- doc='The subscriber_count of this list.')
- def GetFollowing(self):
- '''Get the following status of this list.
- Returns:
- The following status of this list
- '''
- return self._following
- def SetFollowing(self, following):
- '''Set the following status of this list.
- Args:
- following:
- The following of this list.
- '''
- self._following = following
- following = property(GetFollowing, SetFollowing,
- doc='The following status of this list.')
- def GetUser(self):
- '''Get the user of this list.
- Returns:
- The owner of this list
- '''
- return self._user
- def SetUser(self, user):
- '''Set the user of this list.
- Args:
- user:
- The owner of this list.
- '''
- self._user = user
- user = property(GetUser, SetUser,
- doc='The owner of this list.')
- def __ne__(self, other):
- return not self.__eq__(other)
- def __eq__(self, other):
- try:
- return other and \
- self.id == other.id and \
- self.name == other.name and \
- self.slug == other.slug and \
- self.description == other.description and \
- self.full_name == other.full_name and \
- self.mode == other.mode and \
- self.uri == other.uri and \
- self.member_count == other.member_count and \
- self.subscriber_count == other.subscriber_count and \
- self.following == other.following and \
- self.user == other.user
- except AttributeError:
- return False
- def __str__(self):
- '''A string representation of this twitter.List instance.
- The return value is the same as the JSON string representation.
- Returns:
- A string representation of this twitter.List instance.
- '''
- return self.AsJsonString()
- def AsJsonString(self):
- '''A JSON string representation of this twitter.List instance.
- Returns:
- A JSON string representation of this twitter.List instance
- '''
- return simplejson.dumps(self.AsDict(), sort_keys=True)
- def AsDict(self):
- '''A dict representation of this twitter.List instance.
- The return value uses the same key names as the JSON representation.
- Return:
- A dict representing this twitter.List instance
- '''
- data = {}
- if self.id:
- data['id'] = self.id
- if self.name:
- data['name'] = self.name
- if self.slug:
- data['slug'] = self.slug
- if self.description:
- data['description'] = self.description
- if self.full_name:
- data['full_name'] = self.full_name
- if self.mode:
- data['mode'] = self.mode
- if self.uri:
- data['uri'] = self.uri
- if self.member_count is not None:
- data['member_count'] = self.member_count
- if self.subscriber_count is not None:
- data['subscriber_count'] = self.subscriber_count
- if self.following is not None:
- data['following'] = self.following
- if self.user is not None:
- data['user'] = self.user.AsDict()
- return data
- @staticmethod
- def NewFromJsonDict(data):
- '''Create a new instance based on a JSON dict.
- Args:
- data:
- A JSON dict, as converted from the JSON in the twitter API
- Returns:
- A twitter.List instance
- '''
- if 'user' in data:
- user = User.NewFromJsonDict(data['user'])
- else:
- user = None
- return List(id=data.get('id', None),
- name=data.get('name', None),
- slug=data.get('slug', None),
- description=data.get('description', None),
- full_name=data.get('full_name', None),
- mode=data.get('mode', None),
- uri=data.get('uri', None),
- member_count=data.get('member_count', None),
- subscriber_count=data.get('subscriber_count', None),
- following=data.get('following', None),
- user=user)
- class DirectMessage(object):
- '''A class representing the DirectMessage structure used by the twitter API.
- The DirectMessage structure exposes the following properties:
- direct_message.id
- direct_message.created_at
- direct_message.created_at_in_seconds # read only
- direct_message.sender_id
- direct_message.sender_screen_name
- direct_message.recipient_id
- direct_message.recipient_screen_name
- direct_message.text
- '''
- def __init__(self,
- id=None,
- created_at=None,
- sender_id=None,
- sender_screen_name=None,
- recipient_id=None,
- recipient_screen_name=None,
- text=None):
- '''An object to hold a Twitter direct message.
- This class is normally instantiated by the twitter.Api class and
- returned in a sequence.
- Note: Dates are posted in the form "Sat Jan 27 04:17:38 +0000 2007"
- Args:
- id:
- The unique id of this direct message. [Optional]
- created_at:
- The time this direct message was posted. [Optional]
- sender_id:
- The id of the twitter user that sent this message. [Optional]
- sender_screen_name:
- The name of the twitter user that sent this message. [Optional]
- recipient_id:
- The id of the twitter that received this message. [Optional]
- recipient_screen_name:
- The name of the twitter that received this message. [Optional]
- text:
- The text of this direct message. [Optional]
- '''
- self.id = id
- self.created_at = created_at
- self.sender_id = sender_id
- self.sender_screen_name = sender_screen_name
- self.recipient_id = recipient_id
- self.recipient_screen_name = recipient_screen_name
- self.text = text
- def GetId(self):
- '''Get the unique id of this direct message.
- Returns:
- The unique id of this direct message
- '''
- return self._id
- def SetId(self, id):
- '''Set the unique id of this direct message.
- Args:
- id:
- The unique id of this direct message
- '''
- self._id = id
- id = property(GetId, SetId,
- doc='The unique id of this direct message.')
- def GetCreatedAt(self):
- '''Get the time this direct message was posted.
- Returns:
- The time this direct message was posted
- '''
- return self._created_at
- def SetCreatedAt(self, created_at):
- '''Set the time this direct message was posted.
- Args:
- created_at:
- The time this direct message was created
- '''
- self._created_at = created_at
- created_at = property(GetCreatedAt, SetCreatedAt,
- doc='The time this direct message was posted.')
- def GetCreatedAtInSeconds(self):
- '''Get the time this direct message was posted, in seconds since the epoch.
- Returns:
- The time this direct message was posted, in seconds since the epoch.
- '''
- return calendar.timegm(rfc822.parsedate(self.created_at))
- created_at_in_seconds = property(GetCreatedAtInSeconds,
- doc="The time this direct message was "
- "posted, in seconds since the epoch")
- def GetSenderId(self):
- '''Get the unique sender id of this direct message.
- Returns:
- The unique sender id of this direct message
- '''
- return self._sender_id
- def SetSenderId(self, sender_id):
- '''Set the unique sender id of this direct message.
- Args:
- sender_id:
- The unique sender id of this direct message
- '''
- self._sender_id = sender_id
- sender_id = property(GetSenderId, SetSenderId,
- doc='The unique sender id of this direct message.')
- def GetSenderScreenName(self):
- '''Get the unique sender screen name of this direct message.
- Returns:
- The unique sender screen name of this direct message
- '''
- return self._sender_screen_name
- def SetSenderScreenName(self, sender_screen_name):
- '''Set the unique sender screen name of this direct message.
- Args:
- sender_screen_name:
- The unique sender screen name of this direct message
- '''
- self._sender_screen_name = sender_screen_name
- sender_screen_name = property(GetSenderScreenName, SetSenderScreenName,
- doc='The unique sender screen name of this direct message.')
- def GetRecipientId(self):
- '''Get the unique recipient id of this direct message.
- Returns:
- The unique recipient id of this direct message
- '''
- return self._recipient_id
- def SetRecipientId(self, recipient_id):
- '''Set the unique recipient id of this direct message.
- Args:
- recipient_id:
- The unique recipient id of this direct message
- '''
- self._recipient_id = recipient_id
- recipient_id = property(GetRecipientId, SetRecipientId,
- doc='The unique recipient id of this direct message.')
- def GetRecipientScreenName(self):
- '''Get the unique recipient screen name of this direct message.
- Returns:
- The unique recipient screen name of this direct message
- '''
- return self._recipient_screen_name
- def SetRecipientScreenName(self, recipient_screen_name):
- '''Set the unique recipient screen name of this direct message.
- Args:
- recipient_screen_name:
- The unique recipient screen name of this direct message
- '''
- self._recipient_screen_name = recipient_screen_name
- recipient_screen_name = property(GetRecipientScreenName, SetRecipientScreenName,
- doc='The unique recipient screen name of this direct message.')
- def GetText(self):
- '''Get the text of this direct message.
- Returns:
- The text of this direct message.
- '''
- return self._text
- def SetText(self, text):
- '''Set the text of this direct message.
- Args:
- text:
- The text of this direct message
- '''
- self._text = text
- text = property(GetText, SetText,
- doc='The text of this direct message')
- def __ne__(self, other):
- return not self.__eq__(other)
- def __eq__(self, other):
- try:
- return other and \
- self.id == other.id and \
- self.created_at == other.created_at and \
- self.sender_id == other.sender_id and \
- self.sender_screen_name == other.sender_screen_name and \
- self.recipient_id == other.recipient_id and \
- self.recipient_screen_name == other.recipient_screen_name and \
- self.text == other.text
- except AttributeError:
- return False
- def __str__(self):
- '''A string representation of this twitter.DirectMessage instance.
- The return value is the same as the JSON string representation.
- Returns:
- A string representation of this twitter.DirectMessage instance.
- '''
- return self.AsJsonString()
- def AsJsonString(self):
- '''A JSON string representation of this twitter.DirectMessage instance.
- Returns:
- A JSON string representation of this twitter.DirectMessage instance
- '''
- return simplejson.dumps(self.AsDict(), sort_keys=True)
- def AsDict(self):
- '''A dict representation of this twitter.DirectMessage instance.
- The return value uses the same key names as the JSON representation.
- Return:
- A dict representing this twitter.DirectMessage instance
- '''
- data = {}
- if self.id:
- data['id'] = self.id
- if self.created_at:
- data['created_at'] = self.created_at
- if self.sender_id:
- data['sender_id'] = self.sender_id
- if self.sender_screen_name:
- data['sender_screen_name'] = self.sender_screen_name
- if self.recipient_id:
- data['recipient_id'] = self.recipient_id
- if self.recipient_screen_name:
- data['recipient_screen_name'] = self.recipient_screen_name
- if self.text:
- data['text'] = self.text
- return data
- @staticmethod
- def NewFromJsonDict(data):
- '''Create a new instance based on a JSON dict.
- Args:
- data:
- A JSON dict, as converted from the JSON in the twitter API
- Returns:
- A twitter.DirectMessage instance
- '''
- return DirectMessage(created_at=data.get('created_at', None),
- recipient_id=data.get('recipient_id', None),
- sender_id=data.get('sender_id', None),
- text=data.get('text', None),
- sender_screen_name=data.get('sender_screen_name', None),
- id=data.get('id', None),
- recipient_screen_name=data.get('recipient_screen_name', None))
- class Hashtag(object):
- ''' A class representing a twitter hashtag
- '''
- def __init__(self,
- text=None):
- self.text = text
- @staticmethod
- def NewFromJsonDict(data):
- '''Create a new instance based on a JSON dict.
- Args:
- data:
- A JSON dict, as converted from the JSON in the twitter API
- Returns:
- A twitter.Hashtag instance
- '''
- return Hashtag(text = data.get('text', None))
- class Trend(object):
- ''' A class representing a trending topic
- '''
- def __init__(self, name=None, query=None, timestamp=None, url=None):
- self.name = name
- self.query = query
- self.timestamp = timestamp
- self.url = url
- def __repr__(self):
- return self.name
- def __str__(self):
- return 'Name: %s\nQuery: %s\nTimestamp: %s\nSearch URL: %s\n' % (self.name, self.query, self.timestamp, self.url)
- def __ne__(self, other):
- return not self.__eq__(other)
- def __eq__(self, other):
- try:
- return other and \
- self.name == other.name and \
- self.query == other.query and \
- self.timestamp == other.timestamp and \
- self.url == self.url
- except AttributeError:
- return False
- @staticmethod
- def NewFromJsonDict(data, timestamp = None):
- '''Create a new instance based on a JSON dict
- Args:
- data:
- A JSON dict
- timestamp:
- Gets set as the timestamp property of the new object
- Returns:
- A twitter.Trend object
- '''
- return Trend(name=data.get('name', None),
- query=data.get('query', None),
- url=data.get('url', None),
- timestamp=timestamp)
- class Url(object):
- '''A class representing an URL contained in a tweet'''
- def __init__(self,
- url=None,
- expanded_url=None):
- self.url = url
- self.expanded_url = expanded_url
- @staticmethod
- def NewFromJsonDict(data):
- '''Create a new instance based on a JSON dict.
- Args:
- data:
- A JSON dict, as converted from the JSON in the twitter API
- Returns:
- A twitter.Url instance
- '''
- return Url(url=data.get('url', None),
- expanded_url=data.get('expanded_url', None))
- class Api(object):
- '''A python interface into the Twitter API
- By default, the Api caches results for 1 minute.
- Example usage:
- To create an instance of the twitter.Api class, with no authentication:
- >>> import twitter
- >>> api = twitter.Api()
- To fetch a single user's public status messages, where "user" is either
- a Twitter "short name" or their user id.
- >>> statuses = api.GetUserTimeline(user)
- >>> print [s.text for s in statuses]
- To use authentication, instantiate the twitter.Api class with a
- consumer key and secret; and the oAuth key and secret:
- >>> api = twitter.Api(consumer_key='twitter consumer key',
- consumer_secret='twitter consumer secret',
- access_token_key='the_key_given',
- access_token_secret='the_key_secret')
- To fetch your friends (after being authenticated):
- >>> users = api.GetFriends()
- >>> print [u.name for u in users]
- To post a twitter status message (after being authenticated):
- >>> status = api.PostUpdate('I love python-twitter!')
- >>> print status.text
- I love python-twitter!
- There are many other methods, including:
- >>> api.PostUpdates(status)
- >>> api.PostDirectMessage(user, text)
- >>> api.GetUser(user)
- >>> api.GetReplies()
- >>> api.GetUserTimeline(user)
- >>> api.GetHomeTimeLine()
- >>> api.GetStatus(id)
- >>> api.DestroyStatus(id)
- >>> api.GetFriends(user)
- >>> api.GetFollowers()
- >>> api.GetFeatured()
- >>> api.GetDirectMessages()
- >>> api.GetSentDirectMessages()
- >>> api.PostDirectMessage(user, text)
- >>> api.DestroyDirectMessage(id)
- >>> api.DestroyFriendship(user)
- >>> api.CreateFriendship(user)
- >>> api.GetUserByEmail(email)
- >>> api.VerifyCredentials()
- '''
- DEFAULT_CACHE_TIMEOUT = 60 # cache for 1 minute
- _API_REALM = 'Twitter API'
- def __init__(self,
- consumer_key=None,
- consumer_secret=None,
- access_token_key=None,
- access_token_secret=None,
- input_encoding=None,
- request_headers=None,
- cache=DEFAULT_CACHE,
- shortner=None,
- base_url=None,
- use_gzip_compression=False,
- debugHTTP=False,
- proxy=None):
- '''Instantiate a new twitter.Api object.
- Args:
- consumer_key:
- Your Twitter user's consumer_key.
- consumer_secret:
- Your Twitter user's consumer_secret.
- access_token_key:
- The oAuth access token key value you retrieved
- from running get_access_token.py.
- access_token_secret:
- The oAuth access token's secret, also retrieved
- from the get_access_token.py run.
- input_encoding:
- The encoding used to encode input strings. [Optional]
- request_header:
- A dictionary of additional HTTP request headers. [Optional]
- cache:
- The cache instance to use. Defaults to DEFAULT_CACHE.
- Use None to disable caching. [Optional]
- shortner:
- The shortner instance to use. Defaults to None.
- See shorten_url.py for an example shortner. [Optional]
- base_url:
- The base URL to use to contact the Twitter API.
- Defaults to https://api.twitter.com. [Optional]
- use_gzip_compression:
- Set to True to tell enable gzip compression for any call
- made to Twitter. Defaults to False. [Optional]
- debugHTTP:
- Set to True to enable debug output from urllib2 when performing
- any HTTP requests. Defaults to False. [Optional]
- '''
- self.SetCache(cache)
- self.http_proxy = None
- if proxy is not None:
- self.http_proxy = proxy
- self._urllib = urllib2
- self._cache_timeout = Api.DEFAULT_CACHE_TIMEOUT
- self._input_encoding = input_encoding
- self._use_gzip = use_gzip_compression
- self._debugHTTP = debugHTTP
- self._oauth_consumer = None
- self._shortlink_size = 19
- self._InitializeRequestHeaders(request_headers)
- self._InitializeUserAgent()
- self._InitializeDefaultParameters()
- from config import APIsources
- for source in APIsources:
- self.source_api = source['source_api']
- if base_url is None:
- if self.source_api == "api.twitter.com":
- self.base_url = 'https://'+self.source_api+'/1.1'
- else:
- self.base_url = 'https://'+self.source_api
- else:
- self.base_url = base_url
- if consumer_key is not None and (access_token_key is None or
- access_token_secret is None):
- print >> sys.stderr, 'Twitter now requires an oAuth Access Token for API calls.'
- print >> sys.stderr, 'If your using this library from a command line utility, please'
- print >> sys.stderr, 'run the included get_access_token.py tool to generate one.'
- raise TwitterError('Twitter requires oAuth Access Token for all API access')
- self.SetCredentials(consumer_key, consumer_secret, access_token_key, access_token_secret)
- def SetCredentials(self,
- consumer_key,
- consumer_secret,
- access_token_key=None,
- access_token_secret=None):
- '''Set the consumer_key and consumer_secret for this instance
- Args:
- consumer_key:
- The consumer_key of the twitter account.
- consumer_secret:
- The consumer_secret for the twitter account.
- access_token_key:
- The oAuth access token key value you retrieved
- from running get_access_token.py.
- access_token_secret:
- The oAuth access token's secret, also retrieved
- from the get_access_token.py run.
- '''
- self._consumer_key = consumer_key
- self._consumer_secret = consumer_secret
- self._access_token_key = access_token_key
- self._access_token_secret = access_token_secret
- self._oauth_consumer = None
- if consumer_key is not None and consumer_secret is not None and \
- access_token_key is not None and access_token_secret is not None:
- self._signature_method_plaintext = oauth.SignatureMethod_PLAINTEXT()
- self._signature_method_hmac_sha1 = oauth.SignatureMethod_HMAC_SHA1()
- self._oauth_token = oauth.Token(key=access_token_key, secret=access_token_secret)
- self._oauth_consumer = oauth.Consumer(key=consumer_key, secret=consumer_secret)
- self._config = self.GetHelpConfiguration()
- def GetHelpConfiguration(self):
- if self.source_api == "api.twitter.com":
- url = '%s/help/configuration.json' % self.base_url
- else:
- url = '%s/statusnet/config.json' % self.base_url
- json = self._FetchUrl(url)
- data = self._ParseAndCheckTwitter(json)
- return data
- def GetShortUrlLength(self, https=False):
- if https:
- return self._config['short_url_length_https']
- else:
- return self._config['short_url_length']
- def ClearCredentials(self):
- '''Clear the any credentials for this instance
- '''
- self._consumer_key = None
- self._consumer_secret = None
- self._access_token_key = None
- self._access_token_secret = None
- self._oauth_consumer = None
- def GetSearch(self,
- term=None,
- geocode=None,
- since_id=None,
- max_id=None,
- until=None,
- count=15,
- lang=None,
- locale=None,
- result_type="mixed",
- include_entities=None):
- '''Return twitter search results for a given term.
- Args:
- term:
- Term to search by. Optional if you include geocode.
- since_id:
- Returns results with an ID greater than (that is, more recent
- than) the specified ID. There are limits to the number of
- Tweets which can be accessed through the API. If the limit of
- Tweets has occurred since the since_id, the since_id will be
- forced to the oldest ID available. [Optional]
- max_id:
- Returns only statuses with an ID less than (that is, older
- than) or equal to the specified ID. [Optional]
- until:
- Returns tweets generated before the given date. Date should be
- formatted as YYYY-MM-DD. [Optional]
- geocode:
- Geolocation information in the form (latitude, longitude, radius)
- [Optional]
- count:
- Number of results to return. Default is 15 [Optional]
- lang:
- Language for results as ISO 639-1 code. Default is None (all languages)
- [Optional]
- locale:
- Language of the search query. Currently only 'ja' is effective. This is
- intended for language-specific consumers and the default should work in
- the majority of cases.
- result_type:
- Type of result which should be returned. Default is "mixed". Other
- valid options are "recent" and "popular". [Optional]
- include_entities:
- If True, each tweet will include a node called "entities,".
- This node offers a variety of metadata about the tweet in a
- discrete structure, including: user_mentions, urls, and
- hashtags. [Optional]
- Returns:
- A sequence of twitter.Status instances, one for each message containing
- the term
- '''
- # Build request parameters
- parameters = {}
- if since_id:
- try:
- parameters['since_id'] = long(since_id)
- except ValueError:
- raise TwitterError("since_id must be an integer")
- if max_id:
- try:
- parameters['max_id'] = long(max_id)
- except ValueError:
- raise TwitterError("max_id must be an integer")
- if until:
- parameters['until'] = until
- if lang:
- parameters['lang'] = lang
- if locale:
- parameters['locale'] = locale
- if term is None and geocode is None:
- return []
- if term is not None:
- parameters['q'] = term
- if geocode is not None:
- parameters['geocode'] = ','.join(map(str, geocode))
- if include_entities:
- parameters['include_entities'] = 1
- try:
- parameters['count'] = int(count)
- except ValueError:
- raise TwitterError("count must be an integer")
- if result_type in ["mixed", "popular", "recent"]:
- parameters['result_type'] = result_type
- # Make and send requests
- if self.source_api == "api.twitter.com":
- url = "%s/search/tweets.json" % self.base_url
- else:
- url = '%s/search.json' % self.base_url
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- if self.source_api == "api.twitter.com":
- return [Status.NewFromJsonDict(x) for x in data["statuses"]]
- else:
- return [Status.NewFromJsonDict(x) for x in data]
- def GetUsersSearch(self,
- term=None,
- page=1,
- count=20,
- include_entities=None):
- '''Return twitter user search results for a given term.
- Args:
- term:
- Term to search by.
- page:
- Page of results to return. Default is 1
- [Optional]
- count:
- Number of results to return. Default is 20
- [Optional]
- include_entities:
- If True, each tweet will include a node called "entities,".
- This node offers a variety of metadata about the tweet in a
- discrete structure, including: user_mentions, urls, and hashtags.
- [Optional]
- Returns:
- A sequence of twitter.User instances, one for each message containing
- the term
- '''
- # Build request parameters
- parameters = {}
- if term is not None:
- parameters['q'] = term
- if include_entities:
- parameters['include_entities'] = 1
- try:
- parameters['count'] = int(count)
- except ValueError:
- raise TwitterError("count must be an integer")
- # Make and send requests
- url = '%s/users/search.json' % self.base_url
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- return [User.NewFromJsonDict(x) for x in data]
- def GetTrendsCurrent(self, exclude=None):
- '''Get the current top trending topics (global)
- Args:
- exclude:
- Appends the exclude parameter as a request parameter.
- Currently only exclude=hashtags is supported. [Optional]
- Returns:
- A list with 10 entries. Each entry contains a trend.
- '''
- return self.GetTrendsWoeid(id=1, exclude=exclude)
- def GetTrendsWoeid(self, id, exclude=None):
- '''Return the top 10 trending topics for a specific WOEID, if trending
- information is available for it.
- Args:
- woeid:
- the Yahoo! Where On Earth ID for a location.
- exclude:
- Appends the exclude parameter as a request parameter.
- Currently only exclude=hashtags is supported. [Optional]
- Returns:
- A list with 10 entries. Each entry contains a trend.
- '''
- url = '%s/trends/place.json' % (self.base_url)
- parameters = {'id': id}
- if exclude:
- parameters['exclude'] = exclude
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- trends = []
- timestamp = data[0]['as_of']
- for trend in data[0]['trends']:
- trends.append(Trend.NewFromJsonDict(trend, timestamp = timestamp))
- return trends
- def GetHomeTimeline(self,
- count=None,
- since_id=None,
- max_id=None,
- trim_user=False,
- exclude_replies=False,
- contributor_details=False,
- include_entities=True):
- '''
- Fetch a collection of the most recent Tweets and retweets posted by the
- authenticating user and the users they follow.
- The home timeline is central to how most users interact with the Twitter
- service.
- The twitter.Api instance must be authenticated.
- Args:
- count:
- Specifies the number of statuses to retrieve. May not be
- greater than 200. Defaults to 20. [Optional]
- since_id:
- Returns results with an ID greater than (that is, more recent
- than) the specified ID. There are limits to the number of
- Tweets which can be accessed through the API. If the limit of
- Tweets has occurred since the since_id, the since_id will be
- forced to the oldest ID available. [Optional]
- max_id:
- Returns results with an ID less than (that is, older than) or
- equal to the specified ID. [Optional]
- trim_user:
- When True, each tweet returned in a timeline will include a user
- object including only the status authors numerical ID. Omit this
- parameter to receive the complete user object. [Optional]
- exclude_replies:
- This parameter will prevent replies from appearing in the
- returned timeline. Using exclude_replies with the count
- parameter will mean you will receive up-to count tweets -
- this is because the count parameter retrieves that many
- tweets before filtering out retweets and replies.
- [Optional]
- contributor_details:
- This parameter enhances the contributors element of the
- status response to include the screen_name of the contributor.
- By default only the user_id of the contributor is included.
- [Optional]
- include_entities:
- The entities node will be disincluded when set to false.
- This node offers a variety of metadata about the tweet in a
- discreet structure, including: user_mentions, urls, and
- hashtags. [Optional]
- Returns:
- A sequence of twitter.Status instances, one for each message
- '''
- if self.source_api == "api.twitter.com":
- url = '%s/statuses/home_timeline.json' % self.base_url
- else:
- url = '%s/statuses/public_timeline.json' % self.base_url
- if not self._oauth_consumer:
- raise TwitterError("API must be authenticated.")
- parameters = {}
- if count is not None:
- try:
- if int(count) > 200:
- raise TwitterError("'count' may not be greater than 200")
- except ValueError:
- raise TwitterError("'count' must be an integer")
- parameters['count'] = count
- if since_id:
- try:
- parameters['since_id'] = long(since_id)
- except ValueError:
- raise TwitterError("'since_id' must be an integer")
- if max_id:
- try:
- parameters['max_id'] = long(max_id)
- except ValueError:
- raise TwitterError("'max_id' must be an integer")
- if trim_user:
- parameters['trim_user'] = 1
- if exclude_replies:
- parameters['exclude_replies'] = 1
- if contributor_details:
- parameters['contributor_details'] = 1
- if not include_entities:
- parameters['include_entities'] = 'false'
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- return [Status.NewFromJsonDict(x) for x in data]
- def GetUserTimeline(self,
- user_id=None,
- screen_name=None,
- since_id=None,
- max_id=None,
- count=None,
- include_rts=True,
- trim_user=None,
- exclude_replies=None):
- '''Fetch the sequence of public Status messages for a single user.
- The twitter.Api instance must be authenticated if the user is prprintivate.
- Args:
- user_id:
- Specifies the ID of the user for whom to return the
- user_timeline. Helpful for disambiguating when a valid user ID
- is also a valid screen name. [Optional]
- screen_name:
- Specifies the screen name of the user for whom to return the
- user_timeline. Helpful for disambiguating when a valid screen
- name is also a user ID. [Optional]
- since_id:
- Returns results with an ID greater than (that is, more recent
- than) the specified ID. There are limits to the number of
- Tweets which can be accessed through the API. If the limit of
- Tweets has occurred since the since_id, the since_id will be
- forced to the oldest ID available. [Optional]
- max_id:
- Returns only statuses with an ID less than (that is, older
- than) or equal to the specified ID. [Optional]
- count:
- Specifies the number of statuses to retrieve. May not be
- greater than 200. [Optional]
- include_rts:
- If True, the timeline will contain native retweets (if they
- exist) in addition to the standard stream of tweets. [Optional]
- trim_user:
- If True, statuses will only contain the numerical user ID only.
- Otherwise a full user object will be returned for each status.
- [Optional]
- exclude_replies:
- If True, this will prevent replies from appearing in the returned
- timeline. Using exclude_replies with the count parameter will mean you
- will receive up-to count tweets - this is because the count parameter
- retrieves that many tweets before filtering out retweets and replies.
- This parameter is only supported for JSON and XML responses. [Optional]
- Returns:
- A sequence of Status instances, one for each message up to count
- '''
- parameters = {}
- url ='%s/statuses/user_timeline.json' % (self.base_url)
- if user_id:
- parameters['user_id'] = user_id
- elif screen_name:
- parameters['screen_name'] = screen_name
- if since_id:
- try:
- parameters['since_id'] = long(since_id)
- except ValueError:
- raise TwitterError("since_id must be an integer")
- if max_id:
- try:
- parameters['max_id'] = long(max_id)
- except ValueError:
- raise TwitterError("max_id must be an integer")
- if count:
- try:
- parameters['count'] = int(count)
- except ValueError:
- raise TwitterError("count must be an integer")
- if not include_rts:
- parameters['include_rts'] = 0
- if trim_user:
- parameters['trim_user'] = 1
- if exclude_replies:
- parameters['exclude_replies'] = 1
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- return [Status.NewFromJsonDict(x) for x in data]
- def GetStatus(self,
- id,
- trim_user=False,
- include_my_retweet=True,
- include_entities=True):
- '''Returns a single status message, specified by the id parameter.
- The twitter.Api instance must be authenticated.
- Args:
- id:
- The numeric ID of the status you are trying to retrieve.
- trim_user:
- When set to True, each tweet returned in a timeline will include
- a user object including only the status authors numerical ID.
- Omit this parameter to receive the complete user object.
- [Optional]
- include_my_retweet:
- When set to True, any Tweets returned that have been retweeted by
- the authenticating user will include an additional
- current_user_retweet node, containing the ID of the source status
- for the retweet. [Optional]
- include_entities:
- If False, the entities node will be disincluded.
- This node offers a variety of metadata about the tweet in a
- discreet structure, including: user_mentions, urls, and
- hashtags. [Optional]
- Returns:
- A twitter.Status instance representing that status message
- '''
- url = '%s/statuses/show.json' % (self.base_url)
- if not self._oauth_consumer:
- raise TwitterError("API must be authenticated.")
- parameters = {}
- try:
- parameters['id'] = long(id)
- except ValueError:
- raise TwitterError("'id' must be an integer.")
- if trim_user:
- parameters['trim_user'] = 1
- if include_my_retweet:
- parameters['include_my_retweet'] = 1
- if not include_entities:
- parameters['include_entities'] = 'none'
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- return Status.NewFromJsonDict(data)
- def GetStatusOembed(self,
- id=None,
- url=None,
- maxwidth=None,
- hide_media=False,
- hide_thread=False,
- omit_script=False,
- align=None,
- related=None,
- lang=None):
- '''Returns information allowing the creation of an embedded representation of a
- Tweet on third party sites.
- Specify tweet by the id or url parameter.
- The twitter.Api instance must be authenticated.
- Args:
- id:
- The numeric ID of the status you are trying to embed.
- url:
- The url of the status you are trying to embed.
- maxwidth:
- The maximum width in pixels that the embed should be rendered at.
- This value is constrained to be between 250 and 550 pixels. [Optional]
- hide_media:
- Specifies whether the embedded Tweet should automatically expand images. [Optional]
- hide_thread:
- Specifies whether the embedded Tweet should automatically show the original
- message in the case that the embedded Tweet is a reply. [Optional]
- omit_script:
- Specifies whether the embedded Tweet HTML should include a <script>
- element pointing to widgets.js. [Optional]
- align:
- Specifies whether the embedded Tweet should be left aligned, right aligned,
- or centered in the page. [Optional]
- related:
- A comma sperated string of related screen names. [Optional]
- lang:
- Language code for the rendered embed. [Optional]
- Returns:
- A dictionary with the response.
- '''
- request_url = '%s/statuses/oembed.json' % (self.base_url)
- if not self._oauth_consumer:
- raise TwitterError("API must be authenticated.")
- parameters = {}
- if id is not None:
- try:
- parameters['id'] = long(id)
- except ValueError:
- raise TwitterError("'id' must be an integer.")
- elif url is not None:
- parameters['url'] = url
- else:
- raise TwitterError("Must specify either 'id' or 'url'")
- if maxwidth is not None:
- parameters['maxwidth'] = maxwidth
- if hide_media == True:
- parameters['hide_media'] = 'true'
- if hide_thread == True:
- parameters['hide_thread'] = 'true'
- if omit_script == True:
- parameters['omit_script'] = 'true'
- if align is not None:
- if align not in ('left', 'center', 'right', 'none'):
- raise TwitterError("'align' must be 'left', 'center', 'right', or 'none'")
- parameters['align'] = align
- if related:
- if not isinstance(related, str):
- raise TwitterError("'related' should be a string of comma separated screen names")
- parameters['related'] = related
- if lang is not None:
- if not isinstance(lang, str):
- raise TwitterError("'lang' should be string instance")
- parameters['lang'] = lang
- json = self._FetchUrl(request_url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- return data
- def DestroyStatus(self, id, trim_user=False):
- '''Destroys the status specified by the required ID parameter.
- The twitter.Api instance must be authenticated and the
- authenticating user must be the author of the specified status.
- Args:
- id:
- The numerical ID of the status you're trying to destroy.
- Returns:
- A twitter.Status instance representing the destroyed status message
- '''
- if not self._oauth_consumer:
- raise TwitterError("API must be authenticated.")
- try:
- post_data = {'id': long(id)}
- except ValueError:
- raise TwitterError("id must be an integer")
- url = '%s/statuses/destroy/%s.json' % (self.base_url, id)
- if trim_user:
- post_data['trim_user'] = 1
- json = self._FetchUrl(url, post_data=post_data)
- data = self._ParseAndCheckTwitter(json)
- return Status.NewFromJsonDict(data)
- @classmethod
- def _calculate_status_length(cls, status, linksize=19):
- dummy_link_replacement = 'https://-%d-chars%s/' % (linksize, '-'*(linksize - 18))
- shortened = ' '.join([x if not (x.startswith('http://') or
- x.startswith('https://'))
- else
- dummy_link_replacement
- for x in status.split(' ')])
- return len(shortened)
- def PostUpdate(self, status, in_reply_to_status_id=None, latitude=None, longitude=None, place_id=None, display_coordinates=False, trim_user=False):
- '''Post a twitter status message from the authenticated user.
- The twitter.Api instance must be authenticated.
- https://dev.twitter.com/docs/api/1.1/post/statuses/update
- Args:
- status:
- The message text to be posted.
- Must be less than or equal to 140 characters.
- in_reply_to_status_id:
- The ID of an existing status that the status to be posted is
- in reply to. This implicitly sets the in_reply_to_user_id
- attribute of the resulting status to the user ID of the
- message being replied to. Invalid/missing status IDs will be
- ignored. [Optional]
- latitude:
- Latitude coordinate of the tweet in degrees. Will only work
- in conjunction with longitude argument. Both longitude and
- latitude will be ignored by twitter if the user has a false
- geo_enabled setting. [Optional]
- longitude:
- Longitude coordinate of the tweet in degrees. Will only work
- in conjunction with latitude argument. Both longitude and
- latitude will be ignored by twitter if the user has a false
- geo_enabled setting. [Optional]
- place_id:
- A place in the world. These IDs can be retrieved from
- GET geo/reverse_geocode. [Optional]
- display_coordinates:
- Whether or not to put a pin on the exact coordinates a tweet
- has been sent from. [Optional]
- trim_user:
- If True the returned payload will only contain the user IDs,
- otherwise the payload will contain the full user data item.
- [Optional]
- Returns:
- A twitter.Status instance representing the message posted.
- '''
- if not self._oauth_consumer:
- raise TwitterError("The twitter.Api instance must be authenticated.")
- url = '%s/statuses/update.json' % self.base_url
- if isinstance(status, unicode) or self._input_encoding is None:
- u_status = status
- else:
- u_status = unicode(status, self._input_encoding)
- #if self._calculate_status_length(u_status, self._shortlink_size) > CHARACTER_LIMIT:
- # raise TwitterError("Text must be less than or equal to %d characters. "
- # "Consider using PostUpdates." % CHARACTER_LIMIT)
- data = {'status': status}
- if in_reply_to_status_id:
- data['in_reply_to_status_id'] = in_reply_to_status_id
- if latitude is not None and longitude is not None:
- data['lat'] = str(latitude)
- data['long'] = str(longitude)
- if place_id is not None:
- data['place_id'] = str(place_id)
- if display_coordinates:
- data['display_coordinates'] = 'true'
- if trim_user:
- data['trim_user'] = 'true'
- json = self._FetchUrl(url, post_data=data)
- data = self._ParseAndCheckTwitter(json)
- return Status.NewFromJsonDict(data)
- def PostUpdates(self, status, continuation=None, **kwargs):
- '''Post one or more twitter status messages from the authenticated user.
- Unlike api.PostUpdate, this method will post multiple status updates
- if the message is longer than 140 characters.
- The twitter.Api instance must be authenticated.
- Args:
- status:
- The message text to be posted.
- May be longer than 140 characters.
- continuation:
- The character string, if any, to be appended to all but the
- last message. Note that Twitter strips trailing '...' strings
- from messages. Consider using the unicode \u2026 character
- (horizontal ellipsis) instead. [Defaults to None]
- **kwargs:
- See api.PostUpdate for a list of accepted parameters.
- Returns:
- A of list twitter.Status instance representing the messages posted.
- '''
- results = list()
- if continuation is None:
- continuation = ''
- line_length = CHARACTER_LIMIT - len(continuation)
- lines = textwrap.wrap(status, line_length)
- for line in lines[0:-1]:
- results.append(self.PostUpdate(line + continuation, **kwargs))
- results.append(self.PostUpdate(lines[-1], **kwargs))
- return results
- def PostRetweet(self, original_id, trim_user=False):
- '''Retweet a tweet with the Retweet API.
- The twitter.Api instance must be authenticated.
- Args:
- original_id:
- The numerical id of the tweet that will be retweeted
- trim_user:
- If True the returned payload will only contain the user IDs,
- otherwise the payload will contain the full user data item.
- [Optional]
- Returns:
- A twitter.Status instance representing the original tweet with retweet details embedded.
- '''
- if not self._oauth_consumer:
- raise TwitterError("The twitter.Api instance must be authenticated.")
- try:
- if int(original_id) <= 0:
- raise TwitterError("'original_id' must be a positive number")
- except ValueError:
- raise TwitterError("'original_id' must be an integer")
- url = '%s/statuses/retweet/%s.json' % (self.base_url, original_id)
- data = {'id': original_id}
- if trim_user:
- data['trim_user'] = 'true'
- json = self._FetchUrl(url, post_data=data)
- data = self._ParseAndCheckTwitter(json)
- return Status.NewFromJsonDict(data)
- def GetUserRetweets(self, count=None, since_id=None, max_id=None, trim_user=False):
- '''Fetch the sequence of retweets made by the authenticated user.
- The twitter.Api instance must be authenticated.
- Args:
- count:
- The number of status messages to retrieve. [Optional]
- since_id:
- Returns results with an ID greater than (that is, more recent
- than) the specified ID. There are limits to the number of
- Tweets which can be accessed through the API. If the limit of
- Tweets has occurred since the since_id, the since_id will be
- forced to the oldest ID available. [Optional]
- max_id:
- Returns results with an ID less than (that is, older than) or
- equal to the specified ID. [Optional]
- trim_user:
- If True the returned payload will only contain the user IDs,
- otherwise the payload will contain the full user data item.
- [Optional]
- Returns:
- A sequence of twitter.Status instances, one for each message up to count
- '''
- return self.GetUserTimeline(since_id=since_id, count=count, max_id=max_id, trim_user=trim_user, exclude_replies=True, include_rts=True)
- def GetReplies(self, since_id=None, count=None, max_id=None, trim_user=False):
- '''Get a sequence of status messages representing the 20 most
- recent replies (status updates prefixed with @twitterID) to the
- authenticating user.
- Args:
- since_id:
- Returns results with an ID greater than (that is, more recent
- than) the specified ID. There are limits to the number of
- Tweets which can be accessed through the API. If the limit of
- Tweets has occurred since the since_id, the since_id will be
- forced to the oldest ID available. [Optional]
- max_id:
- Returns results with an ID less than (that is, older than) or
- equal to the specified ID. [Optional]
- trim_user:
- If True the returned payload will only contain the user IDs,
- otherwise the payload will contain the full user data item.
- [Optional]
- Returns:
- A sequence of twitter.Status instances, one for each reply to the user.
- '''
- return self.GetUserTimeline(since_id=since_id, count=count, max_id=max_id, trim_user=trim_user, exclude_replies=False, include_rts=False)
- def GetRetweets(self, statusid, count=None, trim_user=False):
- '''Returns up to 100 of the first retweets of the tweet identified
- by statusid
- Args:
- statusid:
- The ID of the tweet for which retweets should be searched for
- count:
- The number of status messages to retrieve. [Optional]
- trim_user:
- If True the returned payload will only contain the user IDs,
- otherwise the payload will contain the full user data item.
- [Optional]
- Returns:
- A list of twitter.Status instances, which are retweets of statusid
- '''
- if not self._oauth_consumer:
- raise TwitterError("The twitter.Api instsance must be authenticated.")
- url = '%s/statuses/retweets/%s.json' % (self.base_url, statusid)
- parameters = {}
- if trim_user:
- parameters['trim_user'] = 'true'
- if count:
- try:
- parameters['count'] = int(count)
- except ValueError:
- raise TwitterError("count must be an integer")
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- return [Status.NewFromJsonDict(s) for s in data]
- def GetRetweetsOfMe(self,
- count=None,
- since_id=None,
- max_id=None,
- trim_user=False,
- include_entities=True,
- include_user_entities=True):
- '''Returns up to 100 of the most recent tweets of the user that have been
- retweeted by others.
- Args:
- count:
- The number of retweets to retrieve, up to 100. If omitted, 20 is
- assumed.
- since_id:
- Returns results with an ID greater than (newer than) this ID.
- max_id:
- Returns results with an ID less than or equal to this ID.
- trim_user:
- When True, the user object for each tweet will only be an ID.
- include_entities:
- When True, the tweet entities will be included.
- include_user_entities:
- When True, the user entities will be included.
- '''
- if not self._oauth_consumer:
- raise TwitterError("The twitter.Api instance must be authenticated.")
- url = '%s/statuses/retweets_of_me.json' % self.base_url
- parameters = {}
- if count is not None:
- try:
- if int(count) > 100:
- raise TwitterError("'count' may not be greater than 100")
- except ValueError:
- raise TwitterError("'count' must be an integer")
- if count:
- parameters['count'] = count
- if since_id:
- parameters['since_id'] = since_id
- if max_id:
- parameters['max_id'] = max_id
- if trim_user:
- parameters['trim_user'] = trim_user
- if not include_entities:
- parameters['include_entities'] = include_entities
- if not include_user_entities:
- parameters['include_user_entities'] = include_user_entities
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- return [Status.NewFromJsonDict(s) for s in data]
- def GetBlocks(self, user_id=None, screen_name=None, cursor=-1, skip_status=False, include_user_entities=False):
- '''Fetch the sequence of twitter.User instances, one for each blocked user.
- The twitter.Api instance must be authenticated.
- Args:
- user_id:
- The twitter id of the user whose friends you are fetching.
- If not specified, defaults to the authenticated user. [Optional]
- screen_name:
- The twitter name of the user whose friends you are fetching.
- If not specified, defaults to the authenticated user. [Optional]
- cursor:
- Should be set to -1 for the initial call and then is used to
- control what result page Twitter returns [Optional(ish)]
- skip_status:
- If True the statuses will not be returned in the user items.
- [Optional]
- include_user_entities:
- When True, the user entities will be included.
- Returns:
- A sequence of twitter.User instances, one for each friend
- '''
- if not self._oauth_consumer:
- raise TwitterError("twitter.Api instance must be authenticated")
- url = '%s/blocks/list.json' % self.base_url
- result = []
- parameters = {}
- if user_id is not None:
- parameters['user_id'] = user_id
- if screen_name is not None:
- parameters['screen_name'] = screen_name
- if skip_status:
- parameters['skip_status'] = True
- if include_user_entities:
- parameters['include_user_entities'] = True
- while True:
- parameters['cursor'] = cursor
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- result += [User.NewFromJsonDict(x) for x in data['users']]
- if 'next_cursor' in data:
- if data['next_cursor'] == 0 or data['next_cursor'] == data['previous_cursor']:
- break
- else:
- cursor = data['next_cursor']
- else:
- break
- return result
- def GetFriends(self, user_id=None, screen_name=None, cursor=-1, skip_status=False, include_user_entities=False):
- '''Fetch the sequence of twitter.User instances, one for each friend.
- The twitter.Api instance must be authenticated.
- Args:
- user_id:
- The twitter id of the user whose friends you are fetching.
- If not specified, defaults to the authenticated user. [Optional]
- screen_name:
- The twitter name of the user whose friends you are fetching.
- If not specified, defaults to the authenticated user. [Optional]
- cursor:
- Should be set to -1 for the initial call and then is used to
- control what result page Twitter returns [Optional(ish)]
- skip_status:
- If True the statuses will not be returned in the user items.
- [Optional]
- include_user_entities:
- When True, the user entities will be included.
- Returns:
- A sequence of twitter.User instances, one for each friend
- '''
- if not self._oauth_consumer:
- raise TwitterError("twitter.Api instance must be authenticated")
- url = '%s/friends/list.json' % self.base_url
- result = []
- parameters = {}
- if user_id is not None:
- parameters['user_id'] = user_id
- if screen_name is not None:
- parameters['screen_name'] = screen_name
- if skip_status:
- parameters['skip_status'] = True
- if include_user_entities:
- parameters['include_user_entities'] = True
- while True:
- parameters['cursor'] = cursor
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- result += [User.NewFromJsonDict(x) for x in data['users']]
- if 'next_cursor' in data:
- if data['next_cursor'] == 0 or data['next_cursor'] == data['previous_cursor']:
- break
- else:
- cursor = data['next_cursor']
- else:
- break
- return result
- def GetFriendIDs(self, user_id=None, screen_name=None, cursor=-1, stringify_ids=False, count=None):
- '''Returns a list of twitter user id's for every person
- the specified user is following.
- Args:
- user_id:
- The id of the user to retrieve the id list for
- [Optional]
- screen_name:
- The screen_name of the user to retrieve the id list for
- [Optional]
- cursor:
- Specifies the Twitter API Cursor location to start at.
- Note: there are pagination limits.
- [Optional]
- stringify_ids:
- if True then twitter will return the ids as strings instead of integers.
- [Optional]
- count:
- The number of status messages to retrieve. [Optional]
- Returns:
- A list of integers, one for each user id.
- '''
- url = '%s/friends/ids.json' % self.base_url
- if not self._oauth_consumer:
- raise TwitterError("twitter.Api instance must be authenticated")
- parameters = {}
- if user_id is not None:
- parameters['user_id'] = user_id
- if screen_name is not None:
- parameters['screen_name'] = screen_name
- if stringify_ids:
- parameters['stringify_ids'] = True
- if count is not None:
- parameters['count'] = count
- result = []
- while True:
- parameters['cursor'] = cursor
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- result += [x for x in data['ids']]
- if 'next_cursor' in data:
- if data['next_cursor'] == 0 or data['next_cursor'] == data['previous_cursor']:
- break
- else:
- cursor = data['next_cursor']
- else:
- break
- return result
- def GetFollowerIDs(self, user_id=None, screen_name=None, cursor=-1, stringify_ids=False, count=None, total_count=None):
- '''Returns a list of twitter user id's for every person
- that is following the specified user.
- Args:
- user_id:
- The id of the user to retrieve the id list for
- [Optional]
- screen_name:
- The screen_name of the user to retrieve the id list for
- [Optional]
- cursor:
- Specifies the Twitter API Cursor location to start at.
- Note: there are pagination limits.
- [Optional]
- stringify_ids:
- if True then twitter will return the ids as strings instead of integers.
- [Optional]
- count:
- The number of user id's to retrieve per API request. Please be aware that
- this might get you rate-limited if set to a small number. By default Twitter
- will retrieve 5000 UIDs per call.
- [Optional]
- total_count:
- The total amount of UIDs to retrieve. Good if the account has many followers
- and you don't want to get rate limited. The data returned might contain more
- UIDs if total_count is not a multiple of count (5000 by default).
- [Optional]
- Returns:
- A list of integers, one for each user id.
- '''
- url = '%s/followers/ids.json' % self.base_url
- if not self._oauth_consumer:
- raise TwitterError("twitter.Api instance must be authenticated")
- parameters = {}
- if user_id is not None:
- parameters['user_id'] = user_id
- if screen_name is not None:
- parameters['screen_name'] = screen_name
- if stringify_ids:
- parameters['stringify_ids'] = True
- if count is not None:
- parameters['count'] = count
- result = []
- while True:
- if total_count and total_count < count:
- parameters['count'] = total_count
- parameters['cursor'] = cursor
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- result += [x for x in data['ids']]
- if 'next_cursor' in data:
- if data['next_cursor'] == 0 or data['next_cursor'] == data['previous_cursor']:
- break
- else:
- cursor = data['next_cursor']
- total_count -= len(data['ids'])
- if total_count < 1:
- break
- else:
- break
- return result
- def GetFollowers(self, user_id=None, screen_name=None, cursor=-1, skip_status=False, include_user_entities=False):
- '''Fetch the sequence of twitter.User instances, one for each follower
- The twitter.Api instance must be authenticated.
- Args:
- user_id:
- The twitter id of the user whose followers you are fetching.
- If not specified, defaults to the authenticated user. [Optional]
- screen_name:
- The twitter name of the user whose followers you are fetching.
- If not specified, defaults to the authenticated user. [Optional]
- cursor:
- Should be set to -1 for the initial call and then is used to
- control what result page Twitter returns [Optional(ish)]
- skip_status:
- If True the statuses will not be returned in the user items.
- [Optional]
- include_user_entities:
- When True, the user entities will be included.
- Returns:
- A sequence of twitter.User instances, one for each follower
- '''
- if not self._oauth_consumer:
- raise TwitterError("twitter.Api instance must be authenticated")
- url = '%s/followers/list.json' % self.base_url
- result = []
- parameters = {}
- if user_id is not None:
- parameters['user_id'] = user_id
- if screen_name is not None:
- parameters['screen_name'] = screen_name
- if skip_status:
- parameters['skip_status'] = True
- if include_user_entities:
- parameters['include_user_entities'] = True
- while True:
- parameters['cursor'] = cursor
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- result += [User.NewFromJsonDict(x) for x in data['users']]
- if 'next_cursor' in data:
- if data['next_cursor'] == 0 or data['next_cursor'] == data['previous_cursor']:
- break
- else:
- cursor = data['next_cursor']
- else:
- break
- return result
- def UsersLookup(self, user_id=None, screen_name=None, users=None, include_entities=True):
- '''Fetch extended information for the specified users.
- Users may be specified either as lists of either user_ids,
- screen_names, or twitter.User objects. The list of users that
- are queried is the union of all specified parameters.
- The twitter.Api instance must be authenticated.
- Args:
- user_id:
- A list of user_ids to retrieve extended information.
- [Optional]
- screen_name:
- A list of screen_names to retrieve extended information.
- [Optional]
- users:
- A list of twitter.User objects to retrieve extended information.
- [Optional]
- include_entities:
- The entities node that may appear within embedded statuses will be
- disincluded when set to False.
- [Optional]
- Returns:
- A list of twitter.User objects for the requested users
- '''
- if not self._oauth_consumer:
- raise TwitterError("The twitter.Api instance must be authenticated.")
- if not user_id and not screen_name and not users:
- raise TwitterError("Specify at least one of user_id, screen_name, or users.")
- url = '%s/users/lookup.json' % self.base_url
- parameters = {}
- uids = list()
- if user_id:
- uids.extend(user_id)
- if users:
- uids.extend([u.id for u in users])
- if len(uids):
- parameters['user_id'] = ','.join(["%s" % u for u in uids])
- if screen_name:
- parameters['screen_name'] = ','.join(screen_name)
- if not include_entities:
- parameters['include_entities'] = 'false'
- json = self._FetchUrl(url, parameters=parameters)
- try:
- data = self._ParseAndCheckTwitter(json)
- except TwitterError, e:
- _, e, _ = sys.exc_info()
- t = e.args[0]
- if len(t) == 1 and ('code' in t[0]) and (t[0]['code'] == 34):
- data = []
- else:
- raise
- return [User.NewFromJsonDict(u) for u in data]
- def GetUser(self, user_id=None, screen_name=None, include_entities=True):
- '''Returns a single user.
- The twitter.Api instance must be authenticated.
- Args:
- user_id:
- The id of the user to retrieve.
- [Optional]
- screen_name:
- The screen name of the user for whom to return results for. Either a
- user_id or screen_name is required for this method.
- [Optional]
- include_entities:
- if set to False, the 'entities' node will not be included.
- [Optional]
- Returns:
- A twitter.User instance representing that user
- '''
- url = '%s/users/show.json' % (self.base_url)
- parameters = {}
- if not self._oauth_consumer:
- raise TwitterError("The twitter.Api instance must be authenticated.")
- if user_id:
- parameters['user_id'] = user_id
- elif screen_name:
- parameters['screen_name'] = screen_name
- else:
- raise TwitterError("Specify at least one of user_id or screen_name.")
- if not include_entities:
- parameters['include_entities'] = 'false'
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- return User.NewFromJsonDict(data)
- def GetDirectMessages(self, since_id=None, max_id=None, count=None, include_entities=True, skip_status=False):
- '''Returns a list of the direct messages sent to the authenticating user.
- The twitter.Api instance must be authenticated.
- Args:
- since_id:
- Returns results with an ID greater than (that is, more recent
- than) the specified ID. There are limits to the number of
- Tweets which can be accessed through the API. If the limit of
- Tweets has occurred since the since_id, the since_id will be
- forced to the oldest ID available. [Optional]
- max_id:
- Returns results with an ID less than (that is, older than) or
- equal to the specified ID. [Optional]
- count:
- Specifies the number of direct messages to try and retrieve, up to a
- maximum of 200. The value of count is best thought of as a limit to the
- number of Tweets to return because suspended or deleted content is
- removed after the count has been applied. [Optional]
- include_entities:
- The entities node will not be included when set to False.
- [Optional]
- skip_status:
- When set to True statuses will not be included in the returned user
- objects. [Optional]
- Returns:
- A sequence of twitter.DirectMessage instances
- '''
- url = '%s/direct_messages.json' % self.base_url
- if not self._oauth_consumer:
- raise TwitterError("The twitter.Api instance must be authenticated.")
- parameters = {}
- if since_id:
- parameters['since_id'] = since_id
- if max_id:
- parameters['max_id'] = max_id
- if count:
- try:
- parameters['count'] = int(count)
- except ValueError:
- raise TwitterError("count must be an integer")
- if not include_entities:
- parameters['include_entities'] = 'false'
- if skip_status:
- parameters['skip_status'] = 1
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- return [DirectMessage.NewFromJsonDict(x) for x in data]
- def GetSentDirectMessages(self, since_id=None, max_id=None, count=None, page=None, include_entities=True):
- '''Returns a list of the direct messages sent by the authenticating user.
- The twitter.Api instance must be authenticated.
- Args:
- since_id:
- Returns results with an ID greater than (that is, more recent
- than) the specified ID. There are limits to the number of
- Tweets which can be accessed through the API. If the limit of
- Tweets has occured since the since_id, the since_id will be
- forced to the oldest ID available. [Optional]
- max_id:
- Returns results with an ID less than (that is, older than) or
- equal to the specified ID. [Optional]
- count:
- Specifies the number of direct messages to try and retrieve, up to a
- maximum of 200. The value of count is best thought of as a limit to the
- number of Tweets to return because suspended or deleted content is
- removed after the count has been applied. [Optional]
- page:
- Specifies the page of results to retrieve.
- Note: there are pagination limits. [Optional]
- include_entities:
- The entities node will not be included when set to False.
- [Optional]
- Returns:
- A sequence of twitter.DirectMessage instances
- '''
- url = '%s/direct_messages/sent.json' % self.base_url
- if not self._oauth_consumer:
- raise TwitterError("The twitter.Api instance must be authenticated.")
- parameters = {}
- if since_id:
- parameters['since_id'] = since_id
- if page:
- parameters['page'] = page
- if max_id:
- parameters['max_id'] = max_id
- if count:
- try:
- parameters['count'] = int(count)
- except ValueError:
- raise TwitterError("count must be an integer")
- if not include_entities:
- parameters['include_entities'] = 'false'
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- return [DirectMessage.NewFromJsonDict(x) for x in data]
- def PostDirectMessage(self, text, user_id=None, screen_name=None):
- '''Post a twitter direct message from the authenticated user
- The twitter.Api instance must be authenticated. user_id or screen_name
- must be specified.
- Args:
- text: The message text to be posted. Must be less than 140 characters.
- user_id:
- The ID of the user who should receive the direct message.
- [Optional]
- screen_name:
- The screen name of the user who should receive the direct message.
- [Optional]
- Returns:
- A twitter.DirectMessage instance representing the message posted
- '''
- if not self._oauth_consumer:
- raise TwitterError("The twitter.Api instance must be authenticated.")
- url = '%s/direct_messages/new.json' % self.base_url
- data = {'text': text}
- if self.source_api == "api.twitter.com" and user_id:
- data['user_id'] = user_id
- elif self.source_api != "api.twitter.com" and user_id:
- data['screen_name'] = user_id
- elif screen_name:
- data['screen_name'] = screen_name
- else:
- raise TwitterError("Specify at least one of user_id or screen_name.")
- json = self._FetchUrl(url, post_data=data)
- data = self._ParseAndCheckTwitter(json)
- return DirectMessage.NewFromJsonDict(data)
- def DestroyDirectMessage(self, id, include_entities=True):
- '''Destroys the direct message specified in the required ID parameter.
- The twitter.Api instance must be authenticated, and the
- authenticating user must be the recipient of the specified direct
- message.
- Args:
- id: The id of the direct message to be destroyed
- Returns:
- A twitter.DirectMessage instance representing the message destroyed
- '''
- url = '%s/direct_messages/destroy.json' % self.base_url
- data = {'id': id}
- if not include_entities:
- data['include_entities'] = 'false'
- json = self._FetchUrl(url, post_data=data)
- data = self._ParseAndCheckTwitter(json)
- return DirectMessage.NewFromJsonDict(data)
- def CreateFriendship(self, user_id=None, screen_name=None, follow=True):
- '''Befriends the user specified by the user_id or screen_name.
- The twitter.Api instance must be authenticated.
- Args:
- user_id:
- A user_id to follow [Optional]
- screen_name:
- A screen_name to follow [Optional]
- follow:
- Set to False to disable notifications for the target user
- Returns:
- A twitter.User instance representing the befriended user.
- '''
- url = '%s/friendships/create.json' % (self.base_url)
- data = {}
- if self.source_api != "api.twitter.com" and user_id:
- data['screen_name'] = user_id
- elif user_id:
- data['user_id'] = user_id
- elif screen_name:
- data['screen_name'] = screen_name
- else:
- raise TwitterError("Specify at least one of user_id or screen_name.")
- if follow:
- data['follow'] = 'true'
- else:
- data['follow'] = 'false'
- json = self._FetchUrl(url, post_data=data)
- data = self._ParseAndCheckTwitter(json)
- return User.NewFromJsonDict(data)
- def DestroyFriendship(self, user_id=None, screen_name=None):
- '''Discontinues friendship with a user_id or screen_name.
- The twitter.Api instance must be authenticated.
- Args:
- user_id:
- A user_id to unfollow [Optional]
- screen_name:
- A screen_name to unfollow [Optional]
- Returns:
- A twitter.User instance representing the discontinued friend.
- '''
- url = '%s/friendships/destroy.json' % self.base_url
- data = {}
- if self.source_api != "api.twitter.com" and user_id:
- data['screen_name'] = user_id
- elif user_id:
- data['user_id'] = user_id
- elif screen_name:
- data['screen_name'] = screen_name
- else:
- raise TwitterError("Specify at least one of user_id or screen_name.")
- json = self._FetchUrl(url, post_data=data)
- data = self._ParseAndCheckTwitter(json)
- return User.NewFromJsonDict(data)
- def CreateFavorite(self, status=None, id=None, include_entities=True):
- '''Favorites the specified status object or id as the authenticating user.
- Returns the favorite status when successful.
- The twitter.Api instance must be authenticated.
- Args:
- id:
- The id of the twitter status to mark as a favorite.
- [Optional]
- status:
- The twitter.Status object to mark as a favorite.
- [Optional]
- include_entities:
- The entities node will be omitted when set to False.
- Returns:
- A twitter.Status instance representing the newly-marked favorite.
- '''
- url = '%s/favorites/create.json' % self.base_url
- data = {}
- if id:
- data['id'] = id
- elif isinstance(status, str):
- data['id'] = status
- elif status:
- data['id'] = status.id
- else:
- raise TwitterError("Specify id or status")
- if not include_entities:
- data['include_entities'] = 'false'
- json = self._FetchUrl(url, post_data=data)
- data = self._ParseAndCheckTwitter(json)
- return Status.NewFromJsonDict(data)
- def DestroyFavorite(self, status=None, id=None, include_entities=True):
- '''Un-Favorites the specified status object or id as the authenticating user.
- Returns the un-favorited status when successful.
- The twitter.Api instance must be authenticated.
- Args:
- id:
- The id of the twitter status to unmark as a favorite.
- [Optional]
- status:
- The twitter.Status object to unmark as a favorite.
- [Optional]
- include_entities:
- The entities node will be omitted when set to False.
- Returns:
- A twitter.Status instance representing the newly-unmarked favorite.
- '''
- url = '%s/favorites/destroy.json' % self.base_url
- data = {}
- if id:
- data['id'] = id
- elif isinstance(status, str):
- data['id'] = status
- elif status:
- data['id'] = status.id
- else:
- raise TwitterError("Specify id or status")
- if not include_entities:
- data['include_entities'] = 'false'
- json = self._FetchUrl(url, post_data=data)
- data = self._ParseAndCheckTwitter(json)
- return Status.NewFromJsonDict(data)
- def GetFavorites(self,
- user_id=None,
- screen_name=None,
- count=None,
- since_id=None,
- max_id=None,
- include_entities=True):
- '''Return a list of Status objects representing favorited tweets.
- By default, returns the (up to) 20 most recent tweets for the
- authenticated user.
- Args:
- user:
- The twitter name or id of the user whose favorites you are fetching.
- If not specified, defaults to the authenticated user. [Optional]
- page:
- Specifies the page of results to retrieve.
- Note: there are pagination limits. [Optional]
- '''
- parameters = {}
- url = '%s/favorites/list.json' % self.base_url
- if self.source_api == "api.twitter.com" and user_id:
- parameters['user_id'] = user_id
- elif self.source_api == "api.twitter.com" and screen_name:
- parameters['screen_name'] = user_id
- if since_id:
- try:
- parameters['since_id'] = long(since_id)
- except ValueError:
- raise TwitterError("since_id must be an integer")
- if max_id:
- try:
- parameters['max_id'] = long(max_id)
- except ValueError:
- raise TwitterError("max_id must be an integer")
- if count:
- try:
- parameters['count'] = int(count)
- except ValueError:
- raise TwitterError("count must be an integer")
- if include_entities:
- parameters['include_entities'] = True
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- return [Status.NewFromJsonDict(x) for x in data]
- def GetMentions(self,
- count=None,
- since_id=None,
- max_id=None,
- trim_user=False,
- contributor_details=False,
- include_entities=True):
- '''Returns the 20 most recent mentions (status containing @screen_name)
- for the authenticating user.
- Args:
- count:
- Specifies the number of tweets to try and retrieve, up to a maximum of
- 200. The value of count is best thought of as a limit to the number of
- tweets to return because suspended or deleted content is removed after
- the count has been applied. [Optional]
- since_id:
- Returns results with an ID greater than (that is, more recent
- than) the specified ID. There are limits to the number of
- Tweets which can be accessed through the API. If the limit of
- Tweets has occurred since the since_id, the since_id will be
- forced to the oldest ID available. [Optional]
- max_id:
- Returns only statuses with an ID less than
- (that is, older than) the specified ID. [Optional]
- trim_user:
- When set to True, each tweet returned in a timeline will include a user
- object including only the status authors numerical ID. Omit this
- parameter to receive the complete user object.
- contributor_details:
- If set to True, this parameter enhances the contributors element of the
- status response to include the screen_name of the contributor. By
- default only the user_id of the contributor is included.
- include_entities:
- The entities node will be disincluded when set to False.
- Returns:
- A sequence of twitter.Status instances, one for each mention of the user.
- '''
- url = '%s/statuses/mentions_timeline.json' % self.base_url
- if not self._oauth_consumer:
- raise TwitterError("The twitter.Api instance must be authenticated.")
- parameters = {}
- if count:
- try:
- parameters['count'] = int(count)
- except ValueError:
- raise TwitterError("count must be an integer")
- if since_id:
- try:
- parameters['since_id'] = long(since_id)
- except ValueError:
- raise TwitterError("since_id must be an integer")
- if max_id:
- try:
- parameters['max_id'] = long(max_id)
- except ValueError:
- raise TwitterError("max_id must be an integer")
- if trim_user:
- parameters['trim_user'] = 1
- if contributor_details:
- parameters['contributor_details'] = 'true'
- if not include_entities:
- parameters['include_entities'] = 'false'
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- return [Status.NewFromJsonDict(x) for x in data]
- def CreateList(self, name, mode=None, description=None):
- '''Creates a new list with the give name for the authenticated user.
- The twitter.Api instance must be authenticated.
- Args:
- name:
- New name for the list
- mode:
- 'public' or 'private'.
- Defaults to 'public'. [Optional]
- description:
- Description of the list. [Optional]
- Returns:
- A twitter.List instance representing the new list
- '''
- url = '%s/lists/create.json' % self.base_url
- if not self._oauth_consumer:
- raise TwitterError("The twitter.Api instance must be authenticated.")
- parameters = {'name': name}
- if mode is not None:
- parameters['mode'] = mode
- if description is not None:
- parameters['description'] = description
- json = self._FetchUrl(url, post_data=parameters)
- data = self._ParseAndCheckTwitter(json)
- return List.NewFromJsonDict(data)
- def DestroyList(self,
- owner_screen_name=False,
- owner_id=False,
- list_id=None,
- slug=None):
- '''
- Destroys the list identified by list_id or owner_screen_name/owner_id and
- slug.
- The twitter.Api instance must be authenticated.
- Args:
- owner_screen_name:
- The screen_name of the user who owns the list being requested by a slug.
- owner_id:
- The user ID of the user who owns the list being requested by a slug.
- list_id:
- The numerical id of the list.
- slug:
- You can identify a list by its slug instead of its numerical id. If you
- decide to do so, note that you'll also have to specify the list owner
- using the owner_id or owner_screen_name parameters.
- Returns:
- A twitter.List instance representing the removed list.
- '''
- url = '%s/lists/destroy.json' % self.base_url
- data = {}
- if list_id:
- try:
- data['list_id']= long(list_id)
- except ValueError:
- raise TwitterError("list_id must be an integer")
- elif slug:
- data['slug'] = slug
- if owner_id:
- try:
- data['owner_id'] = long(owner_id)
- except ValueError:
- raise TwitterError("owner_id must be an integer")
- elif owner_screen_name:
- data['owner_screen_name'] = owner_screen_name
- else:
- raise TwitterError("Identify list by list_id or owner_screen_name/owner_id and slug")
- else:
- raise TwitterError("Identify list by list_id or owner_screen_name/owner_id and slug")
- json = self._FetchUrl(url, post_data=data)
- data = self._ParseAndCheckTwitter(json)
- return List.NewFromJsonDict(data)
- def CreateSubscription(self,
- owner_screen_name=False,
- owner_id=False,
- list_id=None,
- slug=None):
- '''Creates a subscription to a list by the authenticated user
- The twitter.Api instance must be authenticated.
- Args:
- owner_screen_name:
- The screen_name of the user who owns the list being requested by a slug.
- owner_id:
- The user ID of the user who owns the list being requested by a slug.
- list_id:
- The numerical id of the list.
- slug:
- You can identify a list by its slug instead of its numerical id. If you
- decide to do so, note that you'll also have to specify the list owner
- using the owner_id or owner_screen_name parameters.
- Returns:
- A twitter.List instance representing the list subscribed to
- '''
- url = '%s/lists/subscribers/create.json' % (self.base_url)
- if not self._oauth_consumer:
- raise TwitterError("The twitter.Api instance must be authenticated.")
- data = {}
- if list_id:
- try:
- data['list_id']= long(list_id)
- except ValueError:
- raise TwitterError("list_id must be an integer")
- elif slug:
- data['slug'] = slug
- if owner_id:
- try:
- data['owner_id'] = long(owner_id)
- except ValueError:
- raise TwitterError("owner_id must be an integer")
- elif owner_screen_name:
- data['owner_screen_name'] = owner_screen_name
- else:
- raise TwitterError("Identify list by list_id or owner_screen_name/owner_id and slug")
- else:
- raise TwitterError("Identify list by list_id or owner_screen_name/owner_id and slug")
- json = self._FetchUrl(url, post_data=data)
- data = self._ParseAndCheckTwitter(json)
- return List.NewFromJsonDict(data)
- def DestroySubscription(self,
- owner_screen_name=False,
- owner_id=False,
- list_id=None,
- slug=None):
- '''Destroys the subscription to a list for the authenticated user
- The twitter.Api instance must be authenticated.
- Args:
- owner_screen_name:
- The screen_name of the user who owns the list being requested by a slug.
- owner_id:
- The user ID of the user who owns the list being requested by a slug.
- list_id:
- The numerical id of the list.
- slug:
- You can identify a list by its slug instead of its numerical id. If you
- decide to do so, note that you'll also have to specify the list owner
- using the owner_id or owner_screen_name parameters.
- Returns:
- A twitter.List instance representing the removed list.
- '''
- url = '%s/lists/subscribers/destroy.json' % (self.base_url)
- if not self._oauth_consumer:
- raise TwitterError("The twitter.Api instance must be authenticated.")
- data = {}
- if list_id:
- try:
- data['list_id']= long(list_id)
- except ValueError:
- raise TwitterError("list_id must be an integer")
- elif slug:
- data['slug'] = slug
- if owner_id:
- try:
- data['owner_id'] = long(owner_id)
- except ValueError:
- raise TwitterError("owner_id must be an integer")
- elif owner_screen_name:
- data['owner_screen_name'] = owner_screen_name
- else:
- raise TwitterError("Identify list by list_id or owner_screen_name/owner_id and slug")
- else:
- raise TwitterError("Identify list by list_id or owner_screen_name/owner_id and slug")
- json = self._FetchUrl(url, post_data=data)
- data = self._ParseAndCheckTwitter(json)
- return List.NewFromJsonDict(data)
- def GetSubscriptions(self, user_id=None, screen_name=None, count=20, cursor=-1):
- '''
- Obtain a collection of the lists the specified user is subscribed to, 20
- lists per page by default. Does not include the user's own lists.
- The twitter.Api instance must be authenticated.
- Args:
- user_id:
- The ID of the user for whom to return results for. [Optional]
- screen_name:
- The screen name of the user for whom to return results for.
- [Optional]
- count:
- The amount of results to return per page. Defaults to 20.
- No more than 1000 results will ever be returned in a single page.
- cursor:
- "page" value that Twitter will use to start building the
- list sequence from. -1 to start at the beginning.
- Twitter will return in the result the values for next_cursor
- and previous_cursor. [Optional]
- Returns:
- A sequence of twitter.List instances, one for each list
- '''
- if not self._oauth_consumer:
- raise TwitterError("twitter.Api instance must be authenticated")
- url = '%s/lists/subscriptions.json' % (self.base_url)
- parameters = {}
- try:
- parameters['cursor'] = int(cursor)
- except ValueError:
- raise TwitterError("cursor must be an integer")
- try:
- parameters['count'] = int(count)
- except ValueError:
- raise TwitterError("count must be an integer")
- if user_id is not None:
- try:
- parameters['user_id'] = long(user_id)
- except ValueError:
- raise TwitterError('user_id must be an integer')
- elif screen_name is not None:
- parameters['screen_name'] = screen_name
- else:
- raise TwitterError('Specify user_id or screen_name')
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- return [List.NewFromJsonDict(x) for x in data['lists']]
- def GetLists(self, user_id=None, screen_name=None, count=None, cursor=-1):
- '''Fetch the sequence of lists for a user.
- The twitter.Api instance must be authenticated.
- Args:
- user_id:
- The ID of the user for whom to return results for. [Optional]
- screen_name:
- The screen name of the user for whom to return results for.
- [Optional]
- count:
- The amount of results to return per page. Defaults to 20. No more than
- 1000 results will ever be returned in a single page.
- [Optional]
- cursor:
- "page" value that Twitter will use to start building the
- list sequence from. -1 to start at the beginning.
- Twitter will return in the result the values for next_cursor
- and previous_cursor. [Optional]
- Returns:
- A sequence of twitter.List instances, one for each list
- '''
- if not self._oauth_consumer:
- raise TwitterError("twitter.Api instance must be authenticated")
- url = '%s/lists/ownerships.json' % self.base_url
- result = []
- parameters = {}
- if user_id is not None:
- try:
- parameters['user_id'] = long(user_id)
- except ValueError:
- raise TwitterError('user_id must be an integer')
- elif screen_name is not None:
- parameters['screen_name'] = screen_name
- else:
- raise TwitterError('Specify user_id or screen_name')
- if count is not None:
- parameters['count'] = count
- while True:
- parameters['cursor'] = cursor
- json = self._FetchUrl(url, parameters=parameters)
- data = self._ParseAndCheckTwitter(json)
- result += [List.NewFromJsonDict(x) for x in data['lists']]
- if 'next_cursor' in data:
- if data['next_cursor'] == 0 or data['next_cursor'] == data['previous_cursor']:
- break
- else:
- cursor = data['next_cursor']
- else:
- break
- return result
- def VerifyCredentials(self):
- '''Returns a twitter.User instance if the authenticating user is valid.
- Returns:
- A twitter.User instance representing that user if the
- credentials are valid, None otherwise.
- '''
- if not self._oauth_consumer:
- raise TwitterError("Api instance must first be given user credentials.")
- url = '%s/account/verify_credentials.json' % self.base_url
- try:
- json = self._FetchUrl(url, no_cache=True)
- except urllib2.HTTPError, http_error:
- if http_error.code == httplib.UNAUTHORIZED:
- return None
- else:
- raise http_error
- data = self._ParseAndCheckTwitter(json)
- return User.NewFromJsonDict(data)
- def SetCache(self, cache):
- '''Override the default cache. Set to None to prevent caching.
- Args:
- cache:
- An instance that supports the same API as the twitter._FileCache
- '''
- if cache == DEFAULT_CACHE:
- self._cache = _FileCache()
- else:
- self._cache = cache
- def SetUrllib(self, urllib):
- '''Override the default urllib implementation.
- Args:
- urllib:
- An instance that supports the same API as the urllib2 module
- '''
- self._urllib = urllib
- def SetCacheTimeout(self, cache_timeout):
- '''Override the default cache timeout.
- Args:
- cache_timeout:
- Time, in seconds, that responses should be reused.
- '''
- self._cache_timeout = cache_timeout
- def SetUserAgent(self, user_agent):
- '''Override the default user agent
- Args:
- user_agent:
- A string that should be send to the server as the User-agent
- '''
- self._request_headers['User-Agent'] = user_agent
- def SetXTwitterHeaders(self, client, url, version):
- '''Set the X-Twitter HTTP headers that will be sent to the server.
- Args:
- client:
- The client name as a string. Will be sent to the server as
- the 'X-Twitter-Client' header.
- url:
- The URL of the meta.xml as a string. Will be sent to the server
- as the 'X-Twitter-Client-URL' header.
- version:
- The client version as a string. Will be sent to the server
- as the 'X-Twitter-Client-Version' header.
- '''
- self._request_headers['X-Twitter-Client'] = client
- self._request_headers['X-Twitter-Client-URL'] = url
- self._request_headers['X-Twitter-Client-Version'] = version
- def SetSource(self, source):
- '''Suggest the "from source" value to be displayed on the Twitter web site.
- The value of the 'source' parameter must be first recognized by
- the Twitter server. New source values are authorized on a case by
- case basis by the Twitter development team.
- Args:
- source:
- The source name as a string. Will be sent to the server as
- the 'source' parameter.
- '''
- self._default_params['source'] = source
- def GetRateLimitStatus(self, resources=None):
- '''Fetch the rate limit status for the currently authorized user.
- Args:
- resources:
- A comma seperated list of resource families you want to know the current
- rate limit disposition of.
- [Optional]
- Returns:
- A dictionary containing the time the limit will reset (reset_time),
- the number of remaining hits allowed before the reset (remaining_hits),
- the number of hits allowed in a 60-minute period (hourly_limit), and
- the time of the reset in seconds since The Epoch (reset_time_in_seconds).
- '''
- parameters = {}
- if resources is not None:
- parameters['resources'] = resources
- url = '%s/application/rate_limit_status.json' % self.base_url
- json = self._FetchUrl(url, parameters=parameters, no_cache=True)
- data = self._ParseAndCheckTwitter(json)
- return data
- def MaximumHitFrequency(self):
- '''Determines the minimum number of seconds that a program must wait
- before hitting the server again without exceeding the rate_limit
- imposed for the currently authenticated user.
- Returns:
- The minimum second interval that a program must use so as to not
- exceed the rate_limit imposed for the user.
- '''
- rate_status = self.GetRateLimitStatus()
- reset_time = rate_status.get('reset_time', None)
- limit = rate_status.get('remaining_hits', None)
- if reset_time:
- # put the reset time into a datetime object
- reset = datetime.datetime(*rfc822.parsedate(reset_time)[:7])
- # find the difference in time between now and the reset time + 1 hour
- delta = reset + datetime.timedelta(hours=1) - datetime.datetime.utcnow()
- if not limit:
- return int(delta.seconds)
- # determine the minimum number of seconds allowed as a regular interval
- max_frequency = int(delta.seconds / limit) + 1
- # return the number of seconds
- return max_frequency
- return 60
- def _BuildUrl(self, url, path_elements=None, extra_params=None):
- # Break url into constituent parts
- (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url)
- # Add any additional path elements to the path
- if path_elements:
- # Filter out the path elements that have a value of None
- p = [i for i in path_elements if i]
- if not path.endswith('/'):
- path += '/'
- path += '/'.join(p)
- # Add any additional query parameters to the query string
- if extra_params and len(extra_params) > 0:
- extra_query = self._EncodeParameters(extra_params)
- # Add it to the existing query
- if query:
- query += '&' + extra_query
- else:
- query = extra_query
- # Return the rebuilt URL
- return urlparse.urlunparse((scheme, netloc, path, params, query, fragment))
- def _InitializeRequestHeaders(self, request_headers):
- if request_headers:
- self._request_headers = request_headers
- else:
- self._request_headers = {}
- def _InitializeUserAgent(self):
- user_agent = 'Python-urllib/%s (python-twitter/%s)' % \
- (self._urllib.__version__, __version__)
- self.SetUserAgent(user_agent)
- def _InitializeDefaultParameters(self):
- self._default_params = {}
- def _DecompressGzippedResponse(self, response):
- raw_data = response.read()
- if response.headers.get('content-encoding', None) == 'gzip':
- url_data = gzip.GzipFile(fileobj=StringIO.StringIO(raw_data)).read()
- else:
- url_data = raw_data
- return url_data
- def _Encode(self, s):
- if self._input_encoding:
- return unicode(s, self._input_encoding).encode('utf-8')
- else:
- return unicode(s).encode('utf-8')
- def _EncodeParameters(self, parameters):
- '''Return a string in key=value&key=value form
- Values of None are not included in the output string.
- Args:
- parameters:
- A dict of (key, value) tuples, where value is encoded as
- specified by self._encoding
- Returns:
- A URL-encoded string in "key=value&key=value" form
- '''
- if parameters is None:
- return None
- else:
- return urllib.urlencode(dict([(k, self._Encode(v)) for k, v in parameters.items() if v is not None]))
- def _EncodePostData(self, post_data):
- '''Return a string in key=value&key=value form
- Values are assumed to be encoded in the format specified by self._encoding,
- and are subsequently URL encoded.
- Args:
- post_data:
- A dict of (key, value) tuples, where value is encoded as
- specified by self._encoding
- Returns:
- A URL-encoded string in "key=value&key=value" form
- '''
- if post_data is None:
- return None
- else:
- return urllib.urlencode(dict([(k, self._Encode(v)) for k, v in post_data.items()]))
- def _ParseAndCheckTwitter(self, json):
- """Try and parse the JSON returned from Twitter and return
- an empty dictionary if there is any error. This is a purely
- defensive check because during some Twitter network outages
- it will return an HTML failwhale page."""
- try:
- data = simplejson.loads(json)
- self._CheckForTwitterError(data)
- except ValueError:
- if "<title>Twitter / Over capacity</title>" in json:
- raise TwitterError("Capacity Error")
- if "<title>Twitter / Error</title>" in json:
- raise TwitterError("Technical Error")
- raise TwitterError("json decoding")
- return data
- def _CheckForTwitterError(self, data):
- """Raises a TwitterError if twitter returns an error message.
- Args:
- data:
- A python dict created from the Twitter json response
- Raises:
- TwitterError wrapping the twitter error message if one exists.
- """
- # Twitter errors are relatively unlikely, so it is faster
- # to check first, rather than try and catch the exception
- if 'error' in data:
- raise TwitterError(data['error'])
- if 'errors' in data:
- raise TwitterError(data['errors'])
- def _FetchUrl(self,
- url,
- post_data=None,
- parameters=None,
- no_cache=None,
- use_gzip_compression=None):
- '''Fetch a URL, optionally caching for a specified time.
- Args:
- url:
- The URL to retrieve
- post_data:
- A dict of (str, unicode) key/value pairs.
- If set, POST will be used.
- parameters:
- A dict whose key/value pairs should encoded and added
- to the query string. [Optional]
- no_cache:
- If true, overrides the cache on the current request
- use_gzip_compression:
- If True, tells the server to gzip-compress the response.
- It does not apply to POST requests.
- Defaults to None, which will get the value to use from
- the instance variable self._use_gzip [Optional]
- Returns:
- A string containing the body of the response.
- '''
- # Build the extra parameters dict
- extra_params = {}
- if self._default_params:
- extra_params.update(self._default_params)
- if parameters:
- extra_params.update(parameters)
- if post_data:
- http_method = "POST"
- else:
- http_method = "GET"
- if self._debugHTTP:
- _debug = 1
- else:
- _debug = 0
- http_handler = self._urllib.HTTPHandler(debuglevel=_debug)
- https_handler = self._urllib.HTTPSHandler(debuglevel=_debug)
- if self.http_proxy is None :
- proxy_status = False
- else :
- proxy_status = True
- opener = self._urllib.OpenerDirector()
- opener.add_handler(http_handler)
- opener.add_handler(https_handler)
- if proxy_status is True :
- proxy_handler = self._urllib.ProxyHandler({'http':str(self.http_proxy),'https': str(self.http_proxy)})
- opener.add_handler(proxy_handler)
- if use_gzip_compression is None:
- use_gzip = self._use_gzip
- else:
- use_gzip = use_gzip_compression
- # Set up compression
- if use_gzip and not post_data:
- opener.addheaders.append(('Accept-Encoding', 'gzip'))
- if self._oauth_consumer is not None:
- if post_data and http_method == "POST":
- parameters = post_data.copy()
- req = oauth.Request.from_consumer_and_token(self._oauth_consumer,
- token=self._oauth_token,
- http_method=http_method,
- http_url=url, parameters=parameters)
- req.sign_request(self._signature_method_hmac_sha1, self._oauth_consumer, self._oauth_token)
- headers = req.to_header()
- if http_method == "POST":
- encoded_post_data = req.to_postdata()
- else:
- encoded_post_data = None
- url = req.to_url()
- else:
- url = self._BuildUrl(url, extra_params=extra_params)
- encoded_post_data = self._EncodePostData(post_data)
- # Open and return the URL immediately if we're not going to cache
- if encoded_post_data or no_cache or not self._cache or not self._cache_timeout:
- response = opener.open(url, encoded_post_data)
- url_data = self._DecompressGzippedResponse(response)
- opener.close()
- else:
- # Unique keys are a combination of the url and the oAuth Consumer Key
- if self._consumer_key:
- key = self._consumer_key + ':' + url
- else:
- key = url
- # See if it has been cached before
- last_cached = self._cache.GetCachedTime(key)
- # If the cached version is outdated then fetch another and store it
- if not last_cached or time.time() >= last_cached + self._cache_timeout:
- try:
- response = opener.open(url, encoded_post_data)
- url_data = self._DecompressGzippedResponse(response)
- self._cache.Set(key, url_data)
- except urllib2.HTTPError, e:
- print e
- opener.close()
- else:
- url_data = self._cache.Get(key)
- # Always return the latest version
- return url_data
- class _FileCacheError(Exception):
- '''Base exception class for FileCache related errors'''
- class _FileCache(object):
- DEPTH = 3
- def __init__(self,root_directory=None):
- self._InitializeRootDirectory(root_directory)
- def Get(self,key):
- path = self._GetPath(key)
- if os.path.exists(path):
- return open(path).read()
- else:
- return None
- def Set(self,key,data):
- path = self._GetPath(key)
- directory = os.path.dirname(path)
- if not os.path.exists(directory):
- os.makedirs(directory)
- if not os.path.isdir(directory):
- raise _FileCacheError('%s exists but is not a directory' % directory)
- temp_fd, temp_path = tempfile.mkstemp()
- temp_fp = os.fdopen(temp_fd, 'w')
- temp_fp.write(data)
- temp_fp.close()
- if not path.startswith(self._root_directory):
- raise _FileCacheError('%s does not appear to live under %s' %
- (path, self._root_directory))
- if os.path.exists(path):
- os.remove(path)
- os.rename(temp_path, path)
- def Remove(self,key):
- path = self._GetPath(key)
- if not path.startswith(self._root_directory):
- raise _FileCacheError('%s does not appear to live under %s' %
- (path, self._root_directory ))
- if os.path.exists(path):
- os.remove(path)
- def GetCachedTime(self,key):
- path = self._GetPath(key)
- if os.path.exists(path):
- return os.path.getmtime(path)
- else:
- return None
- def _GetUsername(self):
- '''Attempt to find the username in a cross-platform fashion.'''
- try:
- return os.getenv('USER') or \
- os.getenv('LOGNAME') or \
- os.getenv('USERNAME') or \
- os.getlogin() or \
- 'nobody'
- except (AttributeError, IOError, OSError), e:
- return 'nobody'
- def _GetTmpCachePath(self):
- username = self._GetUsername()
- cache_directory = 'python.cache_' + username
- return os.path.join(tempfile.gettempdir(), cache_directory)
- def _InitializeRootDirectory(self, root_directory):
- if not root_directory:
- root_directory = self._GetTmpCachePath()
- root_directory = os.path.abspath(root_directory)
- if not os.path.exists(root_directory):
- os.mkdir(root_directory)
- if not os.path.isdir(root_directory):
- raise _FileCacheError('%s exists but is not a directory' %
- root_directory)
- self._root_directory = root_directory
- def _GetPath(self,key):
- try:
- hashed_key = md5(key).hexdigest()
- except TypeError:
- hashed_key = md5.new(key).hexdigest()
- return os.path.join(self._root_directory,
- self._GetPrefix(hashed_key),
- hashed_key)
- def _GetPrefix(self,hashed_key):
- return os.path.sep.join(hashed_key[0:_FileCache.DEPTH])
|