switch to requests, move playlist reader to utils, url quote, spellings

This commit is contained in:
jb-alvarado 2021-02-04 16:16:42 +01:00
parent cc3c47dd94
commit 52a33d39c0
2 changed files with 68 additions and 64 deletions

View File

@ -17,16 +17,10 @@
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
import os
import socket
import ssl
import time
from urllib import request
from .filters.default import build_filtergraph from .filters.default import build_filtergraph
from .utils import (MediaProbe, _playlist, gen_filler, get_date, get_delta, from .utils import (MediaProbe, _playlist, gen_filler, get_date, get_delta,
get_float, get_time, messenger, stdin_args, timed_source, get_float, get_time, messenger, read_playlist, stdin_args,
valid_json, validate_thread) timed_source)
class GetSourceFromPlaylist: class GetSourceFromPlaylist:
@ -37,6 +31,7 @@ class GetSourceFromPlaylist:
""" """
def __init__(self): def __init__(self):
self.list_date = get_date(True)
self.init_time = _playlist.start self.init_time = _playlist.start
self.last_time = get_time('full_sec') self.last_time = get_time('full_sec')
@ -49,15 +44,12 @@ class GetSourceFromPlaylist:
self.last_time += self.total_playtime self.last_time += self.total_playtime
self.last_mod_time = 0.0 self.last_mod_time = 0.0
self.json_file = None
self.clip_nodes = None self.clip_nodes = None
self.src_cmd = None self.src_cmd = None
self.probe = MediaProbe() self.probe = MediaProbe()
self.filtergraph = [] self.filtergraph = []
self.first = True self.first = True
self.last = False self.last = False
self.list_date = get_date(True)
self.node = None self.node = None
self.node_last = None self.node_last = None
self.node_next = None self.node_next = None
@ -66,49 +58,11 @@ class GetSourceFromPlaylist:
self.seek = 0 self.seek = 0
self.out = 20 self.out = 20
self.duration = 20 self.duration = 20
self.ad = False
self.ad_last = False
self.ad_next = False
def get_playlist(self): def get_playlist(self):
if stdin_args.playlist: self.clip_nodes, self.last_mod_time = read_playlist(self.list_date,
self.json_file = stdin_args.playlist self.last_mod_time,
else: self.clip_nodes)
year, month, day = self.list_date.split('-')
self.json_file = os.path.join(
_playlist.path, year, month, self.list_date + '.json')
if '://' in self.json_file:
self.json_file = self.json_file.replace('\\', '/')
try:
req = request.urlopen(self.json_file,
timeout=1,
context=ssl._create_unverified_context())
b_time = req.headers['last-modified']
temp_time = time.strptime(b_time, "%a, %d %b %Y %H:%M:%S %Z")
mod_time = time.mktime(temp_time)
if mod_time > self.last_mod_time:
self.clip_nodes = valid_json(req)
self.last_mod_time = mod_time
messenger.info('Open: ' + self.json_file)
validate_thread(self.clip_nodes)
except (request.URLError, socket.timeout):
self.eof_handling('Get playlist from url failed!', False)
elif os.path.isfile(self.json_file):
# check last modification from playlist
mod_time = os.path.getmtime(self.json_file)
if mod_time > self.last_mod_time:
with open(self.json_file, 'r', encoding='utf-8') as f:
self.clip_nodes = valid_json(f)
self.last_mod_time = mod_time
messenger.info('Open: ' + self.json_file)
validate_thread(self.clip_nodes)
else:
self.clip_nodes = None
def get_input(self): def get_input(self):
self.src_cmd, self.seek, self.out, self.next_playlist = timed_source( self.src_cmd, self.seek, self.out, self.next_playlist = timed_source(
@ -145,11 +99,8 @@ class GetSourceFromPlaylist:
self.last_mod_time = 0.0 self.last_mod_time = 0.0
self.last_time = _playlist.start - 1 self.last_time = _playlist.start - 1
def eof_handling(self, message, fill, duration=None): def eof_handling(self, fill, duration=None):
self.seek = 0.0 self.seek = 0.0
self.ad = False
messenger.error(message)
if duration: if duration:
self.out = duration self.out = duration
@ -177,8 +128,8 @@ class GetSourceFromPlaylist:
def peperation_task(self, index): def peperation_task(self, index):
# call functions in order to prepare source and filter # call functions in order to prepare source and filter
self.src = self.node['source'] self.probe.load(self.node.get('source'))
self.probe.load(self.src) self.src = self.probe.src
self.get_input() self.get_input()
self.last_and_next_node(index) self.last_and_next_node(index)
@ -190,8 +141,9 @@ class GetSourceFromPlaylist:
self.get_playlist() self.get_playlist()
if self.clip_nodes is None: if self.clip_nodes is None:
self.eof_handling( self.node = {'in': 0, 'out': 30, 'duration': 30}
f'No valid playlist:\n{self.json_file}', True, 30) messenger.error('clip_nodes are empty')
self.eof_handling(True, 30)
yield self.src_cmd + self.filtergraph yield self.src_cmd + self.filtergraph
continue continue
@ -231,10 +183,12 @@ class GetSourceFromPlaylist:
return None return None
elif self.begin == self.init_time: elif self.begin == self.init_time:
# no clip was played, generate dummy # no clip was played, generate dummy
self.eof_handling('Playlist is empty!', False) messenger.error('Playlist is empty!')
self.eof_handling(False)
else: else:
# playlist is not long enough, play filler # playlist is not long enough, play filler
self.eof_handling('Playlist is not long enough!', True) messenger.error('Playlist is not long enough!')
self.eof_handling(True)
if self.src_cmd is not None: if self.src_cmd is not None:
yield self.src_cmd + self.filtergraph yield self.src_cmd + self.filtergraph

View File

@ -27,6 +27,8 @@ import smtplib
import socket import socket
import sys import sys
import tempfile import tempfile
import time
import urllib
from argparse import ArgumentParser from argparse import ArgumentParser
from datetime import date, datetime, timedelta from datetime import date, datetime, timedelta
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
@ -39,6 +41,7 @@ from subprocess import STDOUT, CalledProcessError, check_output
from threading import Thread from threading import Thread
from types import SimpleNamespace from types import SimpleNamespace
import requests
import yaml import yaml
# path to user define configs # path to user define configs
@ -550,6 +553,8 @@ class MediaProbe:
self.video = [] self.video = []
if self.src and self.src.split('://')[0] in self.remote_source: if self.src and self.src.split('://')[0] in self.remote_source:
url = self.src.split('://')
self.src = f'{url[0]}://{urllib.parse.quote(url[1])}'
self.is_remote = True self.is_remote = True
else: else:
self.is_remote = False self.is_remote = False
@ -747,7 +752,7 @@ def validate_thread(clip_nodes):
if probe.is_remote: if probe.is_remote:
if not probe.video[0]: if not probe.video[0]:
missing.append(f'Stream not exist: "{source}"') missing.append(f'Remote file not exist: "{source}"')
elif not os.path.isfile(source): elif not os.path.isfile(source):
missing.append(f'File not exist: "{source}"') missing.append(f'File not exist: "{source}"')
@ -863,7 +868,7 @@ def src_or_dummy(probe, src, dur, seek, out):
if probe.is_remote and probe.video[0]: if probe.is_remote and probe.video[0]:
if seek > 0.0: if seek > 0.0:
messenger.warning( messenger.warning(
f'Seek in live source "{src}" not supported!') f'Seek in remote source "{src}" not supported!')
return ['-i', src] + set_length(86400.0, seek, out) return ['-i', src] + set_length(86400.0, seek, out)
elif src and os.path.isfile(src): elif src and os.path.isfile(src):
if out > dur: if out > dur:
@ -972,6 +977,51 @@ def handle_list_end(probe, new_length, src, begin, dur, seek, out):
return src_cmd, seek, new_out, new_playlist return src_cmd, seek, new_out, new_playlist
def read_playlist(list_date, modification_time, clip_nodes):
"""
read playlists from remote url or local file
and give his nodes and modification time back
"""
if stdin_args.playlist:
json_file = stdin_args.playlist
else:
year, month, day = list_date.split('-')
json_file = os.path.join(_playlist.path, year, month,
f'{list_date}.json')
if '://' in json_file:
json_file = json_file.replace('\\', '/')
try:
result = requests.get(json_file, timeout=1, verify=False)
b_time = result.headers['last-modified']
temp_time = time.strptime(b_time, "%a, %d %b %Y %H:%M:%S %Z")
mod_time = time.mktime(temp_time)
if mod_time > modification_time:
if isinstance(result.json(), dict):
clip_nodes = result.json()
modification_time = mod_time
messenger.info('Open: ' + json_file)
validate_thread(clip_nodes)
except (requests.exceptions.ConnectionError, socket.timeout):
messenger.error(f'No valid playlist from url: {json_file}')
elif os.path.isfile(json_file):
# check last modification from playlist
mod_time = os.path.getmtime(json_file)
if mod_time > modification_time:
with open(json_file, 'r', encoding='utf-8') as f:
clip_nodes = valid_json(f)
modification_time = mod_time
messenger.info('Open: ' + json_file)
validate_thread(clip_nodes)
return clip_nodes, modification_time
def timed_source(probe, src, begin, dur, seek, out, first, last): def timed_source(probe, src, begin, dur, seek, out, first, last):
""" """
prepare input clip prepare input clip