Ñò
@ó¥Oc           @   s7  d  d k  Z  d  d k l Z d  d k Z d  d k Z d  d k Z d  d k l Z d  d k l	 Z	 d  d k
 l Z l Z d  d k l Z d  d k l Z d  d k Z d d	 k l Z e i d
 d „  ƒ e  i e ƒ Z d Z d „  Z d „  Z d „  Z d „  Z d „  Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ d S(   iÿÿÿÿN(   t   exported(   t   izip(   t   wraps(   t   Threadt   RLock(   t   time(   t   datetimei   (   t   zephyrt   BOOLc         C   s
   |  d  j S(   t   0(    (   t   v(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   <lambda>   s    t   Filtert	   Messengerc            s   t  ˆ  ƒ ‡  f d †  ƒ } | S(   Nc            s/   |  i  i i ƒ  z ˆ  |  | | Ž SWd  QXd  S(   N(   t   lockt   __exit__t	   __enter__(   t   selft   argst   kwargs(   t   func(    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   do   s    (   R   (   R   R   (    (   R   sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   sync   s    c            s   t  ˆ  ƒ ‡  f d †  ƒ } | S(   Nc            s~   |  i  i i ƒ  zc y4 |  i i ƒ  ˆ  |  | | Ž } |  i i ƒ  | SWn( t j
 o } |  i i ƒ  | ‚ n XWd  QXd  S(   N(   R   R   R   t   dbt   committ   BaseExceptiont   rollback(   R   R   R   t   rt   e(   R   (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyR      s    (   R   (   R   R   (    (   R   sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   transaction   s    c         C   sŒ   |  d j o: t  i i |  ƒ p# t  i t  i |  t  i d ƒ ƒ qG n t i |  d t i d t	 ƒ} d „  | _
 | i d ƒ | i ƒ  | S(   sÆ   
    Either open an existing db or create a new one.

    Arguments:
        path -  the path to the database. the database does not need to exist
                but the parent directory must.
    s   :memory:i€  t   detect_typest   check_same_threadc         S   s    t  t d  „  |  i Dƒ | ƒ ƒ S(   c         s   s   x |  ] } | d  Vq Wd S(   i    N(    (   t   .0t   c(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pys	   <genexpr>>   s   	 (   t   dictR   t   description(   t   cursort   row(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyR   >   s    s  CREATE TABLE IF NOT EXISTS messages (
        id          INTEGER NOT NULL PRIMARY KEY,
        sender      TEXT    NOT NULL,
        auth        BOOL    NOT NULL DEFAULT 1,
        signature   TEXT    NOT NULL DEFAULT "",
        message     TEXT    NOT NULL,
        read        BOOL    NOT NULL DEFAULT 0,
        cls         TEXT    NOT NULL DEFAULT "message",
        instance    TEXT    NOT NULL DEFAULT "personal",
        user        TEXT    DEFAULT NULL,
        timestamp   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
    )(   t   ost   patht   isfilet   closet   opent   O_CREATt   sqlite3t   connectt   PARSE_DECLTYPESt   Falset   row_factoryt   executeR   (   R'   R   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   open_or_create_db(   s    '
c         C   s   d d |  d d S(   Nt   (s   ?,i   s   ?)(    (   t   num(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt
   gen_paramsN   s    c         C   s   |  S(    (    (   t   x(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyR   R   s    c           B   s  e  Z d  Z d& Z h e d f d 6e d f d	 6e d
 f d 6e d f d 6e d f d 6d „  d f d 6e d f d 6e d f d 6Z e d „  ƒ Z d „  Z	 d „  Z
 d d d „ Z d d d „ Z d „  Z d „  Z d  „  Z d d d! „ Z d" „  Z d# „  Z d d d$ „ Z d d d% „ Z RS('   sS   
    A filter that is an or of its clauses anded with its parent (recursivly).
    t   fidt   _objst   _query_listt   _wheret   _dnfs   cls=?t   clss
   instance=?t   instances   user=?t   users   sender=?t   senders   read=?t   readc         C   s   d  |  d  S(   t   %(    (   t   m(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyR   b   s    s   message LIKE ?t   messages   timestamp > ?t   afters   timestamp < ?t   beforec         C   s   d i  d „  |  Dƒ ƒ S(   Ns    OR c         s   s"   x |  ] } d  i  | ƒ Vq Wd S(   s    AND N(   t   join(   R    R!   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pys	   <genexpr>i   s   	 (   RF   (   t   dnf(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   parseDNFg   s    c            s×   t  t d „  | Dƒ ƒ ƒ ˆ  _ | p h  | j o: t  t ƒ  ƒ ˆ  _ d ˆ  _ d ˆ  _ d ˆ  _ d ˆ  _ nf t ‡  f d †  | Dƒ Œ  \ ˆ  _ ˆ  _ t	 ˆ  i t
 ƒ  ƒ ˆ  _ ˆ  i ˆ  i ƒ ˆ  _ d ˆ  i ˆ  _ d S(   sý   Initialize a new Filter
        Arguments:
            f - a filter {"field": "value", ... }
        Filter clause:
            {
                field: field-name,
                regex: bool,
                value: search-value,
            }
        c         s   s%   x |  ] } t  | i ƒ  ƒ Vq Wd  S(   N(   t	   frozensett	   iteritems(   R    t   clause(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pys	   <genexpr>x   s   	 t    c         3   s?   x8 |  ]1 } t  d  „  ‡  f d †  | i ƒ  Dƒ Dƒ Œ  Vq Wd S(   c         s   s1   x* |  ]# \ \ } } } | | ƒ | f Vq Wd  S(   N(    (   R    t   tt   lR
   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pys	   <genexpr>ƒ   s   	 c         3   s,   x% |  ] \ } } ˆ  i  | | f Vq Wd  S(   N(   t   FIELDS(   R    t   fR
   (   R   (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pys	   <genexpr>„   s   	 N(   R   RJ   (   R    RK   (   R   (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pys	   <genexpr>‚   s   	s    WHERE N(    (    (   t   hashRI   R7   R8   R9   R:   t   NoneR;   R   t   sumt   tupleRH   (   R   t   clauses(    (   R   sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   __init__l   s    			c         C   s   |  i  S(   N(   R7   (   R   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   __hash__Œ   s    i    iÿÿÿÿc         C   s*   | i  d | |  i f |  i | | f ƒ S(   Ns7   %s FROM messages %s ORDER BY timestamp LIMIT ? OFFSET ?(   R1   R:   R8   (   R   R   t   actiont   offsett   perpage(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt
   applyQuery   s    c         C   s   |  i  | d | | ƒ i ƒ  S(   Ns   SELECT *(   R[   t   fetchall(   R   R   RY   RZ   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   get•   s    c         C   s   | i  d |  i |  i ƒ i S(   Ns   DELETE FROM messages(   R1   R:   R8   t   rowcount(   R   R   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   delete˜   s    c         C   s   | i  d |  i |  i ƒ i S(   Ns   UPDATE messages SET read=1(   R1   R:   R8   R^   (   R   R   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   markRead›   s    c         C   s   | i  d |  i |  i ƒ i S(   Ns   UPDATE messages SET read=0(   R1   R:   R8   R^   (   R   R   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt
   markUnreadž   s    c         C   s    |  i  | d | | ƒ i ƒ  d S(   Ns   SELECT count(*) AS totalt   total(   R[   t   fetchone(   R   R   RY   RZ   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   count¡   s    c         C   s:   d |  i  } | i | |  i ƒ i ƒ  } | d | d f S(   s5   
        Returns (unread_count, total_count)
        sê   
                SELECT count(*) AS total, count(unread) AS unread
                FROM (
                    SELECT nullif(read, 1) AS unread
                    FROM messages
                    %s
                )
                t   unreadRb   (   R:   R1   R8   Rc   (   R   R   t   queryt   result(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   counts¤   s    c         C   s´   |  i  | ƒ \ } } | d j o d | f S|  i o d |  i } n d } d | } |  i o d |  i | f } n d | } d | } | i | |  i d	 ƒ i ƒ  d
 | f S(   sÍ  
        selects the offset of the oldest unread zephyr using a query similar to

        SELECT count(*) AS offset
        FROM  messages
        WHERE col1=val1 AND col2=val2 AND timestamp < (
            SELECT timestamp
            FROM messages
            WHERE col1=val1 AND col2=val2 AND read=0
            ORDER BY timestamp
            LIMIT 1
        )

        If there are no unread messages, uses -1

        Returns (offset, total_count)
        i    iÿÿÿÿs   (%s) AND read=0s   read=0sO   SELECT timestamp FROM messages WHERE (%s) AND read=0 ORDER BY timestamp LIMIT 1s   (%s) AND timestamp < (%s)s   timestamp < (%s)s0   SELECT count(*) AS offset FROM messages WHERE %si   RY   (   Rh   R;   R1   R8   Rc   (   R   R   Re   Rb   t   subquery_wheret   subqueryt   query_whereRf   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   oldestUnreadOffset³   s    




c         C   s5   g  } |  i  | d | | ƒ D] } | | d q ~ S(   Ns	   SELECT idt   id(   R[   (   R   R   RY   RZ   t   _[1]t   i(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   getIDsÖ   s    c         C   s8   h t  |  i ƒ d 6|  i | | | ƒ d 6| d 6| d 6S(   Nt   filtert   messagesRZ   RY   (   t   strR7   R]   (   R   R   RY   RZ   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   filterResponseÚ   s
    (   s   fids   _objss   _query_lists   _wheres   _dnf(   t   __name__t
   __module__t   __doc__t	   __slots__t   rett   intRO   t   staticmethodRH   RV   RW   R[   R]   R_   R`   Ra   Rd   Rh   Rl   Rp   Rt   (    (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyR   U   s0   	 						#c           B   s6  e  Z e i d  „ Z d „  Z d „  Z e d „  ƒ Z e d „  ƒ Z	 e
 e d d d d „ ƒ ƒ Z e
 d „  ƒ Z e
 e d	 d
 d „ ƒ ƒ Z e
 e d d „ ƒ ƒ Z e
 e d „  ƒ ƒ Z e
 e d	 d
 d „ ƒ ƒ Z e
 d	 d
 d „ ƒ Z e
 e d	 d
 d „ ƒ ƒ Z e
 e d	 d
 d „ ƒ ƒ Z e
 d „  ƒ Z e
 e d „  ƒ ƒ Z e
 e d „  ƒ ƒ Z e
 e d d	 d
 d „ ƒ ƒ Z d „  Z e
 e d	 d
 d „ ƒ ƒ Z e
 e d	 d
 d „ ƒ ƒ Z e
 e d	 d
 d „ ƒ ƒ Z e
 e d	 d
 d „ ƒ ƒ Z e
 e d	 d
 d „ ƒ ƒ Z e
 e d d „ ƒ ƒ Z  e
 e d „  ƒ ƒ Z! RS(   c         C   sD   t  t |  ƒ i ƒ  t | ƒ |  _ | |  _ h  |  _ t ƒ  |  _ d  S(   N(	   t   superR   RV   R2   R   t   usernamet   filtersR   R   (   R   R}   t   db_path(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyRV   ã   s
    		c         C   sQ   x= t  o5 t i d t  ƒ } | d  j o Pn |  i | ƒ q Wt i d ƒ d  S(   Nt   blocks   Stopping receiving thread.(   t   TrueR   t   receiveRR   t   store_znoticet   loggert   info(   R   t   z(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   runê   s     c         C   s   t  i ƒ  |  i ƒ  d  S(   N(   R   t	   interruptRF   (   R   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   quitò   s    
c         G   s   |  i  i d t | ƒ ƒ S(   s   Stores a message and returns its ID.

        >>> messenger = Messenger("ME", ":memory:")
        >>> messenger.store_messages(
        >>>     ("SENDER", "MESSAGE", "CLASS", "INSTANCE", "USER"),
        >>>     ("SENDER", "MESSAGE2", "CLASS", "INSTANCE", "USER")
        >>> )
        sQ   INSERT INTO messages(sender, message, cls, instance, user) VALUES (?, ?, ?, ?, ?)(   R   t   executemanyt   iter(   R   Rr   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   store_messages÷   s    	c         C   s*  | i  d j o d  S| i o d  Sd } d } t | i ƒ d j o | i d } n5 t | i ƒ d j o | i d } | i d } n |  i i d t | i d d ƒ | i t | d d ƒ t | d d ƒ t | i	 d d ƒ t | i
 d d ƒ t | i d d ƒ p d  t i | i p t ƒ  ƒ f ƒ S(   Ni   RL   i   i    sv   INSERT INTO messages(sender, auth, signature, message, cls, instance, user, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?)s   utf-8t   replace(   t   kindt   opcodet   lent   fieldsR   R1   t   unicodeR?   t   authR<   R=   t	   recipientRR   R   t   fromtimestampR   (   R   t   znoticet   msgt   sig(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyRƒ     s*    
	RC   t   personalc         C   s]   t  i d | d | d | d d t i d ƒ | f ƒ } | i ƒ  | o |  i | ƒ n t S(   sJ  
        Send a zephyr.

        Arguments:
            message - The message content
            cls - the message class (defaults to "message")
            instance - the message instance (defaults to "personal")
            user - the destination user (None means everyone)

        >>> messenger = Messenger("ME", ":memory:")
        # Send a message to -c help -i linux
        >>> messenger.send("This is a really short message.", "help", "linux")
        # Send a message to bsw
        >>> messenger.send("This is a really short message.", "message", "personal", "bsw")
        R<   R=   R”   RC   s   %s %st	   signature(   R   t   ZNoticet   preferencest   getVariablet   sendRƒ   R   (   R   RC   R<   R=   R>   R–   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyRž   $  s    	
c         G   s)   t  | Œ  } | |  i | i <t | i ƒ S(   s  
        Filters messages.
        Arguments:
            messageFilters - a list of filters in the form of {"field": "value"}
            Valid fields are:
                sender, class, instance, user, message, before, after, read


        Returns:
            fid - a string filterID and count.

        # Matches all unread messages in class help.
        >>> fid = messenger.filterMessages({"cls": "help", "read": False})
        # Get the messages that match the filter
        >>> messenger.get(fid)
        (   R   R~   R7   Rs   (   R   t   messageFiltersRP   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   filterMessagesC  s    i    iÿÿÿÿc         C   s#   |  i  t | ƒ i |  i | | ƒ S(   sž  
        Get the messages that match fid.
        Arguments:
            fid     - the filter's ID
            offset  - the first item to return from the matched messages.
                      A negitive offset will index backwards.
            perpage - The maximum number of of results to return. Passing a
                      negative number returns all results.

        >>> from . import subscriptions
        >>> m = Messenger(subscriptions.SubscriptionManager("ME"), "ME")
        >>> m.store_message(
        >>> message = {
        >>>     "id": int,
        >>>     "timestamp": int,
        >>>     "cls": str,
        >>>     "instance": str,
        >>>     "message": str,
        >>>     "user": str,        # the destination user
        >>>     "sender": str       # the sender
        >>> }

        # Returns:
        >>> return_value = {
        >>>     "filter": int,      # The filter used to generate the result.
        >>>     "offset": int,      # The offset of the first result returned.
        >>>     "perpage": int,     # The number of results requested.
        >>>     "messages": list    # A list of message dictionaries.
        >>> }
        (   R~   Rz   Rt   R   (   R   R7   RY   RZ   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyR]   Y  s    "c         C   s   t  S(   sh   
        Returns True if there is a message that matches messageFilter newer
        than last.
        (   R   (   R   t   lastt   messageFilter(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   hasNew~  s    c         C   s8   | p d S|  i  i d t t | ƒ ƒ t | ƒ ƒ i S(   sQ   
        Deletes the given messages.
        Returns the number deleted.
        i    s!   DELETE FROM messages WHERE id IN (   R   R1   R5   R   RT   R^   (   R   t   ids(    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyR_   ˆ  s    c         C   sh   | d j p | d j o- |  i  |  i t | ƒ i |  i | | ƒ ƒ S|  i t | ƒ i  |  i ƒ Sd S(   sf   
        Delete the messages that match the given filter.
        Returns the number deleted.
        i    N(   R_   R~   Rz   Rp   R   (   R   R7   RY   RZ   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   deleteFilter”  s    -c         C   s:   | d j o |  i  | ƒ S| d j o |  i | ƒ Sd  S(   NR@   Re   (   t   markFilterReadt   markFilterUnread(   R   t   statusR7   RY   RZ   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt
   markFilter   s    c         C   sh   | d j p | d j o- |  i  |  i t | ƒ i |  i | | ƒ ƒ S|  i t | ƒ i  |  i ƒ Sd S(   sE    Mark all of the messages that match a filter with the given status. i    N(   R`   R~   Rz   Rp   R   (   R   R7   RY   RZ   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyR¦   §  s    -c         C   sh   | d j p | d j o- |  i  |  i t | ƒ i |  i | | ƒ ƒ S|  i t | ƒ i  |  i ƒ Sd S(   sE    Mark all of the messages that match a filter with the given status. i    N(   Ra   R~   Rz   Rp   R   (   R   R7   RY   RZ   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyR§   °  s    -c         C   s4   | d j o |  i  ƒ  S| d j o |  i ƒ  Sd S(   s"    Mark the given messages as read. R@   Re   N(   R`   Ra   (   R   R¨   R¤   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   markº  s    c         C   s8   | p d S|  i  i d t t | ƒ ƒ t | ƒ ƒ i S(   Ni    s'   UPDATE messages SET read=1 WHERE id IN (   R   R1   R5   R   RT   R^   (   R   R¤   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyR`   Â  s    c         C   s8   | p d S|  i  i d t t | ƒ ƒ t | ƒ ƒ i S(   Ni    s'   UPDATE messages SET read=0 WHERE id IN (   R   R1   R5   R   RT   R^   (   R   R¤   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyRa   É  s    c         C   s#   |  i  t | ƒ i |  i | | ƒ S(   s9    Get all of the message ids that match the given filter. (   R~   Rz   Rp   R   (   R   R7   RY   RZ   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyRp   Ð  s    c            sn   t  i d ƒ ‰  t  i d ƒ ‰ ‡  ‡ f d †  } g  } | D] } | | | ƒ q; ~ } | i d d „  ƒ | S(   s8   
        Star and hide a given list of classes.
        s   starred-classess   hidden-classesc            s,   |  d ˆ  j |  d <|  d ˆ j |  d <|  S(   NR<   t   starredt   hidden(    (   t   item(   t   starred_classest   hidden_classes(    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   processà  s    t   keyc         S   s	   |  d  S(   R«   (    (   R­   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyR   æ  s    (   Rœ   R   t   sort(   R   t   classesR°   Rn   R!   (    (   R®   R¯   sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   starAndHideÖ  s    'c         C   s"   |  i  i d | | | f ƒ i ƒ  S(   sé    List the instances with messages in a given class.

        Returns:
            [{
                instance: instance,
                unread: unread_count,
                total: total_count,
             },
            ]
        s-  
            SELECT instance, COUNT(*) AS total, COUNT(unread) AS unread
            FROM (SELECT cls, instance, nullif(read, 1) AS unread, timestamp FROM messages)
            WHERE cls=?
            GROUP BY instance
            ORDER BY MAX(timestamp) DESC
            LIMIT ? OFFSET ?
            (   R   R1   R\   (   R   R<   RY   RZ   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   getInstancesé  s    	c         C   s"   |  i  i d | | | f ƒ i ƒ  S(   sé    List the instances with messages in a given class.

        Returns:
            [{
                instance: instance,
                unread: unread_count,
                total: total_count,
             },
            ]
        s>  
            SELECT instance, COUNT(*) AS total, COUNT(unread) AS unread
            FROM (SELECT cls, instance, read, nullif(read, 1) AS unread, timestamp FROM messages)
            WHERE cls=? AND read=0
            GROUP BY instance
            ORDER BY MAX(timestamp) DESC
            LIMIT ? OFFSET ?
            (   R   R1   R\   (   R   R<   RY   RZ   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   getUnreadInstances   s    	c         C   s"   |  i  |  i i d | | f ƒ ƒ S(   s  
        List the classes with messages.
        Returns:
            [{
                cls: class,
                unread: unread_count,
                total: total_count,
                starred: true if the class is starred,
             },
            ]
        s  
            SELECT cls, COUNT(*) AS total, COUNT(unread) AS unread
            FROM (SELECT cls, nullif(read, 1) AS unread, timestamp FROM messages)
            GROUP BY cls
            ORDER BY MAX(timestamp) DESC
            LIMIT ? OFFSET ?
            (   R´   R   R1   (   R   RY   RZ   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt
   getClasses  s    c         C   s"   |  i  |  i i d | | f ƒ ƒ S(   s  
        List the classes with messages.
        Returns:
            [{
                cls: class,
                unread: unread_count,
                total: total_count,
                starred: true if the class is starred,
             },
            ]

        s   
            SELECT cls, COUNT(*) AS total, COUNT(unread) AS unread
            FROM (SELECT cls, read, nullif(read, 1) AS unread, timestamp FROM messages)
            WHERE read=0
            GROUP BY cls
            ORDER BY MAX(timestamp) DESC
            LIMIT ? OFFSET ?
            (   R´   R   R1   (   R   RY   RZ   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   getUnreadClasses1  s    c         C   s%   |  i  i d d d | | f ƒ i ƒ  S(   s  
        List the users that have sent personals.
        Returns:
            [
                {
                    sender: sender,
                    unread: unread_count,
                    total: total_count,
                }, ...
            ]
        s“  
            SELECT sender, COUNT(*) AS total, COUNT(unread) AS unread
            FROM (
                SELECT sender, read, nullif(read, 1) AS unread, timestamp, cls, instance, user
                FROM messages
                WHERE user IS NOT NULL AND instance=? AND cls=?
            )
            GROUP BY sender
            ORDER BY MAX(timestamp) DESC
            LIMIT ? OFFSET ?
            R™   RC   (   R   R1   R\   (   R   RY   RZ   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   getPersonalsK  s    	c         C   sI   | d j	 o |  i t | ƒ i |  i ƒ S|  i i d ƒ i ƒ  d Sd S(   s1    Get the number of messages that match a filter. s&   SELECT COUNT(*) AS total FROM messagesRb   N(   RR   R~   Rz   Rd   R   R1   Rc   (   R   R7   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   getCountf  s    c         C   s   |  i  t | ƒ i |  i ƒ S(   sú   
        Gets the offset of the oldest unread message that matches a filter, or
        -1 if there are no unread messages. Produces undefined behavior
        if the filter contains a condition on read. Returns
        (offset, total_count)
        (   R~   Rz   Rl   R   (   R   R7   (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   getOldestUnreadOffseto  s    	N("   Ru   Rv   t   settingst	   ZEPHYR_DBRV   R‡   R‰   R   RŒ   Rƒ   R    R   RR   Rž   R    R]   R£   R_   R¥   R©   R¦   R§   Rª   R`   Ra   Rp   R´   Rµ   R¶   R·   R¸   R¹   Rº   R»   (    (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyR   â   sr   		#
	(   s   Filters	   Messenger(   t   loggingt   serverR    R¼   Rœ   R,   t	   itertoolsR   t	   functoolsR   t	   threadingR   R   R   R   R&   RL   R   t   register_convertert	   getLoggerRu   R„   t   __all__R   R   R2   R5   Ry   t   objectR   R   (    (    (    sC   /mit/zmobile/testing/lib/python2.6/site-packages/zserv/messenger.pyt   <module>   s(   			&		