# Path: src/petmail/database.py
# class DBError(Exception):
# class ObservableDatabase:
# def get_schema(version):
# def serialize(row):
#     def __init__(self, connection):
#     def subscribe(self, table, observer):
#     def unsubscribe(self, table, observer):
#     def execute(self, sql, values=None):
#     def insert(self, sql, values, table=None, tags={}):
#     def update(self, sql, values, table=None, id=None, tags={}):
#     def delete(self, sql, values, table, id, tags={}):
#     def commit(self):
# def get_db(dbfile, stderr=sys.stderr):
# def make_observable_db(dbfile, stderr=sys.stderr):
#     VERSION = 1
# 
# Path: src/petmail/util.py
# def equal(a, b):
#     # not vulnerable to timing attack
#     return hashlib.sha256(a).digest() == hashlib.sha256(b).digest()
# 
# def make_nonce():
#     return base64.b32encode(os.urandom(32)).strip("=").lower()
# 
# Path: src/petmail/errors.py
# class CommandError(Exception):
#     def __init__(self, msg):
#         self.msg = msg


import json, collections
from pkg_resources import resource_string, resource_filename
from twisted.application import service, strports
from twisted.web import server, static, resource, http
from .database import Notice
from .util import equal, make_nonce
from .errors import CommandError
class EventChannelSubscribe(BaseHandler):
    def handle(self, payload):
        self.event_dispatcher.subscribe(str(payload["esid"]),
                                        str(payload["topic"]),
                                        payload.get("catchup", False))
        return {"ok": "ok"}
handlers["eventchannel-subscribe"] = EventChannelSubscribe

class EventChannelUnsubscribe(BaseHandler):
    def handle(self, payload):
        self.event_dispatcher.unsubscribe(str(payload["esid"]),
                                          str(payload["topic"]))
        return {"ok": "ok"}
handlers["eventchannel-unsubscribe"] = EventChannelUnsubscribe


class API(resource.Resource):
    def __init__(self, access_token, db, agent):
        resource.Resource.__init__(self)
        self.access_token = access_token
        self.db = db
        self.agent = agent
        self.event_dispatcher = EventChannelDispatcher(db, agent)

    def getChild(self, path, request):
        if path == "events":
            # Server-Sent Events use a GET with a use-once URL, not a token
            return self.event_dispatcher
        # everything else requires a token, check it here
        payload = json.loads(request.content.read())

# Path: src/petmail/database.py
# class DBError(Exception):
# class ObservableDatabase:
# def get_schema(version):
# def serialize(row):
#     def __init__(self, connection):
#     def subscribe(self, table, observer):
#     def unsubscribe(self, table, observer):
#     def execute(self, sql, values=None):
#     def insert(self, sql, values, table=None, tags={}):
#     def update(self, sql, values, table=None, id=None, tags={}):
#     def delete(self, sql, values, table, id, tags={}):
#     def commit(self):
# def get_db(dbfile, stderr=sys.stderr):
# def make_observable_db(dbfile, stderr=sys.stderr):
#     VERSION = 1
# 
# Path: src/petmail/util.py
# def equal(a, b):
#     # not vulnerable to timing attack
#     return hashlib.sha256(a).digest() == hashlib.sha256(b).digest()
# 
# def make_nonce():
#     return base64.b32encode(os.urandom(32)).strip("=").lower()
# 
# Path: src/petmail/errors.py
# class CommandError(Exception):
#     def __init__(self, msg):
#         self.msg = msg


# Path: src/petmail/web.py
import json, collections
from pkg_resources import resource_string, resource_filename
from twisted.application import service, strports
from twisted.web import server, static, resource, http
from .database import Notice
from .util import equal, make_nonce
from .errors import CommandError

class EventChannelSubscribe(BaseHandler):
    def handle(self, payload):
        self.event_dispatcher.subscribe(str(payload["esid"]),
                                        str(payload["topic"]),
                                        payload.get("catchup", False))
        return {"ok": "ok"}
handlers["eventchannel-subscribe"] = EventChannelSubscribe

class EventChannelUnsubscribe(BaseHandler):
    def handle(self, payload):
        self.event_dispatcher.unsubscribe(str(payload["esid"]),
                                          str(payload["topic"]))
        return {"ok": "ok"}
handlers["eventchannel-unsubscribe"] = EventChannelUnsubscribe


class API(resource.Resource):
    def __init__(self, access_token, db, agent):
        resource.Resource.__init__(self)
        self.access_token = access_token
        self.db = db
        self.agent = agent
        self.event_dispatcher = EventChannelDispatcher(db, agent)

    def getChild(self, path, request):
        if path == "events":
            # Server-Sent Events use a GET with a use-once URL, not a token
            return self.event_dispatcher
        # everything else requires a token, check it here
        payload = json.loads(request.content.read())

        if not equal(payload["token"], self.access_token):