From b7d95018022710f58b0343d5d581e43fd2533c29 Mon Sep 17 00:00:00 2001 From: joyfuI Date: Tue, 20 Oct 2020 21:24:37 +0900 Subject: [PATCH 1/3] =?UTF-8?q?.gitignore=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 90588b7..cef476c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea/ -venv/ -*.pyo \ No newline at end of file +.venv/ +*.pyo +test/ From 7bec0524e6cb613e1e02750761d59bf838f3f2ec Mon Sep 17 00:00:00 2001 From: joyfuI Date: Sun, 8 Nov 2020 16:06:34 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=ED=8C=8C=EC=9D=B4=EC=8D=AC3=20=ED=98=B8?= =?UTF-8?q?=ED=99=98=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + __init__.py | 2 +- logic.py | 2 +- plugin.py | 3 ++- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index cef476c..6d0abba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .idea/ .venv/ *.pyo +__pycache__/ test/ diff --git a/__init__.py b/__init__.py index f7cd4a1..dd87e12 100644 --- a/__init__.py +++ b/__init__.py @@ -1,2 +1,2 @@ # -*- coding: utf-8 -*- -from plugin import blueprint, menu, plugin_load, plugin_unload, plugin_info +from .plugin import blueprint, menu, plugin_load, plugin_unload, plugin_info diff --git a/logic.py b/logic.py index 2f760b7..866f2e3 100644 --- a/logic.py +++ b/logic.py @@ -59,7 +59,7 @@ class Logic(object): logger.debug(subprocess.check_output([sys.executable, '-m', 'pip', 'install', '--upgrade', 'youtube-dl'], universal_newlines=True)) # 편의를 위해 json 파일 생성 - from plugin import plugin_info + from .plugin import plugin_info Util.save_from_dict_to_json(plugin_info, os.path.join(os.path.dirname(__file__), 'info.json')) except Exception as e: logger.error('Exception:%s', e) diff --git a/plugin.py b/plugin.py index 714c5a9..97b8f81 100644 --- a/plugin.py +++ b/plugin.py @@ -112,7 +112,8 @@ def ajax(sub): # UI 요청 elif sub == 'ffmpeg_version': path = request.form['path'] - ret = subprocess.check_output([path, '-version']).replace('\n', '
') + ret = subprocess.check_output([path, '-version']) + ret = ret.decode().replace('\n', '
') return jsonify(ret) elif sub == 'download': From 5e0aaa0d9245503ba1212faee3efb454e47e9420 Mon Sep 17 00:00:00 2001 From: joyfuI Date: Sun, 8 Nov 2020 22:58:35 +0900 Subject: [PATCH 3/3] =?UTF-8?q?download=20API=EC=97=90=20dateafter=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 +++++++ info.json | 2 +- logic_normal.py | 72 ++++++++++++++++++++++++++---------------------- my_youtube_dl.py | 14 ++++++++-- plugin.py | 6 +++- 5 files changed, 66 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 93af164..4b3090a 100644 --- a/README.md +++ b/README.md @@ -73,8 +73,12 @@ API에선 직접 비트레이트를 설정할 수 있습니다. `preferedformat` | 변환할 비디오 포맷. 가능한 포맷은 https://ffmpeg.org/general.html#File-Formats 참고. 미지정 시 변환하지 않음 | X | String `preferredcodec` | 추출할 오디오 코덱. 가능한 값은 `"best"`, `"mp3"`, `"aac"`, `"flac"`, `"m4a"`, `"opus"`, `"vorbis"`, `"wav"`. 미지정 시 추출하지 않음 | X | String `preferredquality` | 추출한 오디오의 비트레이트. 0 ~ 9 사이의 VBR 퀄리티 값(0에 가까울수록 좋음) 혹은 특정 비트레이트 값. `preferredcodec` 키가 있을 때만 유효. 기본값: `192` | X | Integer +`dateafter` | 지정한 날짜 이후에 업로드된 동영상만 다운로드. 미지정 시 모든 동영상 다운로드 | X | String `archive` | 다운로드한 동영상의 ID를 기록할 파일 경로. 파일이 이미 있을 경우 이미 다운로드한 동영상은 다운로드 하지 않음. 미지정 시 기록하지 않음 | X | String `start` | 다운로드 준비 후 바로 다운로드를 시작할지 여부. 기본값: `false` | X | Boolean + +`dateafter` 키에 넣을 수 있는 날짜는 `YYYYMMDD` 또는 `(now|today)[+-][0-9](day|week|month|year)(s)?` 형식의 문자열입니다. + #### Response 키 | 설명 | 타입 --- | --- | --- @@ -131,6 +135,12 @@ API에선 직접 비트레이트를 설정할 수 있습니다. 물론 해당 정보가 없으면 null입니다. ## Changelog +v1.7.0 +* Python 3 지원 + Python 2를 유지한 채로 Python 3 지원을 추가했습니다. +* download API에 dateafter 추가 + 지정한 날짜 이후에 업로드된 동영상만 다운로드하는 옵션입니다. 플레이리스트 다운로드 시에 유용하게 사용할 수 있습니다. + v1.6.11 * 목록 메뉴에 전체 중지 버튼 추가 diff --git a/info.json b/info.json index fd7d7e8..e1b6d80 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.11", "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.7.0", "home": "https://github.com/joyfuI/youtube-dl", "category_name": "vod", "developer": "joyfuI"} \ No newline at end of file diff --git a/logic_normal.py b/logic_normal.py index e70b8d1..b73a03b 100644 --- a/logic_normal.py +++ b/logic_normal.py @@ -72,39 +72,45 @@ class LogicNormal(object): @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 + try: + 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'] + dateafter = kwagrs.get('dateafter') + youtube_dl = MyYoutubeDL(plugin, url, filename, temp_path, save_path, opts, dateafter) + youtube_dl.key = kwagrs.get('key') + LogicNormal.youtube_dl_list.append(youtube_dl) # 리스트 추가 + return youtube_dl + except Exception as e: + logger.error('Exception:%s', e) + logger.error(traceback.format_exc()) + return None @staticmethod def get_data(youtube_dl): diff --git a/my_youtube_dl.py b/my_youtube_dl.py index 1fe677f..985719d 100644 --- a/my_youtube_dl.py +++ b/my_youtube_dl.py @@ -45,7 +45,9 @@ class MyYoutubeDL(object): __index = 0 _last_msg = '' - def __init__(self, plugin, url, filename, temp_path, save_path=None, opts=None): + def __init__(self, plugin, url, filename, temp_path, save_path=None, opts=None, dateafter=None, datebefore=None): + from youtube_dl.utils import DateRange + if save_path is None: save_path = temp_path if opts is None: @@ -60,6 +62,8 @@ class MyYoutubeDL(object): os.makedirs(save_path) self.save_path = save_path self.opts = opts + if dateafter or datebefore: + self.opts['daterange'] = DateRange(start=dateafter, end=datebefore) self.index = MyYoutubeDL.__index MyYoutubeDL.__index += 1 self.__status = Status.READY @@ -97,6 +101,7 @@ class MyYoutubeDL(object): def run(self): import youtube_dl import glob2 + try: self.start_time = datetime.now() self.status = Status.START @@ -148,12 +153,14 @@ class MyYoutubeDL(object): @staticmethod def get_version(): - import youtube_dl - return youtube_dl.version.__version__ + from youtube_dl.version import __version__ + + return __version__ @staticmethod def get_info_dict(url, proxy=None): import youtube_dl + try: ydl_opts = { 'simulate': True, @@ -199,6 +206,7 @@ class MyYoutubeDL(object): @status.setter def status(self, value): from .plugin import socketio_emit + self.__status = value socketio_emit('status', self) diff --git a/plugin.py b/plugin.py index 97b8f81..5eb4c83 100644 --- a/plugin.py +++ b/plugin.py @@ -43,7 +43,7 @@ menu = { } plugin_info = { - 'version': '1.6.11', + 'version': '1.7.0', 'name': 'youtube-dl', 'category_name': 'vod', 'developer': 'joyfuI', @@ -202,6 +202,7 @@ def api(sub): preferedformat = request.values.get('preferedformat', None) preferredcodec = request.values.get('preferredcodec', None) preferredquality = request.values.get('preferredquality', 192) + dateafter = request.values.get('dateafter', None) archive = request.values.get('archive', None) start = request.values.get('start', False) ret = { @@ -225,10 +226,13 @@ def api(sub): preferedformat=preferedformat, preferredcodec=preferredcodec, preferredquality=preferredquality, + dateafter=dateafter, archive=archive, proxy=ModelSetting.get('proxy'), ffmpeg_path=ModelSetting.get('ffmpeg_path'), key=key) + if youtube_dl is None: + return LogicNormal.abort(ret, 10) # 실패 ret['index'] = youtube_dl.index if start: youtube_dl.start()