
\}Nc           @   s  d  d l  Z  d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l Z d  d l	 Z	 d  d l
 Z
 d  d l Z d  d l Z d  d l Z d  d l Z d Z d d d     YZ d e f d     YZ d d d     YZ d	 d d
     YZ d d d     YZ d d d     YZ d d d     YZ d d d     YZ d e f d     YZ d e f d     YZ d S(   iNs   /var/lib/apt/listst   Addonc           B   s)   e  Z d  Z d   Z d   Z d   Z RS(   s    
    Indexer plugin wrapper
    c         K   s  t  j j |  |  _ t  j j |  j  d |  _ t j } z< t j j t  j j |   t	 j
 d |  j |  |  _ Wd  | t _ Xy |  j j |   |  _ Wn# t k
 r |  j j   |  _ n X|  j ry |  j j |   |  _ Wqt k
 r	|  j j   |  _ qXn  d  S(   Ni    s   axi.plugin_(   t   ost   patht   basenamet   filenamet   splitextt   namet   syst   appendt   dirnamet   impt   load_sourcet   modulet   initt   objt	   TypeErrort   info(   t   selft   fnamet   kwt   oldpath(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   __init__+   s     	 
	c         C   s&   t  |  j d  r" |  j j   n  d  S(   Nt   finished(   t   hasattrR   R   (   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR   >   s    c         K   s2   t  |  j d d   } | d  k	 r. | |   n  d  S(   Nt   send_extra_info(   t   getattrR   t   None(   R   R   t   func(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR   B   s    (   t   __name__t
   __module__t   __doc__R   R   R   (    (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR    '   s   		t   Pluginsc           B   s   e  Z d    Z d   Z RS(   c         K   s   d | k r |  j    | d <n  | j d d  } g  |  _ x t t j t j   D] } | d d	 k sS | j	 d  r qS n  t j
 j t j |  } t j
 j |  s qS n  | r | j d |  n  t | |  } | j d k rS |  j |  qS qS Wd S(
   sj   
        Read the plugins, in sorted order.

        Pass all the keyword args to the plugin init
        t   langst   progressi    t   .t   _s   .pys   Reading plugin %s.N(   R"   R#   (   t   scan_available_languagest   getR   t   disabledt   sortedR   t   listdirt   axit	   PLUGINDIRt   endswithR   t   joint   isfilet   verboseR    R   R   (   R   R   R!   R   t   fullnamet   addon(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR   H   s    	    c         C   sp   t    } t j d  } xQ t j t  D]@ } | j |  } | sI q( n  | j t j	 | j
 d    q( W| S(   Ns   _i18n_Translation-([^-]+)$i   (   t   sett   ret   compileR   R(   t
   APTLISTDIRt   searcht   addt   urllibt   unquotet   group(   R   R    t   tfilet   ft   mo(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR$   ]   s    	 #(   R   R   R   R$   (    (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR   G   s   	t   Progressc           B   sV   e  Z d  Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z	 d   Z
 RS(	   s*   
    Normal progress report to stdout
    c         C   s   d  |  _ t |  _ t |  _ d  S(   N(   R   t   taskt   Falset   halfwayt
   is_verbose(   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR   p   s    		c         C   s.   | |  _  d |  j  Gt j j   t |  _ d  S(   Ns   %s...(   R>   R   t   stdoutt   flusht   TrueR@   (   R   R>   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   begint   s    	c         C   s+   d |  j  | f Gt j j   t |  _ d  S(   Ns   %s... %d%%(   R>   R   RB   RC   RD   R@   (   R   t   percent(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR!   y   s    c         C   s   d |  j  GHt |  _ d  S(   Ns   %s: done.  (   R>   R?   R@   (   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   end}   s    c         G   s5   |  j  s d  S|  j r Hn  d j |  GHt |  _ d  S(   Nt    (   RA   R@   R,   R?   (   R   t   args(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR.      s    	 	c         G   s0   |  j  r Hn  t j d j |  IJt |  _  d  S(   NRH   (   R@   R   t   stderrR,   R?   (   R   RI   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   notice   s    	c         G   s0   |  j  r Hn  t j d j |  IJt |  _  d  S(   NRH   (   R@   R   RJ   R,   R?   (   R   RI   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   warning   s    	c         G   s0   |  j  r Hn  t j d j |  IJt |  _  d  S(   NRH   (   R@   R   RJ   R,   R?   (   R   RI   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   error   s    	(   R   R   R   R   RE   R!   RG   R.   RK   RL   RM   (    (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR=   l   s   							t   BatchProgressc           B   sV   e  Z d  Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z	 d   Z
 RS(	   s*   
    Machine readable progress report
    c         C   s   d  |  _ d  S(   N(   R   R>   (   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR      s    c         C   s%   | |  _  d |  j  Gt j j   d  S(   Ns
   begin: %s
(   R>   R   RB   RC   (   R   R>   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRE      s    	c         C   s   d | Gt  j j   d  S(   Ns   progress: %d/100
(   R   RB   RC   (   R   RF   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR!      s    c         C   s   d |  j  GHt j j   d  S(   Ns	   done: %s
(   R>   R   RB   RC   (   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRG      s    c         G   s#   d d j  |  GHt j j   d  S(   Ns   verbose: %sRH   (   R,   R   RB   RC   (   R   RI   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR.      s    c         G   s#   d d j  |  GHt j j   d  S(   Ns
   notice: %sRH   (   R,   R   RB   RC   (   R   RI   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRK      s    c         G   s#   d d j  |  GHt j j   d  S(   Ns   warning: %sRH   (   R,   R   RB   RC   (   R   RI   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRL      s    c         G   s#   d d j  |  GHt j j   d  S(   Ns	   error: %sRH   (   R,   R   RB   RC   (   R   RI   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRM      s    (   R   R   R   R   RE   R!   RG   R.   RK   RL   RM   (    (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRN      s   							t   SilentProgressc           B   sM   e  Z d  Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z	 RS(   s   
    Quiet progress report
    c         C   s   d  S(   N(    (   R   R>   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRE      s    c         C   s   d  S(   N(    (   R   RF   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR!      s    c         C   s   d  S(   N(    (   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRG      s    c         G   s   d  S(   N(    (   R   RI   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR.      s    c         G   s   d  S(   N(    (   R   RI   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRK      s    c         G   s   t  j d j |  IJd  S(   NRH   (   R   RJ   R,   (   R   RI   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRL      s    c         G   s   t  j d j |  IJd  S(   NRH   (   R   RJ   R,   (   R   RI   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRM      s    (
   R   R   R   RE   R!   RG   R.   RK   RL   RM   (    (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRO      s   						t   ClientProgressc           B   s    e  Z d  Z d   Z d   Z RS(   sZ   
    Client-side progress report, reporting progress from another running
    indexer
    c         C   sK   t  j  t  j t  j  |  _ |  j j d   |  j j t j  | |  _	 d  S(   N(
   t   sockett   AF_UNIXt   SOCK_STREAMt   sockt
   settimeoutR   t   connectR)   t   XAPIANDBUPDATESOCKR!   (   R   R!   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR      s    c         C   s  t  } xt r|  j j d  } y t j |  } Wn" t k
 rX |  j j d  d  SX| d } | d } | d k r |  j j	 |   t } q	 | d k r | s |  j j	 | d  t } n  |  j j | d   q	 | d k r| s|  j j	 | d  t } n  |  j j
 | d   q	 | d k r=|  j j |   q	 | d	 k r\|  j j |   q	 | d
 k r{|  j j |   q	 | d k rPq	 |  j j d | d j t t |   f  q	 Wd  S(   Ni   s   The other update has stoppedi    i   RE   R!   RG   R.   RK   RM   t   alldonesH   unknown action '%s' from other update-apt-xapian-index.  Arguments: '%s's   , (   R?   RD   RT   t   recvt   picklet   loadst   EOFErrorR!   RM   RE   RG   R.   RK   R,   t   mapt   repr(   R   t   hasBegunt   msgRI   t   action(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   loop   s@    	

			(   R   R   R   R   Rb   (    (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRP      s   	t   ServerSenderProgressc           B   sk   e  Z d  Z d d  Z d   Z d   Z d   Z d   Z d   Z	 d   Z
 d   Z d	   Z d
   Z RS(   s;   
    Server endpoint for client-server progress report
    c         C   s   | |  _  | |  _ d  S(   N(   RT   R>   (   R   RT   R>   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR      s    	c         C   s   |  j  t j d   d  S(   NRX   (   s   alldone(   t   _sendRZ   t   dumps(   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   __del__   s    c         C   s"   y |  j  j |  Wn n Xd  S(   N(   RT   t   send(   R   t   text(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRd      s    c         C   s,   | |  _  |  j t j d |  j  f   d  S(   NRE   (   R>   Rd   RZ   Re   (   R   R>   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRE     s    	c         C   s&   |  j  t j d |  j | f   d  S(   NR!   (   Rd   RZ   Re   R>   (   R   RF   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR!     s    c         C   s#   |  j  t j d |  j f   d  S(   NRG   (   Rd   RZ   Re   R>   (   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRG     s    c         G   s   |  j  t j d |   d  S(   NR.   (   s   verbose(   Rd   RZ   Re   (   R   RI   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR.   
  s    c         G   s   |  j  t j d |   d  S(   NRK   (   s   notice(   Rd   RZ   Re   (   R   RI   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRK     s    c         G   s   |  j  t j d |   d  S(   NRL   (   s   warning(   Rd   RZ   Re   (   R   RI   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRL     s    c         G   s   |  j  t j d |   d  S(   NRM   (   s   error(   Rd   RZ   Re   (   R   RI   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRM     s    N(   R   R   R   R   R   Rf   Rd   RE   R!   RG   R.   RK   RL   RM   (    (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRc      s   								t   ServerProgressc           B   sh   e  Z d  Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z	 d   Z
 d	   Z d
   Z RS(   sT   
    Send progress report to any progress object, as well as to client indexers
    c         C   s   d  |  _ | g |  _ t j |  _ y t j |  j  Wn t k
 rH n Xt	 j	 t	 j
 t	 j  |  _ |  j j t	 j t	 j d  |  j j t j  |  j j t  |  j j d  d  S(   Ni   i   (   R   R>   t   proxiedR)   RW   t   sockfileR   t   unlinkt   OSErrorRQ   RR   RS   RT   t
   setsockoptt
   SOL_SOCKETt   SO_REUSEADDRt   bindt   setblockingR?   t   listen(   R   t   mine(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR     s    	c         C   s!   |  j  j   t j |  j  d  S(   N(   RT   t   closeR   Rl   Rk   (   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRf   '  s    c         C   sl   y3 |  j  j   d } |  j j t | |  j   Wn2 t j k
 rg } | j d t	 j
 k rh   qh n Xd  S(   Ni    (   RT   t   acceptRj   R   Rc   R>   RQ   RM   RI   t   errnot   EAGAIN(   R   RT   t   e(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   _check*  s     
c         C   s8   |  j    | |  _ x |  j D] } | j |  q Wd  S(   N(   Rz   R>   Rj   RE   (   R   R>   t   x(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRE   2  s    
	 c         C   s/   |  j    x |  j D] } | j |  q Wd  S(   N(   Rz   Rj   R!   (   R   RF   R{   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR!   6  s    
 c         C   s,   |  j    x |  j D] } | j   q Wd  S(   N(   Rz   Rj   RG   (   R   R{   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRG   9  s    
 c         G   s/   |  j    x |  j D] } | j |   q Wd  S(   N(   Rz   Rj   R.   (   R   RI   R{   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR.   <  s    
 c         G   s/   |  j    x |  j D] } | j |   q Wd  S(   N(   Rz   Rj   RK   (   R   RI   R{   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRK   ?  s    
 c         G   s/   |  j    x |  j D] } | j |   q Wd  S(   N(   Rz   Rj   RL   (   R   RI   R{   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRL   B  s    
 c         G   s/   |  j    x |  j D] } | j |   q Wd  S(   N(   Rz   Rj   RM   (   R   RI   R{   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRM   E  s    
 (   R   R   R   R   Rf   Rz   RE   R!   RG   R.   RK   RL   RM   (    (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyRi     s   									t   ExecutionTimec           B   s8   e  Z d  Z d d l Z d d  Z d   Z d   Z RS(   s   
    Helper that can be used in with statements to have a simple
    measure of the timing of a particular block of code, e.g.
    with ExecutionTime("db flush"):
        db.flush()
    iNt    c         C   s   | |  _  d  S(   N(   R   (   R   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR   R  s    c         C   s   t  j    |  _ d  S(   N(   t   timet   now(   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt	   __enter__T  s    c         C   s#   d |  j  t j   |  j f GHd  S(   Ns   %s: %s(   R   R~   R   (   R   t   typet   valuet   stack(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   __exit__V  s    (   R   R   R   R~   R   R   R   (    (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR|   J  s
   	t   Indexerc           B   s   e  Z d  Z e d  Z d   Z d   Z d   Z d   Z d   Z	 e e
 d  Z d   Z d	   Z d
   Z d   Z d   Z d   Z d   Z d   Z i  d  Z d d  Z e j d  Z e j d  Z e j d  Z RS(   s   
    The indexer
    c         C   so   | |  _  | |  _ t | d t  |  _ d |  _ d  |  _ d  |  _ d  |  _	 |  j
 t j  |  j
 t j  d  S(   NRA   i    (   R!   t   quietaptR   R?   R.   t   ds_timestampR   t	   apt_cachet   pluginst   lockfdt   ensure_dir_existsR)   t   XAPIANDBPATHt   XAPIANCACHEPATH(   R   R!   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR   ]  s    						c         C   s[   y t  j |  WnC t k
 rV } | j t j k r;   qW t  j j |  sW   qW n Xd S(   sY   
        Create a directory if missing, but do not complain if it already exists
        N(   R   t   mkdirRm   Rw   t   EEXISTR   t   isdir(   R   t   pathnameRy   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR   n  s    c         C   s>   |  j  d k	 r t d   n  |  j   | |  j   |  _  d S(   s   
        Wrap the apt-cache in some proxy object.

        This is used to give tests some control over the apt cache results
        s'   the cache has already been instantiatedN(   R   R   t   RuntimeErrort   aptcache(   R   t   wrapper(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   _test_wrap_apt_cache}  s    
c         C   s   |  j  s d d  l } d d  l } |  j rU d | j j j f d     Y} |   } n d  } | j   | j	 d t
 d |  |  _  n  |  j  S(   Nit   AptSilentProgressc           B   s&   e  Z d    Z d   Z d d  Z RS(   c         S   s   d  S(   N(    (   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR     s    c         S   s   d  S(   N(    (   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   done  s    c         S   s   d  S(   N(    (   R   RF   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   update  s    N(   R   R   R   R   R   R   (    (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR     s   		t   memonlyR!   (   R   t   aptt   apt_pkgR   R!   Rh   t
   OpProgressR   t   init_configt   CacheRD   (   R   R   R   R   t   aptprogress(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR     s    		
c         C   s   t  j t j t  j t  j B |  _ y7 t j |  j t j	 t j
 B t |  j  |  _ t SWn> t k
 r } | j t j k s | j t j k r t S  n Xd S(   s   
        Lock the session to prevent further updates.

        @returns
          True if the session is locked
          False if another indexer is running
        N(   R   t   openR)   t   XAPIANDBLOCKt   O_RDWRt   O_CREATR   t   fcntlt   lockft   LOCK_EXt   LOCK_NBRi   R!   RD   t   IOErrorRw   t   EACCESRx   R?   (   R   Ry   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   lock  s    	"$c         C   s-   |  j  j d  t |  j   } | j   d S(   s{   
        Attach to a running indexer and report its progress.

        Return when the other indexer has finished.
        s8   Another update is already running: showing its progress.N(   R!   RK   RP   Rb   (   R   t   childProgress(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   slave  s    c   	      C   s  t  d |  j d |  |  _ t |  j  d k rK |  j j d t j  t St g  |  j D] } | j	 d ^ qX  |  _
 y7 t j j t j  r t j j t j  } n d } Wn- t k
 r } d } |  j j d |  n X|  j r'|  j j d t j |  j
   |  j j d t j |   n  | d k rt |  j
 d	  t | d	  k r| rv|  j j d
 t j  q|  j j d t j  t Sn  |  j j d  t j d t  \ |  _ |  _ t |  j j    d } xz |  j D]o } xf | j	 j d g   D]O } | d |  j k r qn  | |  j | d <| d 7} | d |  j | d <qWqW|  j j d  x3 |  j D]( } | j j t d |  j  |  j  qrWt S(   s   
        Setup indexing: read plugins, check timestamps...

        @param force: if True, reindex also if the index is up to date

        @return:
          True if there is something to index
          False if there is no need of indexing
        R!   t   systemi    s   No indexing plugins found in %st	   timestampsR   Reading current timestamp failed: %s. Assuming the index has not been created yet.s   Most recent dataset:    %s.s   Most recent update for: %s.g      ?s?   The index %s is up to date, but rebuilding anyway as requested.s   The index %s is up to dates   Aggregating value information.t   quieti   t   valuesR   t   descs   Initializing plugins.(   R   R!   R   t   lenRK   R)   R*   R?   t   maxR   R   R   R   t   existst   XAPIANDBSTAMPt   getmtimeRm   R.   R~   t   ctimet   intR   t   readValueDBRD   R   t   values_descR%   R   R   t   dict(	   R   t   forceR   R{   t   cur_timestampRy   t
   values_seqR0   t   v(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   setupIndexing  sD    ,
	  / 
&c         C   sq   t  j   } | j | j  | j d | j j  | j d | j  x$ |  j D] } | j	 j
 | |  qP W| S(   sH   
        Get a xapian.Document for the given apt package record
        i    t   XP(   t   xapiant   Documentt   set_dataR   t	   add_valuet	   candidatet   versiont   add_termR   R   t   index(   R   t   pkgt   documentR0   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   get_document_from_apt  s    c         C   sq   t  j   } | j | d  | j d | d  | j d | d  x$ |  j D] } | j j | |  qP W| S(   sK   
        Get a xapian.Document for the given deb822 package record
        t   Packagei    t   VersionR   (   R   R   R   R   R   R   R   t   indexDeb822(   R   R   R   R0   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   get_document_from_deb822  s    c         c   s   |  j    } t |  } x t |  D] \ } } | j s@ q% n  | j r{ d | j k r{ | j j d  d | k r{ q% n  | d d k r |  j j d | |  n  |  j |  Vq% Wd S(   s=   
        Generate Xapian documents from an apt cache
        t   :i    i   id   N(	   R   R   t	   enumerateR   t	   installedR   t   splitR!   R   (   R   t   cachet   countt   idxR   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   gen_documents_apt(  s    	
+ c         c   s  y d d l  m } Wn! t k
 r7 d d l m } n Xt   } x | D] } t |  } t j | j    d } x t	 | j
 j |   D] \ } } | d }	 |	 | k r q n  | j |	  | d k r| d d k r| j   }
 |  j j d |
 |  n  |  j |  Vq WqH Wd  S(   Ni(   t   deb822i   R   i    i   id   (   t   debianR   t   ImportErrort   debian_bundleR1   R   R   t   fstatt   filenoR   t   Deb822t   iter_paragraphsR6   t   tellR!   R   (   R   t   fnamesR   t   seenR   t   infdt   totalR   R   R   t   cur(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   gen_documents_deb822:  s"    	%
 c         C   s'  i  } i  } i  } |  j  j d  | j   } x t | j d   D] \ } } | d d k r{ |  j  j  d | |  n  | j | j  }	 |	 j   }
 |	 j d  } | j	 |
  s | |
 j
 r | j | |
 <qD | |
 j
 j | k r | j | |
 <qD | j | |
 <qD W|  j  j   | | | f S(   s&  
        Compare the apt cache to the database and return dicts
        of the form (pkgname, docid) for the following states:

        unchanged - no new version since the last update
        outdated - a new version since the last update
        obsolete - no longer in the apt cache
        s   Reading Xapian indexR}   i  i    id   (   R!   RE   t   get_doccountR   t   postlistt   get_documentt   docidt   get_datat	   get_valuet   has_keyR   R   RG   (   R   R   t   dbt	   unchangedt   outdatedt   obsoleteR   R   t   mt   docR   t   dbver(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   compareCacheToDbO  s$    	" c         C   s   d t  j k S(   Nt   XAPIAN_CJK_NGRAM(   R   t   environ(   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   is_cjk_enabledq  s    c         C   s2  y t  j | t  j  } Wn' t  j k
 rB } |  j j d  d SX|  j   r | j d  d k r |  j j d t	 j
  |  j   S|  j   } t |  } |  j | |  \ } } } |  j j d t |  t |  t |  f  |  j j d  x' |  j D] }	 |	 j d | d	 |  qWx t |  D] \ }
 } |
 d
 d k re|  j j d |
 |  n  | j stq.n  | j | k rq.q.| j | k r| j | | j |  j |   q.| j |  j |   q.Wx! | j   D] } | j |  qWx |  j D] }	 |	 j   qW| j   |  j j   d S(   s"   
        Update the index
        s!   DB Update failed, database lockedNt	   cjk_ngramt   1s1   The index %s is not CJK-compatible, rebuilding itsB   Unchanged versions: %s, oudated version: %s, obsolete versions: %ss   Updating Xapian indexR   R   i  i    id   (   R   t   WritableDatabaset   DB_CREATE_OR_OPENt   DatabaseLockErrorR!   RL   R   t   get_metadataRK   R)   t   XAPIANINDEXt   rebuildR   R   R   R.   RE   R   R   R   R   R   t   replace_documentR   t   add_documentR   t   delete_documentR   RC   RG   (   R   R   R   Ry   R   R   R   R   R   t   aR   R   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   updateIndext  sD    !
		  	#
c         C   s   t  j j t j  s/ |  j j d  |  j   St t j  j	   j
   \ } } |  j |  t  j j t j  s t t j d  j   n  |  j d k r t  j t j |  j |  j f  n  d  S(   Ns7   No Xapian index built yet: falling back to full rebuildt   wi    (   R   R   R   R)   R   R!   RK   R  R   t   readlineR   R  R   Ru   R   t   utime(   R   t   dbkindt   dbpath(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   incrementalUpdate  s    
!c         C   s   |  j  j d  t j | t j  } |  j   rD | j d d  n  x! |  j D] } | j d |  qN Wx | D] } | j	 |  qo Wx |  j D] } | j
   q W| j   |  j  j   d S(   sT   
        Create a new Xapian index with the content provided by the plugins
        s   Rebuilding Xapian indexR   R   R   N(   R!   RE   R   R   t   DB_CREATE_OR_OVERWRITER   t   set_metadataR   R   R  R   RC   RG   (   R   R   t	   documentst	   addoninfoR   R  R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt
   buildIndex  s     
c            s  xO t  j d  D]> } d |   t j j t j    } t j j |  s Pq q W| rj  j |  } n6 x'  j	 D] } | j
 d  j    qt W j   }  j | |   j j d  t t j d d  } | d It j j |  IJ| j   t j t j d t j     f d   } | t j  | t j  t j j t j  spt t j d  j   n   j d	 k rt j t j  j  j f  n   j    j    j   d  S(
   Ni   s   index.%dR   s   Installing the new index.s   .tmpR  t   autoc            s   x t  j |   D]{ } | j d  s+ q n  |   k r= q n  t  j j |  |  } t  j j |  sj q n   j j d |  t j	 |  q Wd  S(   Ns   index.s   Removing old index %s.(
   R   R(   t
   startswithR   R,   R   R!   R.   t   shutilt   rmtree(   t   dirt   filet   fullpath(   t   tmpidxfnameR   (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   cleanoldcaches  s       i    (   t	   itertoolsR   R   R   R,   R)   R   R   R   R   R   R   R   R  R!   R.   R   R   t   abspathRu   t   renameR   R   R   R	  t   writeValuest   writePrefixest   writeDoc(   R   t   pkgfilesR   t   dbdirt	   generatorR  t   outR  (    (   R  R   s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR    s4    
  

"

c      
   C   s  |  j  j d |  t | d d  } | t j d  j   IJt   } x |  j D] } x | j j	 d g   D] } | j	 d d  } | d k r qo n  | j	 d d  } | j	 d d  } | j	 d	 d  }	 | j | t    }
 | r |
 j d |  n  | r|
 j d |  n  |	 ro |
 j d	 |	  qo qo WqS Wxg t | j   d
 d   D]J \ } } | d | | j	 d d  | j	 d d  | j	 d	 d  f IJqSW| j   t j | d |  d S(   s@   
        Write the prefix information on the given file
        s!   Writing prefix information to %s.s   .tmpR  s  
        # This file contains the information about keyword prefixes used in the
        # APT Xapian index.
        #
        # Xapian allows to prefix some terms so they can be told apart from
        # normal keywords: this is used for example with Debtags tags, and
        # stemmed forms.
        #
        # This file lists terms with their index prefix, their queryparser
        # prefix, whether queryparser should treat it as boolean or
        # probabilistic and a short description.
        t   prefixesR   t   qpR   R   t   keyc         S   s   |  d S(   Ni    (    (   R{   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   <lambda>%  s    s   %s	%s	%s	# %st   -s   (description is missing)N(   R!   R.   R   t   textwrapt   dedentt   lstripR   R   R   R%   R   t
   setdefaultR'   t	   iteritemsRu   R   R  (   R   R   R$  R%  R0   t   pR   R&  R   R   t   oldR   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR    s8    
	    (
c         C   s   |  j  j d |  t | d d  } | t j d  j   IJxP t |  j j   d d   D]0 \ } } |  j	 | } | d | | | f IJq_ W| j
   t j | d |  d S(	   s?   
        Write the value information on the given file
        s    Writing value information to %s.s   .tmpR  s  
        # This file contains the mapping between names of numeric values indexed in the
        # APT Xapian index and their index
        #
        # Xapian allows to index numeric values as well as keywords and to use them for
        # all sorts of useful querying tricks.  However, every numeric value needs to
        # have a unique index, and this configuration file is needed to record which
        # indices are allocated and to provide a mnemonic name for them.
        #
        # The format is exactly like /etc/services with name, number and optional
        # aliases, with the difference that the second column does not use the
        # "/protocol" part, which would be meaningless here.
        R'  c         S   s   |  d S(   Ni   (    (   R{   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR(  E  s    s
   %s	%d	# %sN(   R!   R.   R   R*  R+  R,  R'   R   R.  R   Ru   R   R  (   R   R   R$  R   R   R   (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR  0  s    
+
c      
   C   s  |  j  j d |  g  } x |  j D]v } yP | j j   } | d k ry | j t d | d d | d d | d   n  Wq$ |  j  j d | j	  q$ Xq$ Wt
 | d d  } | t j d  j   t j t j f IJx* | D]" } | d	 | d | d f IJq W| t j d
  IJxO | D]G } | | d IJ| d t | d  IJ| t j | d  IJ| Jq!W| j   t j | d |  d S(   s;   
        Write the documentation in the given file
        s   Writing documentation to %s.R   t	   shortDesct   fullDocs!   Skipping documentation for plugins   .tmpR  sL  
        ===============
        Database layout
        ===============

        This Xapian database indexes Debian package information.  To query the
        database, open it as ``%s/index``.

        Data are indexed either as terms or as values.  Words found in package
        descriptions are indexed lowercase, and all other kinds of terms have an
        uppercase prefix as documented below.

        Numbers are indexed as Xapian numeric values.  A list of the meaning of the
        numeric values is found in ``%s``.

        The data sources used for indexing are:
        s	    * %s: %ss  
        This Xapian index follows the conventions for term prefixes described in
        ``/usr/share/doc/xapian-omega/termprefixes.txt.gz``.

        Extra Debian data sources can define more extended prefixes (starting with
        ``X``): their meaning is documented below together with the rest of the data
        source documentation.

        At the very least, at least the package name (with the ``XP`` prefix) will
        be present in every document in the database.  This allows to quickly
        lookup a Xapian document by package name.

        The user data associated to a Xapian document is the package name.


        -------------------
        Active data sources
        -------------------

        t   =N(   R!   R.   R   R   R   R   R   R   RK   R   R   R*  R+  R,  R)   R   t   XAPIANDBVALUESR   Ru   R   R  (   R   R   t   docinfoR0   R   R$  t   d(    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR   M  s4    


 
	
N(   R   R   R   R?   R   R   R   R   R   R   RD   R   R   R   R   R   R   R   R  R  R  R   R  R)   t   XAPIANDBPREFIXESR  R4  R  t   XAPIANDBDOCR   (    (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyR   Y  s*   					
A					"		1	3.(    (    (    (    (    (    (    (   R)   R   R   R
   RQ   Rw   R   R*  R   R  R  R~   R2   R7   t   cPickleRZ   R4   R    t   listR   R=   RN   RO   RP   Rc   Ri   t   objectR|   R   (    (    (    s/   /usr/lib/python2.7/dist-packages/axi/indexer.pyt   <module>   s0    %*/7