From 33b70e3ec73a8c71d17b71bfc816ce786066d63c Mon Sep 17 00:00:00 2001 From: joyfuI Date: Sat, 25 Jul 2020 03:06:03 +0900 Subject: [PATCH] =?UTF-8?q?v1.6.4=20FFmpeg=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FFmpeg 경로 설정 추가 API에서 GET 요청 지원 --- README.md | 8 +- info.json | 2 +- logic.py | 7 +- logic_normal.py | 58 ++++++++-- my_youtube_dl.py | 26 ++--- plugin.py | 164 +++++++++++++---------------- templates/youtube-dl_download.html | 19 ++-- templates/youtube-dl_list.html | 30 +++--- templates/youtube-dl_setting.html | 36 ++++++- 9 files changed, 208 insertions(+), 142 deletions(-) diff --git a/README.md b/README.md index 67ffc99..4dbd9c7 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ API에선 직접 비트레이트를 설정할 수 있습니다. ## API ### 공통사항 -모든 요청은 `POST`로만 받습니다. 그리고 응답은 `JSON` 형식입니다. +모든 요청은 `POST` 또는 `GET`만 받습니다. 그리고 응답은 `JSON` 형식입니다. 모든 요청엔 *플러그인 이름* 정보가 있어야 합니다. `plugin` 키에 담아서 보내면 됩니다. 만약 *플러그인 이름* 정보가 없으면 **403 에러**를 반환합니다. 요청을 처리하는 과정에서 예외가 발생하면 **500 에러**를 반환합니다. 이건 저한테 로그와 함께 알려주시면 됩니다. 모든 응답에는 `errorCode` 키가 있습니다. 코드의 의미는 아래 문단 참고 @@ -131,6 +131,12 @@ API에선 직접 비트레이트를 설정할 수 있습니다. 물론 해당 정보가 없으면 null입니다. ## Changelog +v1.6.4 +* FFmpeg 경로 설정 추가 + SJVA에 내장된 버전 말고 원하는 버전을 사용할 수 있습니다. +* API에서 GET 요청 지원 + 이제 GET 요청으로도 API를 사용할 수 있습니다. + v1.6.3 * 프록시 기능을 사용해도 국가차단 우회가 안 되는 문제 수정 diff --git a/info.json b/info.json index 23243fe..9226df5 100644 --- a/info.json +++ b/info.json @@ -1 +1 @@ -{"description": "\uc720\ud29c\ube0c, \ub124\uc774\ubc84TV \ub4f1 \ub3d9\uc601\uc0c1 \uc0ac\uc774\ud2b8\uc5d0\uc11c \ub3d9\uc601\uc0c1 \ub2e4\uc6b4\ub85c\ub4dc", "name": "youtube-dl", "more": "", "version": "1.6.3", "home": "https://github.com/joyfuI/youtube-dl", "category_name": "vod", "developer": "joyfuI"} \ No newline at end of file +{"description": "\uc720\ud29c\ube0c, \ub124\uc774\ubc84TV \ub4f1 \ub3d9\uc601\uc0c1 \uc0ac\uc774\ud2b8\uc5d0\uc11c \ub3d9\uc601\uc0c1 \ub2e4\uc6b4\ub85c\ub4dc", "name": "youtube-dl", "more": "", "version": "1.6.4", "home": "https://github.com/joyfuI/youtube-dl", "category_name": "vod", "developer": "joyfuI"} \ No newline at end of file diff --git a/logic.py b/logic.py index ffd9f65..2143b9d 100644 --- a/logic.py +++ b/logic.py @@ -3,13 +3,14 @@ # python import os import sys +import platform import subprocess import traceback # third-party # sjva 공용 -from framework import db, path_data +from framework import db, path_app_root, path_data from framework.util import Util # 패키지 @@ -20,6 +21,7 @@ from .model import ModelSetting class Logic(object): db_default = { 'db_version': '1', + 'ffmpeg_path': 'ffmpeg' if platform.system() != 'Windows' else os.path.join(path_app_root, 'bin', 'Windows', 'ffmpeg.exe'), 'temp_path': os.path.join(path_data, 'download_tmp'), 'save_path': os.path.join(path_data, 'download'), 'default_filename': '%(title)s-%(id)s.%(ext)s', @@ -45,16 +47,15 @@ class Logic(object): logger.debug('%s plugin_load', package_name) Logic.db_init() + # 모듈 설치 try: import glob2 except ImportError: - # glob2 설치 logger.debug('glob2 install') logger.debug(subprocess.check_output([sys.executable, '-m', 'pip', 'install', 'glob2'], universal_newlines=True)) try: import flask_cors except ImportError: - # flask-cors 설치 logger.debug('flask-cors install') logger.debug(subprocess.check_output([sys.executable, '-m', 'pip', 'install', 'flask-cors'], universal_newlines=True)) diff --git a/logic_normal.py b/logic_normal.py index b8853ea..775e5ba 100644 --- a/logic_normal.py +++ b/logic_normal.py @@ -9,15 +9,19 @@ from flask import jsonify # 패키지 from .plugin import logger -from .my_youtube_dl import Status +from .my_youtube_dl import MyYoutubeDL, Status ######################################################### class LogicNormal(object): youtube_dl_list = [] + @staticmethod + def get_youtube_dl_version(): + return MyYoutubeDL.get_version() + @staticmethod def get_preset_list(): - preset_list = [ + return [ ['bestvideo+bestaudio/best', '최고 화질'], ['bestvideo[height<=1080]+bestaudio/best[height<=1080]', '1080p'], ['worstvideo+worstaudio/worst', '최저 화질'], @@ -27,11 +31,10 @@ class LogicNormal(object): ['bestaudio/best', '오디오만'], ['_custom', '사용자 정의'] ] - return preset_list @staticmethod def get_postprocessor_list(): - postprocessor_list = [ + return [ ['', '후처리 안함', None], ['mp4', 'MP4', '비디오 변환'], ['flv', 'FLV', '비디오 변환'], @@ -51,7 +54,6 @@ class LogicNormal(object): ['vorbis', 'Vorbis', '오디오 추출'], ['wav', 'WAV', '오디오 추출'] ] - return postprocessor_list @staticmethod def get_postprocessor(): @@ -64,6 +66,42 @@ class LogicNormal(object): extract_audio.append(i[0]) return video_convertor, extract_audio + @staticmethod + def download(**kwagrs): + logger.debug(kwagrs) + plugin = kwagrs['plugin'] + url = kwagrs['url'] + filename = kwagrs['filename'] + temp_path = kwagrs['temp_path'] + save_path = kwagrs['save_path'] + opts = {} + if 'format' in kwagrs and kwagrs['format']: + opts['format'] = kwagrs['format'] + postprocessor = [] + if 'preferedformat' in kwagrs and kwagrs['preferedformat']: + postprocessor.append({ + 'key': 'FFmpegVideoConvertor', + 'preferedformat': kwagrs['preferedformat'] + }) + if 'preferredcodec' in kwagrs and kwagrs['preferredcodec']: + postprocessor.append({ + 'key': 'FFmpegExtractAudio', + 'preferredcodec': kwagrs['preferredcodec'], + 'preferredquality': str(kwagrs['preferredquality']) + }) + if postprocessor: + opts['postprocessors'] = postprocessor + if 'archive' in kwagrs and kwagrs['archive']: + opts['download_archive'] = kwagrs['archive'] + if 'proxy' in kwagrs and kwagrs['proxy']: + opts['proxy'] = kwagrs['proxy'] + if 'ffmpeg_path' in kwagrs and kwagrs['ffmpeg_path']: + opts['ffmpeg_location'] = kwagrs['ffmpeg_path'] + youtube_dl = MyYoutubeDL(plugin, url, filename, temp_path, save_path, opts) + youtube_dl.key = kwagrs.get('key') + LogicNormal.youtube_dl_list.append(youtube_dl) # 리스트 추가 + return youtube_dl + @staticmethod def get_data(youtube_dl): try: @@ -86,16 +124,16 @@ class LogicNormal(object): data['percent'] = '0' data['eta'] = youtube_dl.progress_hooks['eta'] if youtube_dl.progress_hooks['eta'] is not None else '' data['speed_str'] = LogicNormal.human_readable_size(youtube_dl.progress_hooks['speed'], '/s') if youtube_dl.progress_hooks['speed'] is not None else '' - if youtube_dl.status == Status.READY: # 다운로드 전 + if youtube_dl.status == Status.READY: # 다운로드 전 data['start_time'] = '' data['download_time'] = '' else: - if youtube_dl.end_time is None: # 완료 전 + if youtube_dl.end_time is None: # 완료 전 download_time = datetime.now() - youtube_dl.start_time else: download_time = youtube_dl.end_time - youtube_dl.start_time data['end_time'] = youtube_dl.end_time.strftime('%m-%d %H:%M:%S') - if None not in (youtube_dl.progress_hooks['downloaded_bytes'], youtube_dl.progress_hooks['total_bytes']): # 둘 다 값이 있으면 + if None not in (youtube_dl.progress_hooks['downloaded_bytes'], youtube_dl.progress_hooks['total_bytes']): # 둘 다 값이 있으면 data['downloaded_bytes_str'] = LogicNormal.human_readable_size(youtube_dl.progress_hooks['downloaded_bytes']) data['total_bytes_str'] = LogicNormal.human_readable_size(youtube_dl.progress_hooks['total_bytes']) data['percent'] = '%.2f' % (float(youtube_dl.progress_hooks['downloaded_bytes']) / float(youtube_dl.progress_hooks['total_bytes']) * 100) @@ -107,6 +145,10 @@ class LogicNormal(object): logger.error(traceback.format_exc()) return None + @staticmethod + def get_info_dict(url, proxy): + MyYoutubeDL.get_info_dict(url, proxy) + @staticmethod def human_readable_size(size, suffix=''): for unit in ('Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB'): diff --git a/my_youtube_dl.py b/my_youtube_dl.py index d0bc88d..9ca8d5c 100644 --- a/my_youtube_dl.py +++ b/my_youtube_dl.py @@ -39,8 +39,8 @@ class Status(Enum): return str_list[self.value] -class Youtube_dl(object): - _index = 0 +class MyYoutubeDL(object): + __index = 0 _last_msg = '' def __init__(self, plugin, url, filename, temp_path, save_path=None, opts=None): @@ -58,10 +58,10 @@ class Youtube_dl(object): os.makedirs(save_path) self.save_path = save_path self.opts = opts - self.index = Youtube_dl._index - Youtube_dl._index += 1 - self._status = Status.READY - self._thread = None + self.index = MyYoutubeDL.__index + MyYoutubeDL.__index += 1 + self.__status = Status.READY + self.__thread = None self.key = None self.start_time = None # 시작 시간 self.end_time = None # 종료 시간 @@ -86,8 +86,8 @@ class Youtube_dl(object): def start(self): if self.status != Status.READY: return False - self._thread = Thread(target=self.run) - self._thread.start() + self.__thread = Thread(target=self.run) + self.__thread.start() return True def run(self): @@ -96,7 +96,7 @@ class Youtube_dl(object): try: self.start_time = datetime.now() self.status = Status.START - info_dict = Youtube_dl.get_info_dict(self.url, self.opts.get('proxy')) # 동영상 정보 가져오기 + info_dict = MyYoutubeDL.get_info_dict(self.url, self.opts.get('proxy')) # 동영상 정보 가져오기 if info_dict is None: # 가져오기 실패 self.status = Status.ERROR return @@ -163,7 +163,7 @@ class Youtube_dl(object): logger.error('Exception:%s', e) logger.error(traceback.format_exc()) return None - return json.loads(Youtube_dl._last_msg) + return json.loads(MyYoutubeDL._last_msg) def my_hook(self, d): if self.status != Status.STOP: @@ -188,18 +188,18 @@ class Youtube_dl(object): @property def status(self): - return self._status + return self.__status @status.setter def status(self, value): from .plugin import socketio_emit - self._status = value + self.__status = value socketio_emit('status', self) class MyLogger(object): def debug(self, msg): - Youtube_dl._last_msg = msg + MyYoutubeDL._last_msg = msg if msg.find('') != -1 or msg.find('{') != -1: return # 과도한 로그 방지 logger.debug(msg) diff --git a/plugin.py b/plugin.py index c3caee1..41849db 100644 --- a/plugin.py +++ b/plugin.py @@ -3,6 +3,7 @@ # python import os import traceback +import subprocess # third-party from flask import Blueprint, request, render_template, redirect, jsonify, abort @@ -18,7 +19,6 @@ logger = get_logger(package_name) from .logic import Logic from .logic_normal import LogicNormal from .model import ModelSetting -from .my_youtube_dl import Youtube_dl ######################################################### # 플러그인 공용 @@ -34,7 +34,7 @@ menu = { } plugin_info = { - 'version': '1.6.3', + 'version': '1.6.4', 'name': 'youtube-dl', 'category_name': 'vod', 'developer': 'joyfuI', @@ -67,7 +67,7 @@ def first_menu(sub): if sub == 'setting': arg.update(ModelSetting.to_dict()) - arg['youtube_dl_version'] = Youtube_dl.get_version() + arg['youtube_dl_version'] = LogicNormal.get_youtube_dl_version() return render_template('%s_%s.html' % (package_name, sub), arg=arg) elif sub == 'download': @@ -100,33 +100,33 @@ def ajax(sub): return jsonify(ret) # UI 요청 + elif sub == 'ffmpeg_version': + path = request.form['path'] + ret = subprocess.check_output([path, '-version']).replace('\n', '
') + return jsonify(ret) + elif sub == 'download': - url = request.form['url'] - filename = request.form['filename'] - temp_path = ModelSetting.get('temp_path') - save_path = ModelSetting.get('save_path') - format_code = request.form['format'] postprocessor = request.form['postprocessor'] - proxy = ModelSetting.get('proxy') - opts = {} - if format_code: - opts['format'] = format_code video_convertor, extract_audio = LogicNormal.get_postprocessor() + preferedformat = None + preferredcodec = None + preferredquality = None if postprocessor in video_convertor: - opts['postprocessors'] = [{ - 'key': 'FFmpegVideoConvertor', - 'preferedformat': postprocessor - }] + preferedformat = postprocessor elif postprocessor in extract_audio: - opts['postprocessors'] = [{ - 'key': 'FFmpegExtractAudio', - 'preferredcodec': postprocessor, - 'preferredquality': '192' - }] - if proxy: - opts['proxy'] = proxy - youtube_dl = Youtube_dl(package_name, url, filename, temp_path, save_path, opts) - LogicNormal.youtube_dl_list.append(youtube_dl) # 리스트 추가 + preferredcodec = postprocessor + preferredquality = 192 + youtube_dl = LogicNormal.download(plugin=package_name, + url=request.form['url'], + filename=request.form['filename'], + temp_path=ModelSetting.get('temp_path'), + save_path=ModelSetting.get('save_path'), + format=request.form['format'], + preferedformat=preferedformat, + preferredcodec=preferredcodec, + preferredquality=preferredquality, + proxy=ModelSetting.get('proxy'), + ffmpeg_path=ModelSetting.get('ffmpeg_path')) youtube_dl.start() socketio_emit('add', youtube_dl) return jsonify([]) @@ -154,75 +154,63 @@ def ajax(sub): @blueprint.route('/api/', methods=['GET', 'POST']) @check_api def api(sub): - plugin = request.form.get('plugin') + plugin = request.values.get('plugin') logger.debug('API %s %s: %s', package_name, sub, plugin) if not plugin: # 요청한 플러그인명이 빈문자열이거나 None면 abort(403) # 403 에러(거부) try: # 동영상 정보를 반환하는 API if sub == 'info_dict': - url = request.form.get('url') + url = request.values.get('url') ret = { 'errorCode': 0, 'info_dict': None } if None in (url,): - return LogicNormal.abort(ret, 1) # 필수 요청 변수가 없음 + return LogicNormal.abort(ret, 1) # 필수 요청 변수가 없음 if not url.startswith('http'): - return LogicNormal.abort(ret, 2) # 잘못된 동영상 주소 - info_dict = Youtube_dl.get_info_dict(url, ModelSetting.get('proxy')) + return LogicNormal.abort(ret, 2) # 잘못된 동영상 주소 + info_dict = LogicNormal.get_info_dict(url, ModelSetting.get('proxy')) if info_dict is None: - return LogicNormal.abort(ret, 10) # 실패 + return LogicNormal.abort(ret, 10) # 실패 ret['info_dict'] = info_dict return jsonify(ret) # 다운로드 준비를 요청하는 API elif sub == 'download': - key = request.form.get('key') - url = request.form.get('url') - filename = request.form.get('filename', ModelSetting.get('default_filename')) - save_path = request.form.get('save_path', ModelSetting.get('save_path')) - format_code = request.form.get('format', None) - preferedformat = request.form.get('preferedformat', None) - preferredcodec = request.form.get('preferredcodec', None) - preferredquality = request.form.get('preferredquality', 192) - archive = request.form.get('archive', None) - start = request.form.get('start', False) + key = request.values.get('key') + url = request.values.get('url') + filename = request.values.get('filename', ModelSetting.get('default_filename')) + save_path = request.values.get('save_path', ModelSetting.get('save_path')) + format_code = request.values.get('format', None) + preferedformat = request.values.get('preferedformat', None) + preferredcodec = request.values.get('preferredcodec', None) + preferredquality = request.values.get('preferredquality', 192) + archive = request.values.get('archive', None) + start = request.values.get('start', False) ret = { 'errorCode': 0, 'index': None } if None in (key, url): - return LogicNormal.abort(ret, 1) # 필수 요청 변수가 없음 + return LogicNormal.abort(ret, 1) # 필수 요청 변수가 없음 if not url.startswith('http'): - return LogicNormal.abort(ret, 2) # 잘못된 동영상 주소 - opts = {} - if format_code is not None: - opts['format'] = format_code - postprocessor = [] - if preferedformat is not None: - postprocessor.append({ - 'key': 'FFmpegVideoConvertor', - 'preferedformat': preferedformat - }) - if preferredcodec is not None: - if preferredcodec not in ('best', 'mp3', 'aac', 'flac', 'm4a', 'opus', 'vorbis', 'wav'): - return LogicNormal.abort(ret, 5) # 허용되지 않은 값이 있음 - postprocessor.append({ - 'key': 'FFmpegExtractAudio', - 'preferredcodec': preferredcodec, - 'preferredquality': str(preferredquality) - }) - if postprocessor: - opts['postprocessors'] = postprocessor - proxy = ModelSetting.get('proxy') - if proxy: - opts['proxy'] = proxy - if archive is not None: - opts['download_archive'] = archive - youtube_dl = Youtube_dl(plugin, url, filename, ModelSetting.get('temp_path'), save_path, opts) - youtube_dl.key = key - LogicNormal.youtube_dl_list.append(youtube_dl) # 리스트 추가 + return LogicNormal.abort(ret, 2) # 잘못된 동영상 주소 + if preferredcodec not in (None, 'best', 'mp3', 'aac', 'flac', 'm4a', 'opus', 'vorbis', 'wav'): + return LogicNormal.abort(ret, 5) # 허용되지 않은 값이 있음 + youtube_dl = LogicNormal.download(plugin=plugin, + url=url, + filename=filename, + temp_path=ModelSetting.get('temp_path'), + save_path=save_path, + format=format_code, + preferedformat=preferedformat, + preferredcodec=preferredcodec, + preferredquality=preferredquality, + archive=archive, + proxy=ModelSetting.get('proxy'), + ffmpeg_path=ModelSetting.get('ffmpeg_path'), + key=key) ret['index'] = youtube_dl.index if start: youtube_dl.start() @@ -231,50 +219,50 @@ def api(sub): # 다운로드 시작을 요청하는 API elif sub == 'start': - index = request.form.get('index') - key = request.form.get('key') + index = request.values.get('index') + key = request.values.get('key') ret = { 'errorCode': 0, 'status': None } if None in (index, key): - return LogicNormal.abort(ret, 1) # 필수 요청 변수가 없음 + return LogicNormal.abort(ret, 1) # 필수 요청 변수가 없음 index = int(index) if not (0 <= index < len(LogicNormal.youtube_dl_list)): - return LogicNormal.abort(ret, 3) # 인덱스 범위를 벗어남 + return LogicNormal.abort(ret, 3) # 인덱스 범위를 벗어남 youtube_dl = LogicNormal.youtube_dl_list[index] if youtube_dl.key != key: - return LogicNormal.abort(ret, 4) # 키가 일치하지 않음 + return LogicNormal.abort(ret, 4) # 키가 일치하지 않음 ret['status'] = youtube_dl.status.name if not youtube_dl.start(): - return LogicNormal.abort(ret, 10) # 실패 + return LogicNormal.abort(ret, 10) # 실패 return jsonify(ret) # 다운로드 중지를 요청하는 API elif sub == 'stop': - index = request.form.get('index') - key = request.form.get('key') + index = request.values.get('index') + key = request.values.get('key') ret = { 'errorCode': 0, 'status': None } if None in (index, key): - return LogicNormal.abort(ret, 1) # 필수 요청 변수가 없음 + return LogicNormal.abort(ret, 1) # 필수 요청 변수가 없음 index = int(index) if not (0 <= index < len(LogicNormal.youtube_dl_list)): - return LogicNormal.abort(ret, 3) # 인덱스 범위를 벗어남 + return LogicNormal.abort(ret, 3) # 인덱스 범위를 벗어남 youtube_dl = LogicNormal.youtube_dl_list[index] if youtube_dl.key != key: - return LogicNormal.abort(ret, 4) # 키가 일치하지 않음 + return LogicNormal.abort(ret, 4) # 키가 일치하지 않음 ret['status'] = youtube_dl.status.name if not youtube_dl.stop(): - return LogicNormal.abort(ret, 10) # 실패 + return LogicNormal.abort(ret, 10) # 실패 return jsonify(ret) # 현재 상태를 반환하는 API elif sub == 'status': - index = request.form.get('index') - key = request.form.get('key') + index = request.values.get('index') + key = request.values.get('key') ret = { 'errorCode': 0, 'status': None, @@ -284,13 +272,13 @@ def api(sub): 'save_path': None } if None in (index, key): - return LogicNormal.abort(ret, 1) # 필수 요청 변수가 없음 + return LogicNormal.abort(ret, 1) # 필수 요청 변수가 없음 index = int(index) if not (0 <= index < len(LogicNormal.youtube_dl_list)): - return LogicNormal.abort(ret, 3) # 인덱스 범위를 벗어남 + return LogicNormal.abort(ret, 3) # 인덱스 범위를 벗어남 youtube_dl = LogicNormal.youtube_dl_list[index] if youtube_dl.key != key: - return LogicNormal.abort(ret, 4) # 키가 일치하지 않음 + return LogicNormal.abort(ret, 4) # 키가 일치하지 않음 ret['status'] = youtube_dl.status.name ret['start_time'] = youtube_dl.start_time.strftime('%Y-%m-%dT%H:%M:%S') if youtube_dl.start_time is not None else None ret['end_time'] = youtube_dl.end_time.strftime('%Y-%m-%dT%H:%M:%S') if youtube_dl.end_time is not None else None @@ -301,7 +289,7 @@ def api(sub): logger.error('Exception:%s', e) logger.error(traceback.format_exc()) abort(500) # 500 에러(서버 오류) - abort(404) # 404 에러(페이지 없음) + abort(404) # 404 에러(페이지 없음) ######################################################### # socketio diff --git a/templates/youtube-dl_download.html b/templates/youtube-dl_download.html index d0b366b..5bc4d51 100644 --- a/templates/youtube-dl_download.html +++ b/templates/youtube-dl_download.html @@ -57,7 +57,7 @@ // 후처리 변경 $('#postprocessor').change(function () { - if ($(this).find($('option[value="' + $(this).val() + '"]')).parent().attr('label') === '오디오 추출') { + if ($(this).find($(`option[value="${$(this).val()}"]`)).parent().attr('label') === '오디오 추출') { $('#preset').val('bestaudio/best').change(); } }); @@ -72,7 +72,7 @@ return; } $.ajax({ - url: '/' + package_name + '/ajax/download', + url: `/${package_name}/ajax/download`, type: 'POST', cache: false, data: { @@ -81,12 +81,15 @@ format: $('#format').val(), postprocessor: $('#postprocessor').val() }, - dataType: 'json', - success: function () { - $.notify('분석중..', { - type: 'info' - }); - } + dataType: 'json' + }).done(function () { + $.notify('분석중..', { + type: 'info' + }); + }).fail(function () { + $.notify('다운로드 요청 실패', { + type: 'danger' + }); }); return false; }); diff --git a/templates/youtube-dl_list.html b/templates/youtube-dl_list.html index bf5a7d3..4d96f28 100644 --- a/templates/youtube-dl_list.html +++ b/templates/youtube-dl_list.html @@ -43,7 +43,7 @@ const package_name = '{{ arg["package_name"] }}'; $(function () { - let socket = io.connect(location.origin + '/' + package_name); + let socket = io.connect(`${location.origin}/${package_name}`); socket.on('add', function (data) { $('#list').append(make_item(data)); @@ -54,33 +54,31 @@ }); $.ajax({ - url: '/' + package_name + '/ajax/list', + url: `/${package_name}/ajax/list`, type: 'POST', cache: false, data: {}, - dataType: 'json', - success: function (data) { - let str = ''; - for (let i of data) { - str += make_item(i); - } - $('#list').html(str); + dataType: 'json' + }).done(function (data) { + let str = ''; + for (let item of data) { + str += make_item(item); } + $('#list').html(str); }); $('#list').on('click', '.youtube-dl_stop', function () { let index = $(this).data('index'); $.ajax({ - url: '/' + package_name + '/ajax/stop', + url: `/${package_name}/ajax/stop`, type: 'POST', cache: false, data: { index: index }, - dataType: 'json', - success: function () { - location.reload(); // 새로고침 - } + dataType: 'json' + }).done(function () { + location.reload(); }); return false; }); @@ -158,8 +156,8 @@ } function status_html(data) { - $('#item_' + data.index).html(get_item(data)); - $('#detail_' + data.index).html(get_detail(data)); + $(`#item_${data.index}`).html(get_item(data)); + $(`#detail_${data.index}`).html(get_detail(data)); } diff --git a/templates/youtube-dl_setting.html b/templates/youtube-dl_setting.html index b1b744e..ad7974f 100644 --- a/templates/youtube-dl_setting.html +++ b/templates/youtube-dl_setting.html @@ -4,10 +4,11 @@
{{ macros.setting_input_text('youtube_dl_version', 'youtube-dl 버전', value=arg['youtube_dl_version']) }}
- {{ macros.setting_input_text('temp_path', '임시 폴더', value=arg['temp_path'], placeholder='임시 폴더 경로', desc='다운로드 파일이 임시로 저장될 폴더 입니다.') }} - {{ macros.setting_input_text('save_path', '저장 폴더', value=arg['save_path'], placeholder='저장 폴더 경로', desc='정상적으로 완료된 파일이 이동할 폴더 입니다.') }} - {{ macros.setting_input_text('default_filename', '기본 파일명', value=arg['default_filename'], placeholder='저장 폴더 경로', desc=['템플릿 규칙은 https://github.com/ytdl-org/youtube-dl/blob/master/README.md#output-template 참고', '기본값은 "%(title)s-%(id)s.%(ext)s"입니다.']) }} - {{ macros.setting_input_text('proxy', '프록시', value=arg['proxy'], placeholder='프록시 주소', desc=['HTTP/HTTPS/SOCKS를 지원합니다. 예) socks5://127.0.0.1:1080/', '빈칸으로 두면 프록시를 사용하지 않습니다.']) }} + {{ macros.setting_input_text_and_buttons('ffmpeg_path', 'FFmpeg 경로', [['ffmpeg_version', '버전확인']], value=arg['ffmpeg_path'], placeholder='ffmpeg', desc='SJVA에 내장된 버전 말고 원하는 버전을 사용할 수 있습니다.') }} + {{ macros.setting_input_text('temp_path', '임시 폴더', value=arg['temp_path'], desc='다운로드 파일이 임시로 저장될 폴더입니다.') }} + {{ macros.setting_input_text('save_path', '저장 폴더', value=arg['save_path'], desc='정상적으로 완료된 파일이 이동할 폴더입니다.') }} + {{ macros.setting_input_text('default_filename', '기본 파일명', value=arg['default_filename'], desc=['템플릿 규칙은 https://github.com/ytdl-org/youtube-dl/blob/master/README.md#output-template 참고', '기본값은 "%(title)s-%(id)s.%(ext)s"입니다.']) }} + {{ macros.setting_input_text('proxy', '프록시', value=arg['proxy'], desc=['HTTP/HTTPS/SOCKS를 지원합니다. 예) socks5://127.0.0.1:1080/', '빈칸으로 두면 프록시를 사용하지 않습니다.']) }} {{ macros.setting_checkbox('activate_cors', 'CORS 허용', value=arg['activate_cors'], desc='API로의 크로스 도메인 요청을 허용합니다. 설정 저장 후 재시작이 필요합니다.') }} {{ macros.setting_button([['global_setting_save_btn', '저장']]) }}
@@ -16,6 +17,33 @@ {% endblock %}