#!/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()