"""pollIssues.py -- build WBS questions from a formal issues list

USAGE:
  python pollIssues.py 35463 issues-ftf4 issues-formal.rdf \\
      http://...#thisGroup username passwd
"""
__version__ = "$Id: pollIssues.py,v 1.3 2005/01/14 21:23:07 connolly Exp $"

import logging # http://docs.python.org/lib/minimal-example.html

# Redland RDF Application Framework - Python API Reference:
# http://www.redland.opensource.ac.uk/docs/pydoc/RDF.html#Model
# tested with: http://packages.debian.org/python2.3-librdf 0.9.16-1_i386
import RDF
from RDF import Uri

import urllib2 # http://docs.python.org/lib/urllib2-examples.html
from urllib import urlencode

Collab = RDF.NS("http://www.w3.org/2000/10/swap/pim/collab@@#")


def main(argv):
    logging.getLogger().setLevel(logging.INFO)
    logging.info("args: %s", argv)

    try:
        grp, qid, issuesfn, groupTerm, uname, passwd = argv[1:7]
    except ValueError:
        import sys
        print >>sys.stderr, __doc__
        return 2

    issueKB = parseRDF(issuesfn)
    survey=IssueSurvey(grp, qid)
    survey.creds(uname, passwd)

    if 0: #@@ command-line arg
        survey.stayLocal()

    survey.makeQuestions(issueKB, groupTerm)
    
    return 0


def parseRDF(inf):
    graph = RDF.Model()
    rdfp = RDF.Parser(name="rdfxml")
    
    rdfp.parse_into_model(graph, "file:" + inf)
    return graph


class Survey:
    def __init__(self, groupID, surveyID):
        """
        @param groupID is a string
        """
        self._groupID = groupID
        self._surveyID = surveyID
        self._h = None
        self._noop = 0 # really go over the wire

    def stayLocal(self):
        self._noop = 1

    def addr(self):
        return "http://www.w3.org/2002/09/wbs/%s/%s/" % \
               (self._groupID, self._surveyID)
    
    def creds(self, uname, passwd):
        hdl = urllib2.HTTPBasicAuthHandler()
        hdl.add_password('W3CACL', 'www.w3.org', #@@ move to cmdline?
                         uname, passwd)
        opener = urllib2.build_opener(hdl)
        self._h = opener


    # hmm... WSDL tools should give me this code for free, no?
    def addStrawPoll(self, quid, shortdesc, text, comment=0, rationale=0):
        """
        @param quid: limited to 8 chars
        """
        
        params = {'qno': quid,
                  'type': 'choices',
                  'shortdesc': str(shortdesc),
                  'question': text,
                  "wgid": self._groupID,
                  "qaireno": self._surveyID,
                  }
        if comment: params["allowComment"]="on"
        if rationale: params["allowRationale"]="on"

        self.post(self.addr() + 'q/', params)


    def setChoices(self, qno, choices):
        """
        @param choices: a sequence of (id, text) pairs
        """

        params = {'qno': qno,
                  "cChoices": len(choices)+1,
                  }

        c = 1
        for id, text in choices:
            params["choiceid%d" % c] = id
            params["gloss%d" % c] = text
            params["dadd%d" %c] ="0000-00-00 00:00:00" #what is this?
            c += 1

        addr = self.addr() + ("q/%s/choices" % qno)
        logging.info("setting choices; posting to %s", addr)
        self.post(addr, params)


    def post(self, addr, params):
        logging.info("posting params: %s", params)
        if self._noop: return
        try:
            self._h.open(addr, urlencode(params))
        except urllib2.HTTPError, e:
            if e.code <> 201: raise



class IssueSurvey(Survey):
    postponeText = """Postpone: decide that it is not an issue we need to address in this version, though we agree that it should be addressed eventually. @@relevant sections to remove?"""

    def makeQuestions(self, issueKB, groupTerm):
        for issue in issueKB.get_targets(Uri(groupTerm), Collab.issue):

            #skip resolved issues
            if issueKB.get_target(issue, Collab.resolveRecord):
                continue

            shortDesc = str(issueKB.get_target(issue, Collab.shortDesc))

            # if shortDesc <> "SOURCE": # just one for now
            #     continue 

            text = "see <a href='%s'>issue %s</a>." % (issue.uri, shortDesc)

            logging.info("adding issue: %s", shortDesc)
            qno = shortDesc[:8]
            self.addStrawPoll(qno, shortDesc, text,
                              comment=1, rationale=1)

            choices = [("postpone", self.postponeText)]

            choice = 1
            for proposal in issueKB.get_targets(issue, Collab.proposal):
                markup = "<ul>%s</ul>" % proposal.literal_value["string"]
                choices.append(("c%d" % choice, markup))
                choice += 1

            logging.info("setting choices: %s", [t[0] for t in choices])
            self.setChoices(qno, choices)



if __name__ == '__main__':
    import sys
    if '--test' in sys.argv: _test()
    else: sys.exit(main(sys.argv))
