ó řôMc@scdZddlZddlZddlmZddlmZddlmZm Z dZ dZ dZ d Z d Zd Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZdZe eBZeeBZe e BZ e e BeBeBeBeBeBeBeBZ!e dfe dfe dfe dfedfedfed fed!fed"fed#fed$fed%fed&fed'fed(fed)fed*fed+fed,fed-fgZ"d.„Z#d/e$fd0„ƒYZ%d1ee$fd2„ƒYZ&e j'Z'd1d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKgZ(dS(Ls  This module provides support for Twisted to linux inotify API. In order to use this support, simply do the following (and start a reactor at some point):: from twisted.internet import inotify from twisted.python import filepath def notify(ignored, filepath, mask): """ For historical reasons, an opaque handle is passed as first parameter. This object should never be used. @param filepath: FilePath on which the event happened. @param mask: inotify event as hexadecimal masks """ print "event %s on %s" % ( ', '.join(inotify.humanReadableMask(mask)), filepath) notifier = inotify.INotify() notifier.startReading() notifier.watch(filepath.FilePath("/some/directory"), callbacks=[notify]) @since: 10.1 i˙˙˙˙N(tfdesc(tFileDescriptor(tlogt_inotifyllllll l@l€lllll l@liii i@I€taccesstmodifytattribt close_writet close_nowritetopent moved_fromtmoved_totcreatetdeletet delete_selft move_selftunmounttqueue_overflowtignoredtonly_dirt dont_followtmask_addtis_dirtone_shotcCs;g}x.tD]&\}}||@r |j|ƒq q W|S(si Auxiliary function that converts an hexadecimal mask into a series of human readable flags. (t_FLAG_TO_HUMANtappend(tmasktstktv((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pythumanReadableMaskcs  t_WatchcBs)eZdZeedd„Zd„ZRS(sç Watch object that represents a Watch point in the filesystem. The user should let INotify to create these objects @ivar path: The path over which this watch point is monitoring @ivar mask: The events monitored by this watchpoint @ivar autoAdd: Flag that determines whether this watch point should automatically add created subdirectories @ivar callbacks: C{list} of callback functions that will be called when an event occurs on this watch. cCs=||_||_||_|dkr0g}n||_dS(N(tpathRtautoAddtNonet callbacks(tselfR RR!R#((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pyt__init__|s      cCs(x!|jD]}||||ƒq WdS(sL Callback function used by L{INotify} to dispatch an event. N(R#(R$tfilepathteventstcallback((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pyt_notify†sN(t__name__t __module__t__doc__t IN_WATCH_MASKtFalseR"R%R)(((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pyRps  tINotifycBs†eZdZeZd d„Zd„Zd„Zd„Zd„Z d„Z d„Z d„Z e ed ed „Zd „Zd „ZRS( s‘ The INotify file descriptor, it basically does everything related to INotify, from reading to notifying watch points. @ivar _buffer: a C{str} containing the data read from the inotify fd. @ivar _watchpoints: a C{dict} that maps from inotify watch ids to watchpoints objects @ivar _watchpaths: a C{dict} that maps from watched paths to the inotify watch ids cCsvtj|d|ƒ|jjƒ|_tj|jƒtj|jƒd|_t |_ d|_ i|_ i|_ dS(Ntreactorit(RR%Rtinitt_fdRtsetNonBlockingt_setCloseOnExect connectedtTruet_writeDisconnectedt_buffert _watchpointst _watchpaths(R$R0((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pyR%žs    cCsQ|jj|j|j|ƒ}t||||ƒ}||j|<||j|<|S(s~ Private helper that abstracts the use of ctypes. Calls the internal inotify API and checks for any errors after the call. If there's an error L{INotify._addWatch} can raise an INotifyError. If there's no error it proceeds creating a watchpoint and adding a watchpath for inverse lookup of the file descriptor from the path. (RtaddR3R RR:R;(R$R RR!R#twdtiwp((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pyt _addWatch´s   cCs?|jj|j|ƒ|jj|ƒ}|jj|jƒdS(s Private helper that abstracts the use of ctypes. Calls the internal inotify API to remove an fd from inotify then removes the corresponding watchpoint from the internal mapping together with the file descriptor from the watchpath. N(RtremoveR3R:tpopR;R (R$R=R>((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pyt_rmWatchČscCs`tj||ƒ|jdkr\ytj|jƒWq\tk rX}tj|dƒq\XndS(sR Release the inotify file descriptor and do the necessary cleanup is'Couldn't close INotify file descriptor.N(RtconnectionLostR3tostclosetOSErrorRterr(R$treasonte((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pyRCŐs cCs|jS(s‹ Get the underlying file descriptor from this inotify observer. Required by L{abstract.FileDescriptor} subclasses. (R3(R$((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pytfilenoáscCstj|j|jƒdS(sC Read some data from the observed file descriptors N(Rt readFromFDR3t_doRead(R$((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pytdoReadésc Csq|j|7_x[t|jƒdkrltjd|jdd!ƒ\}}}}|ru|jdd|!jdƒ}nd}|jd||_y|j|}Wntk rśqnX|j}|rŘ|j |ƒ}n|j ||ƒ|j rO|t @rO|t @rO|j|d|jdtd|jƒ} |jjd|j|j| ƒn|t@r|j|ƒqqWdS( sF Work on the data just read from the file descriptor. is=LLLLitRR!R#N(R9tlentstructtunpacktrstripR"R:tKeyErrorR tchildR)R!tIN_ISDIRt IN_CREATEtwatchRR7R#R0t callLatert _addChildrentIN_DELETE_SELFRB( R$tin_R=RtcookietsizetnameR>R tnew_wd((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pyRLđs.(      c CsĘy|jjƒ}Wntk r'dSXx›|D]“}|jƒrŸ|j|d|jdtd|jƒ}|j|t t Bƒ|j j d|j |j|ƒn|jƒr/|j|t tBƒq/q/WdS(sÖ This is a very private method, please don't even think about using it. Note that this is a fricking hack... it's because we cannot be fast enough in adding a watch to a directory and so we basically end up getting here too late if some operations have already been going on in the subdir, we basically need to catchup. This eventually ends up meaning that we generate double events, your app must be resistant. NRR!R#i(R tchildrenRFtisdirRWRR7R#R)RURVR0RXRYR:tisfiletIN_CLOSE_WRITE(R$R>tlistdirtfR=((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pyRYs       cCsˆ|rKx{|jƒD]1}|jƒr|j||||dtƒqqWn9|j|ƒ}|rd|S|tB}|j||||ƒSdS(sR Watch the 'mask' events in given path. Can raise C{INotifyError} when there's a problem while adding a directory. @param path: The path needing monitoring @type path: L{FilePath} @param mask: The events that should be watched @type mask: C{int} @param autoAdd: if True automatically add newly created subdirectories @type autoAdd: C{boolean} @param callbacks: A list of callbacks that should be called when an event happens in the given path. The callback should accept 3 arguments: (ignored, filepath, mask) @type callbacks: C{list} of callables @param recursive: Also add all the subdirectories in this path @type recursive: C{boolean} t recursiveN(twalkRaRWR.t _isWatchedRZR?(R$R RR!R#RfRTR=((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pyRWEs  cCsB|j|ƒ}|dkr1td|fƒ‚n |j|ƒdS(s˜ Remove the watch point monitoring the given path @param path: The path that should be ignored @type path: L{FilePath} s%r is not watchedN(RhR"RSRB(R$R R=((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pytignoress cCs|jj|dƒS(sĺ Helper function that checks if the path is already monitored and returns its watchdescriptor if so or None otherwise. @param path: The path that should be checked @type path: L{FilePath} N(R;tgetR"(R$R ((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pyRhsN(R*R+R,RR"R%R?RBRCRJRMRLRYR-R.RWRiRh(((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pyR/s      . '- RR-t IN_ACCESSt IN_MODIFYt IN_ATTRIBtIN_CLOSE_NOWRITERctIN_OPENt IN_MOVED_FROMt IN_MOVED_TORVt IN_DELETERZt IN_MOVE_SELFt IN_UNMOUNTt IN_Q_OVERFLOWt IN_IGNOREDt IN_ONLYDIRtIN_DONT_FOLLOWt IN_MASK_ADDRUt IN_ONESHOTtIN_CLOSEtIN_MOVEDt IN_CHANGED()R,RDRPttwisted.internetRttwisted.internet.abstractRttwisted.pythonRRRkRlRmRcRnRoRpRqRVRrRZRsRtRuRvRwRxRyRURzR{R|R}R-RRtobjectRR/t INotifyErrort__all__(((s</usr/lib/python2.7/dist-packages/twisted/internet/inotify.pytsx     &                    ý