#!/usr/bin/python

import httplib
import urllib
import urllib2
import types

#httplib.HTTPConnection.debuglevel = 1

class SPARQLClientErrorHandler(urllib2.HTTPDefaultErrorHandler):

    def http_error_default(self, req, fp, code, msg, headers):
        result = urllib2.HTTPError(req.get_full_url(), code, msg, headers, fp)
        result.status = code
        return result

class SPARQLClient:

    def __init__(self, service):
        self.service = service
        self.accept = []
        self.result = None
        self.defgraph = []
        self.named = []
        self.usepost = 0

    def execute(self):

        params = [ ( "query", self.query ) ]
        params.extend([ ("default-graph-uri", g) for g in self.defgraph ])
        params.extend([ ("named-graph-uri", g) for g in self.named ])

        self.params = urllib.urlencode(params, 1)
        
        if self.usepost:
            self.request = urllib2.Request(self.service, self.params)
        else:
            self.request = urllib2.Request(self.service + "?" + self.params)
        
        if len(self.accept) > 0:
            self.request.add_header("Accept", ",".join(self.accept))

        http_handler = urllib2.HTTPHandler(debuglevel=1)
        handlers = [http_handler,SPARQLClientErrorHandler()]
        self.opener = urllib2.build_opener(handlers)
        self.stream = self.opener.open(self.request)
        self.result = self.stream.read()
        return self.result

    def add_accept(self, contenttype):
        if isinstance(contenttype, types.ListType):
            self.accept.extend(contenttype)
        else:
            self.accept.append(str(contenttype))

    def set_query(self, query):
        self.query = query

    def add_namedgraph(self, named):
        if isinstance(named, types.ListType):
            self.named.extend(named)
        else:
            self.named.append(named)

    def add_backgroundgraph(self, graph):
        if isinstance(graph, types.ListType):
            self.defgraph.extend(graph)
        else:
            self.defgraph.append(graph)

    def set_post(self, method):
        self.usepost = method

    def get_requesturl(self):
        return self.request.get_full_url()

    def get_responsecode(self):
        if self.stream and hasattr(self.stream, 'status'):
            return int(self.stream.status)
        else:
            return 200

    def get_responseheaders(self):
        if self.stream:
            return self.stream.headers.dict

    def get_contenttype(self):
        if self.stream:
            value = self.stream.headers.dict["content-type"]
            value = value.split(";").pop(0)
            return value

def main():

    query = """
PREFIX books:   <http://example.org/book/>
PREFIX dc:      <http://purl.org/dc/elements/1.1/>
SELECT ?book ?title WHERE { ?book dc:title ?title }
    """

    client = SPARQLClient('http://sparql.org/books')
    client.set_query(query)
    print client.execute()


if __name__ == "__main__":
	main()
