| @@ -15,16 +15,9 @@ import ntpath | |||||
| import yaml | import yaml | ||||
| from pathlib import Path | from pathlib import Path | ||||
| import logging | import logging | ||||
| from systemd.journal import JournalHandler | |||||
| log = logging.getLogger('demotape') | |||||
| log.addHandler(JournalHandler()) | |||||
| log.setLevel(logging.INFO) | |||||
| logging.basicConfig(filename='demotape.log', level=logging.INFO) | |||||
| logging.info("Starting demotape service at " + str(datetime.utcnow())) | |||||
| config_path = Path(__file__).parent / './config.yaml' | config_path = Path(__file__).parent / './config.yaml' | ||||
| with config_path.open() as file: | with config_path.open() as file: | ||||
| @@ -33,13 +26,13 @@ with config_path.open() as file: | |||||
| try: | try: | ||||
| if sys.argv[1] and os.path.exists(sys.argv[1]): | if sys.argv[1] and os.path.exists(sys.argv[1]): | ||||
| ROOT_PATH = sys.argv[1] | ROOT_PATH = sys.argv[1] | ||||
| log('Root path for downloaded streams: ' + ROOT_PATH) | |||||
| logging.info('Root path for downloaded streams: ' + ROOT_PATH) | |||||
| else: | else: | ||||
| log('destination path does not exist') | |||||
| logging.info('destination path does not exist') | |||||
| sys.exit() | sys.exit() | ||||
| except IndexError: | except IndexError: | ||||
| log('Script needs a valid destination path for recorded videos as argument') | |||||
| log('For example: \ndemotape.py /path/to/videos') | |||||
| logging.info('Script needs a valid destination path for recorded videos as argument') | |||||
| logging.info('For example: \ndemotape.py /path/to/videos') | |||||
| sys.exit() | sys.exit() | ||||
| @@ -61,9 +54,9 @@ def generate_channellist(): | |||||
| 'url': 'https://stream.wien.gv.at/live/ngrp:bv' + district_str_lz + '.stream_all/playlist.m3u8' | 'url': 'https://stream.wien.gv.at/live/ngrp:bv' + district_str_lz + '.stream_all/playlist.m3u8' | ||||
| } | } | ||||
| channels.append(channel) | channels.append(channel) | ||||
| log('channels:') | |||||
| logging.info('channels:') | |||||
| for channel in channels: | for channel in channels: | ||||
| log(channel['name'] + ' ' + channel['url']) | |||||
| logging.info(channel['name'] + ' ' + channel['url']) | |||||
| return channels | return channels | ||||
| @@ -77,33 +70,33 @@ def check_stream(url): | |||||
| # no livestream | # no livestream | ||||
| return False | return False | ||||
| except (ValueError, KeyError): | except (ValueError, KeyError): | ||||
| log('some connection error or so') | |||||
| logging.info('some connection error or so') | |||||
| class MyLogger(object): | class MyLogger(object): | ||||
| def debug(self, msg): | def debug(self, msg): | ||||
| #pass | #pass | ||||
| log(msg) | |||||
| logging.info(msg) | |||||
| def warning(self, msg): | def warning(self, msg): | ||||
| #pass | #pass | ||||
| log(msg) | |||||
| logging.info(msg) | |||||
| def error(self, msg): | def error(self, msg): | ||||
| log(msg) | |||||
| logging.info(msg) | |||||
| def my_ytdl_hook(d): | def my_ytdl_hook(d): | ||||
| if d['status'] == 'finished': | if d['status'] == 'finished': | ||||
| log(timestamp() + 'Done downloading!') | |||||
| logging.info(timestamp() + 'Done downloading!') | |||||
| else: | else: | ||||
| log(timestamp() + 'sth went wrong' + d['status']) | |||||
| log(d) | |||||
| logging.info(timestamp() + 'sth went wrong' + d['status']) | |||||
| logging.info(d) | |||||
| def download_stream(channel, dest_path): | def download_stream(channel, dest_path): | ||||
| log('download_stream') | |||||
| logging.info('download_stream') | |||||
| ytdl_opts = { | ytdl_opts = { | ||||
| 'logger': MyLogger(), | 'logger': MyLogger(), | ||||
| 'outtmpl': dest_path, | 'outtmpl': dest_path, | ||||
| @@ -122,42 +115,42 @@ def download_stream(channel, dest_path): | |||||
| ytdl = youtube_dl.YoutubeDL(ytdl_opts) | ytdl = youtube_dl.YoutubeDL(ytdl_opts) | ||||
| try: | try: | ||||
| log(timestamp() + " Downloading: " + channel['url']) | |||||
| logging.info(timestamp() + " Downloading: " + channel['url']) | |||||
| ytdl.download([channel['url']]) | ytdl.download([channel['url']]) | ||||
| except (youtube_dl.utils.DownloadError) as e: | except (youtube_dl.utils.DownloadError) as e: | ||||
| log(timestamp() + " Download error: " + str(e)) | |||||
| logging.info(timestamp() + " Download error: " + str(e)) | |||||
| except (youtube_dl.utils.SameFileError) as e: | except (youtube_dl.utils.SameFileError) as e: | ||||
| log("Download error: " + str(e)) | |||||
| logging.info("Download error: " + str(e)) | |||||
| except (UnicodeDecodeError) as e: | except (UnicodeDecodeError) as e: | ||||
| log("UnicodeDecodeError: " + str(e)) | |||||
| logging.info("UnicodeDecodeError: " + str(e)) | |||||
| def process_channel(channel): | def process_channel(channel): | ||||
| #log('entered function process_channel with ' + channel['name']) | |||||
| #logging.info('entered function process_channel with ' + channel['name']) | |||||
| while True: | while True: | ||||
| log(timestamp() + ' checking ' + channel['name']) | |||||
| logging.info(timestamp() + ' checking ' + channel['name']) | |||||
| if check_stream(channel['url']): | if check_stream(channel['url']): | ||||
| log(channel['name'] + ': stream online! Downloading ...') | |||||
| logging.info(channel['name'] + ': stream online! Downloading ...') | |||||
| dest_dir = ROOT_PATH + '/' + channel['name'] +'/' | dest_dir = ROOT_PATH + '/' + channel['name'] +'/' | ||||
| # create directory if it doesn't exist | # create directory if it doesn't exist | ||||
| if not os.path.exists(dest_dir): | if not os.path.exists(dest_dir): | ||||
| log('creating directory ' + dest_dir) | |||||
| logging.info('creating directory ' + dest_dir) | |||||
| os.makedirs(dest_dir) | os.makedirs(dest_dir) | ||||
| dest_path = get_destpath(channel) # dirctory + filename | dest_path = get_destpath(channel) # dirctory + filename | ||||
| download_stream(channel, dest_path) # also converts video | download_stream(channel, dest_path) # also converts video | ||||
| log(timestamp() + " Uploading video " + dest_path) | |||||
| logging.info(timestamp() + " Uploading video " + dest_path) | |||||
| upload_video(dest_path) | upload_video(dest_path) | ||||
| else: | else: | ||||
| waitingtime = random.randint(50,60) | waitingtime = random.randint(50,60) | ||||
| time.sleep(waitingtime) | time.sleep(waitingtime) | ||||
| log('end processing ' + channel['name'] + ' ... (shouldn\'t happen!)') | |||||
| logging.info('end processing ' + channel['name'] + ' ... (shouldn\'t happen!)') | |||||
| def upload_video(videofile_path): | def upload_video(videofile_path): | ||||
| log('uploading %s' % (videofile_path)) | |||||
| logging.info('uploading %s' % (videofile_path)) | |||||
| credentials = config['webdav']['username'] + ':' + config['webdav']['password'] | credentials = config['webdav']['username'] + ':' + config['webdav']['password'] | ||||
| webdav_baseurl = config['webdav']['base_url'] | webdav_baseurl = config['webdav']['base_url'] | ||||
| filename = ntpath.basename(videofile_path) | filename = ntpath.basename(videofile_path) | ||||
| @@ -169,7 +162,7 @@ def upload_video(videofile_path): | |||||
| delete_video(videofile_path) | delete_video(videofile_path) | ||||
| return true | return true | ||||
| except: | except: | ||||
| log('Error while uploading %s to %s' % (file, webdav_url)) | |||||
| logging.info('Error while uploading %s to %s' % (file, webdav_url)) | |||||
| def delete_video(file): | def delete_video(file): | ||||
| @@ -177,7 +170,7 @@ def delete_video(file): | |||||
| os.system('rm -rf "%s"' % (file)) | os.system('rm -rf "%s"' % (file)) | ||||
| return true | return true | ||||
| except: | except: | ||||
| log('Error while deleting %s' % (file)) | |||||
| logging.info('Error while deleting %s' % (file)) | |||||
| def get_destpath(channel): | def get_destpath(channel): | ||||
| @@ -198,12 +191,12 @@ def main(): | |||||
| try: | try: | ||||
| data = future.result() | data = future.result() | ||||
| except Exception as exc: | except Exception as exc: | ||||
| log('%r generated an exception: %s' % (channel, exc)) | |||||
| logging.info('%r generated an exception: %s' % (channel, exc)) | |||||
| else: | else: | ||||
| log('%r page is %d bytes' % (channel, len(data))) | |||||
| logging.info('%r page is %d bytes' % (channel, len(data))) | |||||
| log('end main (this shouldn\'t happen!)') | |||||
| logging.info('end main (this shouldn\'t happen!)') | |||||
| main() | main() | ||||