示例#1
0
文件: views.py 项目: adrianrv/dpCat
def _fichero_entrada_multiple(request, v):
    n = v.plantilla.tipovideo_set.count()
    FicheroEntradaFormSet = inlineformset_factory(
        Video,
        FicheroEntrada,
        formset=RequiredBaseInlineFormSet,
        form=FicheroEntradaForm,
        extra=n,
        max_num=n,
        can_delete=False,
    )
    tipos = v.plantilla.tipovideo_set.all().order_by("id")
    if request.method == "POST":
        formset = FicheroEntradaFormSet(request.POST, instance=v)
        if formset.is_valid():
            instances = formset.save(commit=False)
            for i in range(n):
                instances[i].fichero = os.path.normpath(config.get_option("VIDEO_INPUT_PATH") + instances[i].fichero)
                instances[i].video = v
                instances[i].tipo = tipos[i]
                instances[i].save()
            return redirect("postproduccion.views.resumen_video", v.id)
    else:
        formset = FicheroEntradaFormSet(instance=v)

    for i in range(n):
        formset.forms[i].titulo = tipos[i].nombre
        if formset.forms[i].initial:
            formset.forms[i].initial["fichero"] = os.path.join(
                "/", os.path.relpath(formset.forms[i].initial["fichero"], config.get_option("VIDEO_INPUT_PATH"))
            )
    return render_to_response(
        "section-nueva-paso2-ficheros.html", {"v": v, "formset": formset}, context_instance=RequestContext(request)
    )
示例#2
0
文件: views.py 项目: Madh93/dpCat
def _fichero_entrada_simple(request, v, type = None):
    if request.method == 'POST':
        form = FicheroEntradaForm(request.POST, instance = v.ficheroentrada_set.all()[0]) if v.ficheroentrada_set.count() else FicheroEntradaForm(request.POST)
        if form.is_valid():
            fe = form.save(commit = False)
            fe.video = v
            fe.fichero = os.path.normpath(config.get_option('VIDEO_INPUT_PATH') + fe.fichero)
            fe.save()
            if type == 'reemplazar_video':
                queue.enqueue_copy(v)
                v.set_status('DEF')
                messages.success(request, "Vídeo reemplazado y encolado para su procesado")
                return redirect('postproduccion.views.estado_video', v.id)
            else:
                return redirect('postproduccion.views.resumen_video', v.id)
    else:
        if  v.ficheroentrada_set.count():
            fe = v.ficheroentrada_set.all()[0]
            fe.fichero = os.path.join('/', os.path.relpath(fe.fichero, config.get_option('VIDEO_INPUT_PATH')))
            form = FicheroEntradaForm(instance = fe)
        else:
            form = FicheroEntradaForm()

    if type == 'reemplazar_video':
        return render_to_response("postproduccion/section-reemplazar-video.html", { 'v' : v, 'form' : form }, context_instance=RequestContext(request))
    else:
        return render_to_response("postproduccion/section-nueva-paso2-fichero.html", { 'v' : v, 'form' : form }, context_instance=RequestContext(request))
示例#3
0
文件: functions.py 项目: Madh93/dpCat
def get_flow():
    return OAuth2WebServerFlow(client_id = config.get_option('YT_PUBLISHER_CLIENT_ID'),
                               client_secret = config.get_option('YT_PUBLISHER_CLIENT_SECRET'),
                               scope = YOUTUBE_SCOPES,
                               redirect_uri = urljoin(config.get_option('SITE_URL'), reverse('oauth2callback')),
                               approval_prompt='force',
                               access_type = 'offline')
示例#4
0
文件: video.py 项目: adrianrv/dpCat
def calculate_preview_size(v):
    [width, height, ratio] = get_tec_data(v.tecdata.xml_data)
    max_width = float(config.get_option('MAX_PREVIEW_WIDTH'))
    max_height = float(config.get_option('MAX_PREVIEW_HEIGHT'))

    # Hace los pixels cuadrados
    if ratio > 0:
        width = height * ratio
    else:
        try:
            height = width / ratio
        except ZeroDivisionError:
            pass
    
    # Reduce el ancho
    if width > max_width:
        r = max_width / width
        width *= r
        height *= r

    # Reduce el alto
    if height > max_height:
        r = max_height / height
        width *= r
        height *= r

    # Hace el tamaño par (necesario para algunos codecs)
    width = int((width + 1) / 2) * 2
    height = int((height + 1) / 2) * 2

    return dict({'width' : width, 'height' : height, 'ratio' : ratio})
示例#5
0
文件: encoder.py 项目: Madh93/dpCat
def embed_metadata(filename, metadata):
    """
    Incrusta la metadata al video final
    """

    if not os.path.exists(filename):
        return False

    command = "'%s' -config %s %s '%s'" % (
        config.get_option('EXIFTOOL_PATH'),
        config.get_option('EXIFTOOL_CONFIG'),
        metadata,
        filename
    )
    p = subprocess.Popen(
        shlex.split(str(command)),
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT
    )
    out, err = p.communicate()  # Esperar a finalizar

    # Borrar video original
    try:
        os.unlink(filename + '_original')
    except:
        pass

    return True
示例#6
0
文件: encoder.py 项目: pchinea/dpCat
def get_file_info(filename):
    command = "%s --Output=XML %s" % (config.get_option('MEDIAINFO_PATH'), filename)
    xml_data = subprocess.Popen(shlex.split(str(command)), stdout=subprocess.PIPE).communicate()[0]

    command = "%s %s" % (config.get_option('MEDIAINFO_PATH'), filename)
    txt_data = subprocess.Popen(shlex.split(str(command)), stdout=subprocess.PIPE).communicate()[0]
    
    return [xml_data, txt_data]
示例#7
0
文件: log.py 项目: pchinea/dpCat
def _register_entry():
    lock.acquire()
    current = int(config.get_option('CURRENT_LOG_SIZE')) if config.get_option('CURRENT_LOG_SIZE') else 0
    if current >= int(config.get_option('LOG_MAX_LINES')):
        _logrotate()
        current = 1
    else:
        current += 1
    config.set_option('CURRENT_LOG_SIZE', current)
    lock.release()
示例#8
0
文件: token.py 项目: Madh93/dpCat
def send_validation_mail_to_user(v, operador):
    """
    Envía un correo para avisar al usuario de
    que su producción ya ha sido validada.
    """
    try:
        send_mail(
            config.get_option('VALIDATED_MAIL_SUBJECT'),
            generate_validation_mail_message(v, operador),
            config.get_option('RETURN_EMAIL'),
            [v.email]
        )
    except:
        return None
    return v
示例#9
0
文件: token.py 项目: Madh93/dpCat
def send_published_mail_to_user(r):
    """
    Envía un correo para avisar al usuario
    de que su producción ya ha sido publicada.
    """
    try:
        send_mail(
            config.get_option('PUBLISHED_MAIL_SUBJECT'),
            generate_published_mail_message(r),
            config.get_option('RETURN_EMAIL'),
            [r.video.email]
        )
    except:
        return None
    return True
示例#10
0
文件: video.py 项目: adrianrv/dpCat
def create_preview(video, logfile, pid_notifier = None):
    # Actualiza el estado del vídeo
    video.set_status('PRP')

    # Obtiene los nombres de ficheros origen y destino
    src = video.fichero
    dst = os.path.join(config.get_option('PREVIEWS_PATH'), utils.generate_safe_filename(video.titulo, video.informeproduccion.fecha_produccion.date(), ".flv"))

    # Crea el objecto previsualización
    pv = Previsualizacion(video = video, fichero = dst)
    pv.save()

    # Calcula las dimensiones de la previsualización.
    size = calculate_preview_size(video)

    # Codifica la previsualización.
    utils.ensure_dir(pv.fichero)
    if encode_preview(src, dst, size, logfile, pid_notifier) != 0:
        video.set_status('COM')
        try:
            os.unlink(dst)
        except:
            pass
        return False

    # Actualiza el estado del vídeo
    video.set_status('PTU')
    return True
示例#11
0
文件: video.py 项目: adrianrv/dpCat
def copy_video(video, logfile):
    # Actualiza el estado del vídeo
    video.set_status('PRV')

    # Obtiene los nombres de ficheros origen y destino
    src = video.ficheroentrada_set.all()[0].fichero
    dst = os.path.join(config.get_option('VIDEO_LIBRARY_PATH'), utils.generate_safe_filename(video.titulo, video.informeproduccion.fecha_produccion.date(), os.path.splitext(src)[1]))
    video.fichero = dst
    video.save()

    # Copia el fichero.
    utils.ensure_dir(video.fichero)
    try:
        shutil.copy(src, dst)
        os.write(logfile, '%s -> %s\n' % (src, dst))
        os.chmod(dst, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP)
        os.write(logfile, 'chmod: 640\n')
    except IOError as error:
        os.write(logfile, error.__str__())
        video.set_status('DEF')
        return False

    # Obtiene la información técnica del vídeo copiado.
    generate_tecdata(video)

    # Actualiza el estado del vídeo
    if video.informeproduccion.aprobacion:
        video.set_status('COM')
    else:
        video.set_status('PTO')

    return True
示例#12
0
文件: views.py 项目: Madh93/dpCat
def feed(request):
    channel_data = get_channel_data()

    channel = dict()
    channel['id'] = channel_data['id']
    channel['title'] = channel_data['snippet']['title']
    channel['description'] = channel_data['snippet']['description']
    channel['logo'] = channel_data['snippet']['thumbnails']['default']['url']

    feed = dict()
    feed['build'] = formatdate(time.mktime(datetime.now().timetuple()))
    feed['baseurl'] = config.get_option(u'SITE_URL')

    video_list = get_all_public_video_data(channel['id'])

    items = list()
    for v in video_list:
        item = dict()
        item['id'] = v['id']
        item['title'] = v['snippet']['title']
        item['description'] = v['snippet']['description']
        published_at = datetime.strptime(v['snippet']['publishedAt'], "%Y-%m-%dT%H:%M:%S.000Z")
        item['published'] = dict()
        item['published']['short'] = published_at.date().isoformat()
        item['published']['long'] = formatdate(time.mktime(published_at.timetuple()))
        item['thumbnail'] = v['snippet']['thumbnails']['high']
        item['category'] = v['snippet']['tags'][-1]
        if 'tags' in item:
            item['tags'] = u','.join(v['snippet']['tags'][:-1])

        items.append(item)

    return render_to_response("yt_publisher/yt-feed.html", { 'channel' :  channel, 'feed' : feed, 'items' : items }, context_instance=RequestContext(request))
示例#13
0
文件: token.py 项目: Madh93/dpCat
def send_custom_mail_to_user(v, texto, operador):
    """
    Envía un correo personalizado al usuario
    para solicitar la aprobación y los metadatos de un vídeo.
    """
    v = create_token(v)
    try:
        send_mail(
            config.get_option('CUSTOM_MAIL_SUBJECT'),
            generate_custom_mail_message(v, texto, operador),
            config.get_option('RETURN_EMAIL'),
            [v.email]
        )
    except:
        return None
    return v
示例#14
0
文件: queue.py 项目: Madh93/dpCat
def available_slots():
    """
    Devuelve el número de puestos libres para
    iniciar el proceso de codificación.
    """
    return int(config.get_option('MAX_ENCODING_TASKS')) - \
        Cola.objects.count_actives()
示例#15
0
文件: token.py 项目: Madh93/dpCat
def send_mail_to_user(v):
    """
    Envía un correo al usuario para solicitar
    la aprobación y los metadatos de un vídeo.
    """
    v = create_token(v)
    try:
        send_mail(
            config.get_option('NOTIFY_MAIL_SUBJECT'),
            generate_mail_message(v),
            config.get_option('RETURN_EMAIL'),
            [v.email]
        )
    except:
        return None
    return v
示例#16
0
文件: views.py 项目: Madh93/dpCat
def _fichero_entrada_multiple(request, v, type = None):
    n = v.plantilla.tipovideo_set.count()
    FicheroEntradaFormSet = inlineformset_factory(Video, FicheroEntrada, formset = RequiredBaseInlineFormSet, form = FicheroEntradaForm, extra = n, max_num = n, can_delete = False)
    tipos = v.plantilla.tipovideo_set.all().order_by('id')
    if request.method == 'POST':
        formset = FicheroEntradaFormSet(request.POST, instance = v) if v.ficheroentrada_set.count() else FicheroEntradaFormSet(request.POST)
        print "previo"
        if formset.is_valid():
            instances = formset.save(commit = False)
            for i in range(n):
                instances[i].fichero = os.path.normpath(config.get_option('VIDEO_INPUT_PATH') + instances[i].fichero)
                instances[i].video = v
                instances[i].tipo = tipos[i]
                instances[i].save()
            if type == 'reemplazar_video':
                queue.enqueue_pil(v)
                v.set_status('DEF')
                messages.success(request, "Vídeo reemplazado y encolado para su procesado")
                return redirect('postproduccion.views.estado_video', v.id)
            else:
                return redirect('postproduccion.views.resumen_video', v.id)
    else:
        formset = FicheroEntradaFormSet(instance = v)

    for i in range(n):
        formset.forms[i].titulo = tipos[i].nombre
        if formset.forms[i].initial:
            formset.forms[i].initial['fichero'] = os.path.join('/', os.path.relpath(formset.forms[i].initial['fichero'], config.get_option('VIDEO_INPUT_PATH')))

    if type == 'reemplazar_video':
        return render_to_response("postproduccion/section-reemplazar-videos.html", { 'v' : v, 'formset' : formset }, context_instance=RequestContext(request))
    else:
        return render_to_response("postproduccion/section-nueva-paso2-ficheros.html", { 'v' : v, 'formset' : formset }, context_instance=RequestContext(request))
示例#17
0
文件: token.py 项目: Madh93/dpCat
def get_expire_time(t):
    """
    Devuelve la fecha de caducidad de un token.
    """
    return t.instante + timedelta(
        days=int(config.get_option('TOKEN_VALID_DAYS'))
    )
示例#18
0
文件: token.py 项目: Madh93/dpCat
def get_token_url(v):
    """
    Devuelve la url del ticket de usuario correspondiente al vídeo dado.
    """
    return urljoin(
        config.get_option('SITE_URL'),
        reverse('postproduccion.views.aprobacion_video', args=(v.token.token,))
    )
示例#19
0
文件: views.py 项目: pchinea/dpCat
def _fichero_entrada_simple(request, v):
    if request.method == 'POST':
        form = FicheroEntradaForm(request.POST, instance = v.ficheroentrada_set.all()[0]) if v.ficheroentrada_set.count() else FicheroEntradaForm(request.POST)
        if form.is_valid():
            fe = form.save(commit = False)
            fe.video = v
            fe.fichero = os.path.normpath(config.get_option('VIDEO_INPUT_PATH') + fe.fichero)
            fe.save()
            return redirect('postproduccion.views.resumen_video', v.id)
    else:
        if  v.ficheroentrada_set.count():
            fe = v.ficheroentrada_set.all()[0]
            fe.fichero = os.path.join('/', os.path.relpath(fe.fichero, config.get_option('VIDEO_INPUT_PATH')))
            form = FicheroEntradaForm(instance = fe)
        else:
            form = FicheroEntradaForm()
    return render_to_response("postproduccion/section-nueva-paso2-fichero.html", { 'v' : v, 'form' : form }, context_instance=RequestContext(request))
示例#20
0
文件: encoder.py 项目: adrianrv/dpCat
def make_streamable(filename, logfile, pid_notifier = None):
    command = "'%s' -inter 0.5 '%s' -tmp '%s'" % (config.get_option('MP4BOX_PATH'), filename, os.path.dirname(filename))
    p = subprocess.Popen(shlex.split(str(command)), stdout = subprocess.PIPE, stderr = subprocess.STDOUT)

    if pid_notifier:
        pid_notifier(p.pid)

    os.write(logfile, p.communicate()[0])
示例#21
0
文件: views.py 项目: adrianrv/dpCat
def status(request):
    # Programas externos
    avconvver = utils.avconv_version()
    meltver = utils.melt_version()
    mediainfover = utils.mediainfo_version()
    mp4boxver = utils.mp4box_version()
    exes = {
        "AVCONV": {
            "path": config.get_option("AVCONV_PATH"),
            "status": True if avconvver else False,
            "version": avconvver,
        },
        "MELT": {"path": config.get_option("MELT_PATH"), "status": True if meltver else False, "version": meltver},
        "crontab": {
            "path": config.get_option("CRONTAB_PATH"),
            "status": utils.is_exec(config.get_option("CRONTAB_PATH")),
            "version": "N/A",
        },
        "mediainfo": {
            "path": config.get_option("MEDIAINFO_PATH"),
            "status": True if mediainfover else False,
            "version": mediainfover,
        },
        "MP4Box": {
            "path": config.get_option("MP4BOX_PATH"),
            "status": True if mp4boxver else False,
            "version": mp4boxver,
        },
    }

    # Directorios
    dirs = dict()
    for i in [("library", "VIDEO_LIBRARY_PATH"), ("input", "VIDEO_INPUT_PATH"), ("previews", "PREVIEWS_PATH")]:
        data = {"path": config.get_option(i[1])}
        if utils.check_dir(data["path"]):
            df = utils.df(data["path"])
            data["info"] = {"total": df[0], "used": df[1], "left": df[2], "perc": df[3], "mount": df[4]}
        dirs[i[0]] = data

    # Tareas Programadas
    if request.method == "POST":
        if "status_process" in request.POST:
            if request.POST["status_process"] == "1":
                crontab.stop("procesar_video")
                messages.warning(request, "Tareas programadas de codificación desactivadas")
            else:
                crontab.start("procesar_video")
                messages.success(request, "Tareas programadas de codificacion activadas")
        if "status_publish" in request.POST:
            if request.POST["status_publish"] == "1":
                crontab.stop("publicar_video")
                messages.warning(request, "Tareas programadas de publicación desactivadas")
            else:
                crontab.start("publicar_video")
                messages.success(request, "Tareas programadas de publicación activadas")
    cron = {"process": crontab.status("procesar_video"), "publish": crontab.status("publicar_video")}

    return render_to_response(
        "section-status.html", {"exes": exes, "dirs": dirs, "cron": cron}, context_instance=RequestContext(request)
    )
示例#22
0
文件: forms.py 项目: adrianrv/dpCat
 def clean_fichero(self):
     data = self.cleaned_data['fichero']
     try:
         str(data)
     except UnicodeEncodeError:
         raise forms.ValidationError("El campo no debe contener tíldes ni caracteres especiales")
     if not is_video_file(os.path.normpath(config.get_option('VIDEO_INPUT_PATH') + data)):
         raise ValidationError(u"El fichero no es un formato de vídeo reconocido")
     return data
示例#23
0
文件: utils.py 项目: adrianrv/dpCat
def mediainfo_version():
    fpath = config.get_option('MEDIAINFO_PATH')
    if is_exec(fpath):
        command = "%s --Version" % fpath
        data = subprocess.Popen(shlex.split(str(command)), stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()[0]
        try:
            return re.search('(v[0-9\.]+)$', data).group(1)
        except AttributeError:
            return None
示例#24
0
文件: token.py 项目: adrianrv/dpCat
def generate_validation_mail_message(v, operador):
    (nombre, titulo, vid, fecha) = (v.autor, v.titulo, v.id, v.informeproduccion.fecha_grabacion)
    return Template(config.get_option('VALIDATED_MAIL_MESSAGE')).render(Context({
        'nombre'   : nombre,
        'titulo'   : titulo,
        'vid'      : vid,
        'fecha'    : fecha,
        'operador' : operador,
        }))
示例#25
0
文件: token.py 项目: adrianrv/dpCat
def generate_published_mail_message(r):
    (nombre, titulo, vid, fecha, url) = (r.video.autor, r.video.titulo, r.video.id, r.fecha, r.enlace)
    return Template(config.get_option('PUBLISHED_MAIL_MESSAGE')).render(Context({
        'nombre'   : nombre,
        'titulo'   : titulo,
        'vid'      : vid,
        'fecha'    : fecha,
        'url'      : url,
        }))
示例#26
0
文件: utils.py 项目: adrianrv/dpCat
def mp4box_version():
    fpath = config.get_option('MP4BOX_PATH')
    if is_exec(fpath):
        command = "%s -version" % fpath
        data = subprocess.Popen(shlex.split(str(command)), stdout = subprocess.PIPE, stderr = subprocess.STDOUT).communicate()[0]
        try:
            return re.search('version (\S*)', data).group(1)
        except AttributeError:
            return None
示例#27
0
文件: functions.py 项目: Madh93/dpCat
    def locked_get(self):
        credentials = None

        raw = config.get_option(self.__STORAGE_OPTION_KEY__)
        if raw:
            credentials = pickle.loads(base64.b64decode(raw))
            credentials.set_store(self)

        return credentials
示例#28
0
文件: utils.py 项目: adrianrv/dpCat
def avconv_version():
    fpath = config.get_option('AVCONV_PATH')
    if is_exec(fpath):
        command = "%s -version" % fpath
        data = subprocess.Popen(shlex.split(str(command)), stdout = subprocess.PIPE, stderr = subprocess.STDOUT).communicate()[0]
        try:
            return re.match('avconv version ([\.0-9]+)', data).group(1)
        except AttributeError:
            return None
示例#29
0
def execute_upload(v, category):
    php_path = config.get_option('CB_PUBLISHER_PHP_PATH')

    p = subprocess.Popen(php_path, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    messages = p.communicate(input=get_uploader_code(v, category))[0]

    if p.returncode == 0:
        return None
    else:
        return messages
示例#30
0
文件: log.py 项目: pchinea/dpCat
def _logrotate():
    for i in range(int(config.get_option('MAX_NUM_LOGFILES')) - 1, 1, -1):
        if os.path.isfile('%s.%s.gz' % (LOGFILE, i)):
            os.rename('%s.%s.gz' % (LOGFILE, i), '%s.%s.gz' % (LOGFILE, i + 1))
    if os.path.isfile('%s.%s' % (LOGFILE, 1)):
        os.rename('%s.%s' % (LOGFILE, 1), '%s.%s' % (LOGFILE, 2))
        _compress_file('%s.%s' % (LOGFILE, 2))
    if os.path.isfile(LOGFILE):
        os.rename(LOGFILE, '%s.%s' % (LOGFILE, 1))
    open(LOGFILE, 'w').close()