utils/export_annotations.py
author rougeronj
Thu, 16 Apr 2015 12:15:33 +0200
changeset 153 60bd2b36b9dc
parent 66 658561ea9e65
permissions -rw-r--r--
put showTime as an option and add it to static pianoroll template on server

#!/usr/bin/env python
# coding=utf-8

import argparse
import datetime
import sys
import logging

from lxml import etree

import utils

def get_logger():
    return logging.getLogger(__name__)

def set_logging(options, plogger=None, queue=None):

    logging_config = {
        "format" : '%(asctime)s %(levelname)s:%(name)s:%(message)s',
        "level" : max(logging.NOTSET, min(logging.CRITICAL, logging.WARNING - 10 * options.verbose + 10 * options.quiet)), #@UndefinedVariable
    }

    if options.logfile == "stdout":
        logging_config["stream"] = sys.stdout
    elif options.logfile == "stderr":
        logging_config["stream"] = sys.stderr
    else:
        logging_config["filename"] = options.logfile

    logger = plogger
    if logger is None:
        logger = get_logger() #@UndefinedVariable

    if len(logger.handlers) == 0:
        filename = logging_config.get("filename")
        if queue is not None:
            hdlr = QueueHandler(queue, True)
        elif filename:
            mode = logging_config.get("filemode", 'a')
            hdlr = logging.FileHandler(filename, mode) #@UndefinedVariable
        else:
            stream = logging_config.get("stream")
            hdlr = logging.StreamHandler(stream) #@UndefinedVariable

        fs = logging_config.get("format", logging.BASIC_FORMAT) #@UndefinedVariable
        dfs = logging_config.get("datefmt", None)
        fmt = logging.Formatter(fs, dfs) #@UndefinedVariable
        hdlr.setFormatter(fmt)
        logger.addHandler(hdlr)
        level = logging_config.get("level")
        if level is not None:
            logger.setLevel(level)

    options.debug = (options.verbose-options.quiet > 0)
    return logger

def set_logging_options(parser):
    parser.add_argument("-l", "--log", dest="logfile",
                      help="log to file", metavar="LOG", default="stderr")
    parser.add_argument("-v", dest="verbose", action="count",
                      help="verbose", default=0)
    parser.add_argument("-q", dest="quiet", action="count",
                      help="quiet", default=0)


def get_options():


    parser = argparse.ArgumentParser(description="All date should be given using iso8601 format. If no timezone is used, the date is considered as UTC")

    parser.add_argument("-f", "--file", dest="filename",
                      help="write export to file", metavar="FILE", default="project.ldt")
    parser.add_argument("-a", "--annot-url", dest="annot_url",
                      help="annotation server url", metavar="ANNOT-URL", required=True)
    parser.add_argument("-s", "--start-date", dest="start_date",
                      help="start date", metavar="START_DATE", default=None)
    parser.add_argument("-e", "--end-date", dest="end_date",
                      help="end date", metavar="END_DATE", default=None)
    parser.add_argument("-I", "--content-file", dest="content_file",
                      help="Content file", metavar="CONTENT_FILE")
    parser.add_argument("-c", "--content", dest="content",
                      help="Content url", metavar="CONTENT")
    parser.add_argument("-V", "--video-url", dest="video",
                      help="video url", metavar="VIDEO")
    parser.add_argument("-i", "--content-id", dest="content_id",
                      help="Content id", metavar="CONTENT_ID")
    parser.add_argument("-C", "--color", dest="color",
                      help="Color code", metavar="COLOR", default="16763904")
    parser.add_argument("-H", "--channel", dest="channels",
                      help="Channel", metavar="CHANNEL", default=[utils.AnnotationsSynchronizer.DEFAULT_ANNOTATION_CHANNEL], action="append")
    parser.add_argument("-E", "--event", dest="events",
                      help="Event", metavar="EVENT", default=[], action="append")
    parser.add_argument("-D", "--duration", dest="duration", type=int,
                      help="Duration", metavar="DURATION", default=None)
    parser.add_argument("-n", "--name", dest="name",
                      help="Cutting name", metavar="NAME", default=u"annotations")
    parser.add_argument("-R", "--replace", dest="replace", action="store_true",
                      help="Replace annotation ensemble", default=False)
    parser.add_argument("-m", "--merge", dest="merge", action="store_true",
                      help="merge annotation ensemble, choose the first ensemble", default=False)
    parser.add_argument("-L", "--list-conf", dest="listconf",
                      help="list of file to process", metavar="LIST_CONF", default=None)
    parser.add_argument("-b", "--base-url", dest="base_url",
                      help="base URL of the platform", metavar="BASE_URL", default="http://ldt.iri.centrepompidou.fr/ldtplatform/")
    parser.add_argument("-p", "--project", dest="project_id",
                      help="Project id", metavar="PROJECT_ID", default=None)
    parser.add_argument("-P", "--post-param", dest="post_param",
                      help="Post param", metavar="POST_PARAM", default=None)
    parser.add_argument("-B", "--batch-size", dest="batch_size", type=int,
                      help="Batch size for annotation request", metavar="BATCH_SIZE", default=500)
    parser.add_argument("--user-whitelist", dest="user_whitelist", action="store",
                      help="A list of user screen name", metavar="USER_WHITELIST",default=None)
    parser.add_argument("--cut", dest="cuts", action="append",
                      help="A cut with the forma <ts in ms>::<duration>", metavar="CUT", default=[])

    set_logging_options(parser)

    return (parser.parse_args(), parser)


def parse_duration(s):
    try:
        return int(s)
    except ValueError:
        parts = s.split(":")
        if len(parts) < 2:
            raise ValueError("Bad duration format")
        time_params = {
            'hours': int(parts[0]),
            'minutes': int(parts[1]),
            'seconds': int(parts[2]) if len(parts)>2 else 0
        }
        return int(round(datetime.timedelta(**time_params).total_seconds()*1000))


if __name__ == "__main__" :

    (options, parser) = get_options()

    set_logging(options)

    get_logger().debug("OPTIONS : " + repr(options)) #@UndefinedVariable


    deltas = [(0,0)]
    total_delta = 0
    if options.cuts:
        cuts_raw = sorted([tuple([parse_duration(s) for s in c.split("::")]) for c in options.cuts])
        for c, d in cuts_raw:
            deltas.append((c+total_delta, -1))
            total_delta += d
            deltas.append((c+total_delta, total_delta))

    if len(sys.argv) == 1 or options.annot_url is None:
        parser.print_help()
        sys.exit(1)

    if options.listconf:

        parameters = []
        confdoc = etree.parse(options.listconf)
        for node in confdoc.xpath("/annotation_export/file"):
            params = {}
            for snode in node:
                if snode.tag == "path":
                    params['content_file'] = snode.text
                    params['content_file_write'] = snode.text
                elif snode.tag == "project_id":
                    params['content_file'] = options.base_url + utils.AnnotationsSynchronizer.LDT_PROJECT_REST_API_PATH + snode.text + "/?format=json"
                    params['content_file_write'] = options.base_url + utils.AnnotationsSynchronizer.LDT_PROJECT_REST_API_PATH + snode.text + "/?format=json"
                    params['project_id'] = snode.text
                elif snode.tag == "start_date":
                    params['start_date'] = snode.text
                elif snode.tag == "end_date":
                    params['end_date'] = snode.text
                elif snode.tag == "duration":
                    params['duration'] = int(snode.text)
                elif snode.tag == "events":
                        params['events'] = [snode.text]
                elif snode.tag == "channels":
                    params['channels'] = [snode.text]
            if options.events or 'events' not in params :
                params['events'] = options.events
            if options.channels or 'channels' not in params :
                params['channels'] = options.channels

            parameters.append(params)
    else:
        if options.project_id:
            content_file = options.base_url + utils.AnnotationsSynchronizer.LDT_PROJECT_REST_API_PATH + options.project_id + "/?format=json"
        else:
            content_file = options.content_file
        parameters = [{
            'start_date'            : options.start_date,
            'end_date'              : options.end_date,
            'duration'              : options.duration,
            'events'                : options.events,
            'channels'              : options.channels,
            'content_file'          : content_file,
            'content_file_write'    : content_file,
            'project_id'            : options.project_id
        }]

    for params in parameters:

        get_logger().debug("PARAMETERS " + repr(params)) #@UndefinedVariable

        sync_args = dict(vars(options))
        sync_args.pop('cuts')
        sync_args.pop('verbose')
        sync_args.pop('quiet')
        sync_args.pop('debug')
        sync_args.pop('listconf')
        sync_args.pop('logfile')
        sync_args['deltas'] = deltas
        sync_args['logger'] = get_logger()
        sync_args.update(params)

        get_logger().debug("SYNC ARGS " + repr(sync_args))

        sync = utils.AnnotationsSynchronizer(**sync_args)
        sync.export_annotations()