# Path: src/petmail/eventual.py
# def eventually(cb, *args, **kwargs):
#     """This is the eventual-send operation, used as a plan-coordination
#     primitive. The callable will be invoked (with args and kwargs) in a later
#     reactor turn. Doing 'eventually(a); eventually(b)' guarantees that a will
#     be called before b.
# 
#     Any exceptions that occur in the callable will be logged with log.err().
#     If you really want to ignore them, be sure to provide a callable that
#     catches those exceptions.
# 
#     This function returns None. If you care to know when the callable was
#     run, be sure to provide a callable that notifies somebody.
#     """
#     _theSimpleQueue.append(cb, args, kwargs)
# 
# Path: src/petmail/util.py
# def remove_prefix(s_bytes, prefix, errortype=None):
#     if not s_bytes.startswith(prefix):
#         errortype = errortype or BadPrefixError
#         raise errortype("did not see expected '%s' prefix" % (prefix,))
#     return s_bytes[len(prefix):]
# 
# def split_into(s, piece_sizes, plus_trailer=False):
#     assert type(s) == type(b"")
#     pieces = []
#     piece_start = 0
#     for size in piece_sizes:
#         piece_end = piece_start+size
#         pieces.append(s[piece_start:piece_end])
#         piece_start = piece_end
#     if plus_trailer:
#         pieces.append(s[piece_start:])
#     else:
#         if piece_start != len(s):
#             raise ValueError("split did not consume entire string")
#     return pieces
# 
# def hex_or_none(s):
#     if s:
#         return s.encode("hex")
#     return s
# 
# def unhex_or_none(hex):
#     if hex:
#         return hex.decode("hex")
#     return hex
# 
# Path: src/petmail/netstring.py
# def split_netstrings_and_trailer(s):
#     p = _NetstringParser()
#     p.messages = messages = []
#     p.makeConnection(_EmptyTransport())
#     p.dataReceived(s)
#     return (messages, p._remainingData)
# 
# Path: src/petmail/web.py
# class EventsProtocol:
#     def __init__(self, request):
#         self.request = request
# 
#     def sendComment(self, comment):
#         # this is ignored by clients, but can keep the connection open in the
#         # face of firewall/NAT timeouts. It also helps unit tests, since
#         # apparently twisted.web.client.Agent doesn't consider the connection
#         # to be established until it sees the first byte of the reponse body.
#         self.request.write(": %s\n\n" % comment)
# 
#     def sendEvent(self, data, name=None, id=None, retry=None):
#         if name:
#             self.request.write("event: %s\n" % name.encode("utf-8"))
#             # e.g. if name=foo, then the client web page should do:
#             # (new EventSource(url)).addEventListener("foo", handlerfunc)
#             # Note that this basically defaults to "message".
#         if id:
#             self.request.write("id: %s\n" % id.encode("utf-8"))
#         if retry:
#             self.request.write("retry: %d\n" % retry) # milliseconds
#         for line in data.splitlines():
#             self.request.write("data: %s\n" % line.encode("utf-8"))
#         self.request.write("\n")
# 
#     def stop(self):
#         self.request.finish()


import os, struct, time, base64
from twisted.application import service, internet
from twisted.web import server, resource, http
from nacl.public import PrivateKey, PublicKey, Box
from nacl.secret import SecretBox
from .. import rrid
from ..eventual import eventually
from ..util import remove_prefix, split_into, hex_or_none, unhex_or_none
from ..netstring import split_netstrings_and_trailer
from ..web import EventsProtocol
        # return a MailboxRecord, which includes retrieval information, and
        # data which can be turned into a TransportRecord for senders
        symkey = None
        if remote:
            symkey = os.urandom(32)
        RT = os.urandom(8) # retrieval token
        TTID, TT0 = rrid.create_token(self.TT_pubkey)
        return self.add_transport(TTID, TT0, RT, symkey)

    def add_transport(self, TTID, TT0, RT, symkey):
        tid = self.db.insert("INSERT INTO mailbox_server_transports"
                             " (TTID, TT0, RT, symkey) VALUES (?,?,?,?)",
                             (TTID.encode("hex"), TT0.encode("hex"),
                              hex_or_none(RT), hex_or_none(symkey)),
                             "mailbox_server_transports")
        self.db.commit()
        return tid

    def get_local_transport(self):
        row = self.db.execute("SELECT * FROM mailbox_server_transports"
                              " WHERE symkey is NULL").fetchone()
        if not row:
            return self.allocate_transport(False)
        return row["id"]

    def get_tid_data(self, tid):
        c = self.db.execute("SELECT * FROM mailbox_server_transports"
                             " WHERE id=?", (tid,))
        row = c.fetchone()
        return (row["TTID"].decode("hex"), row["TT0"].decode("hex"),

# Path: src/petmail/eventual.py
# def eventually(cb, *args, **kwargs):
#     """This is the eventual-send operation, used as a plan-coordination
#     primitive. The callable will be invoked (with args and kwargs) in a later
#     reactor turn. Doing 'eventually(a); eventually(b)' guarantees that a will
#     be called before b.
# 
#     Any exceptions that occur in the callable will be logged with log.err().
#     If you really want to ignore them, be sure to provide a callable that
#     catches those exceptions.
# 
#     This function returns None. If you care to know when the callable was
#     run, be sure to provide a callable that notifies somebody.
#     """
#     _theSimpleQueue.append(cb, args, kwargs)
# 
# Path: src/petmail/util.py
# def remove_prefix(s_bytes, prefix, errortype=None):
#     if not s_bytes.startswith(prefix):
#         errortype = errortype or BadPrefixError
#         raise errortype("did not see expected '%s' prefix" % (prefix,))
#     return s_bytes[len(prefix):]
# 
# def split_into(s, piece_sizes, plus_trailer=False):
#     assert type(s) == type(b"")
#     pieces = []
#     piece_start = 0
#     for size in piece_sizes:
#         piece_end = piece_start+size
#         pieces.append(s[piece_start:piece_end])
#         piece_start = piece_end
#     if plus_trailer:
#         pieces.append(s[piece_start:])
#     else:
#         if piece_start != len(s):
#             raise ValueError("split did not consume entire string")
#     return pieces
# 
# def hex_or_none(s):
#     if s:
#         return s.encode("hex")
#     return s
# 
# def unhex_or_none(hex):
#     if hex:
#         return hex.decode("hex")
#     return hex
# 
# Path: src/petmail/netstring.py
# def split_netstrings_and_trailer(s):
#     p = _NetstringParser()
#     p.messages = messages = []
#     p.makeConnection(_EmptyTransport())
#     p.dataReceived(s)
#     return (messages, p._remainingData)
# 
# Path: src/petmail/web.py
# class EventsProtocol:
#     def __init__(self, request):
#         self.request = request
# 
#     def sendComment(self, comment):
#         # this is ignored by clients, but can keep the connection open in the
#         # face of firewall/NAT timeouts. It also helps unit tests, since
#         # apparently twisted.web.client.Agent doesn't consider the connection
#         # to be established until it sees the first byte of the reponse body.
#         self.request.write(": %s\n\n" % comment)
# 
#     def sendEvent(self, data, name=None, id=None, retry=None):
#         if name:
#             self.request.write("event: %s\n" % name.encode("utf-8"))
#             # e.g. if name=foo, then the client web page should do:
#             # (new EventSource(url)).addEventListener("foo", handlerfunc)
#             # Note that this basically defaults to "message".
#         if id:
#             self.request.write("id: %s\n" % id.encode("utf-8"))
#         if retry:
#             self.request.write("retry: %d\n" % retry) # milliseconds
#         for line in data.splitlines():
#             self.request.write("data: %s\n" % line.encode("utf-8"))
#         self.request.write("\n")
# 
#     def stop(self):
#         self.request.finish()


# Path: src/petmail/mailbox/server.py
import os, struct, time, base64
from twisted.application import service, internet
from twisted.web import server, resource, http
from nacl.public import PrivateKey, PublicKey, Box
from nacl.secret import SecretBox
from .. import rrid
from ..eventual import eventually
from ..util import remove_prefix, split_into, hex_or_none, unhex_or_none
from ..netstring import split_netstrings_and_trailer
from ..web import EventsProtocol

        # return a MailboxRecord, which includes retrieval information, and
        # data which can be turned into a TransportRecord for senders
        symkey = None
        if remote:
            symkey = os.urandom(32)
        RT = os.urandom(8) # retrieval token
        TTID, TT0 = rrid.create_token(self.TT_pubkey)
        return self.add_transport(TTID, TT0, RT, symkey)

    def add_transport(self, TTID, TT0, RT, symkey):
        tid = self.db.insert("INSERT INTO mailbox_server_transports"
                             " (TTID, TT0, RT, symkey) VALUES (?,?,?,?)",
                             (TTID.encode("hex"), TT0.encode("hex"),
                              hex_or_none(RT), hex_or_none(symkey)),
                             "mailbox_server_transports")
        self.db.commit()
        return tid

    def get_local_transport(self):
        row = self.db.execute("SELECT * FROM mailbox_server_transports"
                              " WHERE symkey is NULL").fetchone()
        if not row:
            return self.allocate_transport(False)
        return row["id"]

    def get_tid_data(self, tid):
        c = self.db.execute("SELECT * FROM mailbox_server_transports"
                             " WHERE id=?", (tid,))
        row = c.fetchone()
        return (row["TTID"].decode("hex"), row["TT0"].decode("hex"),

                unhex_or_none(row["RT"]), unhex_or_none(row["symkey"]))