def build_params(_options):
    """Function that builds the query string for Motu according to the given
    options.
    """
    # Build the main url to connect to
    query_options = utils_collection.ListMultimap()

    # describeProduct in XML format (sync) / productDownload (sync/async)
    if _options.describe:
        _options.sync = True
        log.info('Synchronous mode set')
        query_options.insert(action='describeProduct',
                             service=_options.service_id,
                             product=_options.product_id)
    else:
        # synchronous/asynchronous mode
        if _options.sync:
            log.info('Synchronous mode set')
            query_options.insert(action='productdownload',
                                 mode='console',
                                 service=_options.service_id,
                                 product=_options.product_id)
        else:
            log.info('Asynchronous mode set')
            query_options.insert(action='productdownload',
                                 mode='status',
                                 service=_options.service_id,
                                 product=_options.product_id)

        # geographical parameters
    if _options.extraction_geographic:
        query_options.insert(x_lo=_options.longitude_min,
                             x_hi=_options.longitude_max,
                             y_lo=_options.latitude_min,
                             y_hi=_options.latitude_max)

    if _options.extraction_vertical:
        query_options.insert(z_lo=_options.depth_min,
                             z_hi=_options.depth_max)

    if _options.extraction_temporal:
        # date are strings, and they are send to Motu "as is". If not, we
        # convert them into string
        if _options.date_min is not None or _options.date_min is not None:
            date_min = _options.date_min
            if not isinstance(date_min, basestring):
                date_min = date_min.strftime(DATETIME_FORMAT)
            query_options.insert(t_lo=date_min)

        if _options.date_max is not None or _options.date_max is not None:
            date_max = _options.date_max
            if not isinstance(date_max, basestring):
                date_max = date_max.strftime(DATETIME_FORMAT)
            query_options.insert(t_hi=date_max)

    variable = _options.variable
    if variable is not None:
        for _, opt in enumerate(variable):
            query_options.insert(variable=opt)

    return utils_http.encode(query_options)
def authenticate_CAS_for_URL(url, user, pwd, **url_config):
    """Performs a CAS authentication for the given URL service and returns
    the service url with the obtained credential.

    The following algorithm is done:
    1) A connection is opened on the given URL
    2) We check that the response is an HTTP redirection
    3) Redirected URL contains the CAS address
    4) We ask for a ticket for the given user and password
    5) We ask for a service ticket for the given service
    6) Then we return a new url with the ticket attached

    url: the url of the service to invoke
    user: the username
    pwd: the password"""
    log = logging.getLogger("utils_cas:authenticate_CAS_for_URL")

    server, _, _ = url.partition('?')

    log.info('Authenticating user %s for service %s', user, server)

    connexion = utils_http.open_url(url, **url_config)

    # connexion response code must be a redirection, else, there's an error
    # (user can't be already connected since no cookie or ticket was sent)
    if connexion.url == url:
        raise Exception(
            utils_messages.get_external_messages()[
                'motu-client.exception.authentication.not-redirected'
            ] % server)

    # find the cas url from the redirected url
    redirected_url = connexion.url

    m = re.search(CAS_URL_PATTERN, redirected_url)

    if m is None:
        raise Exception(
            utils_messages.get_external_messages()[
                'motu-client.exception.authentication.unfound-url'
            ] % redirected_url)

    url_cas = m.group(1) + '/v1/tickets'

    opts = utils_http.encode(utils_collection.ListMultimap(username=user,
                                                           password=pwd))

    utils_log.log_url(log, "login user into CAS:\t", url_cas+'?'+opts)
    url_config['data'] = opts
    connexion = utils_http.open_url(url_cas, **url_config)

    fp = utils_html.FounderParser()
    for line in connexion:
        log.log(utils_log.TRACE_LEVEL,
                'utils_html.FounderParser() line: %s',
                line)
        fp.feed(line)

    tgt = fp.action_[fp.action_.rfind('/') + 1:]
    log.log(utils_log.TRACE_LEVEL,
            'TGT: %s',
            tgt)

    # WARNING : don't use 'fp.action_' as url : it seems protocol is always
    # http never https use 'url_cas', extract TGT from 'fp.action_' , then
    # construct url_ticket.
    # url_ticket = fp.action_
    url_ticket = url_cas + '/' + tgt

    if url_ticket is None:
        raise Exception(
            utils_messages.get_external_messages()[
                'motu-client.exception.authentication.tgt'
            ])

    utils_log.log_url(log, "found url ticket:\t", url_ticket)

    opts = utils_http.encode(
        utils_collection.ListMultimap(service=urllib.quote_plus(url)))

    utils_log.log_url(log,
                      'Granting user for service\t',
                      url_ticket + '?' + opts)
    url_config['data'] = opts
    ticket = utils_http.open_url(url_ticket, **url_config).readline()

    utils_log.log_url(log, "found service ticket:\t", ticket)

    # we append the download url with the ticket and return the result
    service_url = url + '&ticket=' + ticket

    utils_log.log_url(log, "service url is:\t", service_url)

    return service_url