From b26f25a41379aeb9d626c9f7a31c69e15e9d72c5 Mon Sep 17 00:00:00 2001 From: joyfuI Date: Thu, 6 Feb 2020 23:43:13 +0900 Subject: [PATCH] =?UTF-8?q?v0.1.1=20=EC=9C=88=EB=8F=84=EC=9A=B0=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=20=EC=A7=80=EC=9B=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 윈도우 환경 지원 추가 다운로드 실패 시 임시파일 삭제가 안 되는 문제 수정 --- README.md | 4 ++++ logic.py | 22 +++++++++++++++++++--- model.py | 2 +- plugin.py | 27 +++++++++++---------------- youtube_dl.py | 21 ++++++++++++++------- 5 files changed, 49 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 0d25642..741f8d3 100644 --- a/README.md +++ b/README.md @@ -9,5 +9,9 @@ SJVA에서 유튜브 등 동영상 사이트 영상을 다운로드할 수 있 일단 어느 정도 코드가 정리되면 그때 화질 선택 등 옵션을 추가할 예정 ## Changelog +v0.1.1 +* 윈도우 환경 지원 추가 +* 다운로드 실패 시 임시파일 삭제가 안 되는 문제 수정 + v0.1.0 * 최초 공개 diff --git a/logic.py b/logic.py index 021adf0..87bcd45 100644 --- a/logic.py +++ b/logic.py @@ -3,11 +3,13 @@ # python import os import traceback +import platform +import subprocess # third-party # sjva 공용 -from framework import db, path_data +from framework import db, path_app_root, path_data from framework.util import Util # 패키지 @@ -37,8 +39,11 @@ class Logic(object): def plugin_load(): try: logger.debug('%s plugin_load', package_name) - # DB 초기화 - Logic.db_init() + Logic.db_init() # DB 초기화 + if platform.system() == 'Windows': # 윈도우일 때 + Logic.youtube_dl_path = os.path.join(path_app_root, 'bin', 'Windows', 'youtube-dl.exe') + if not os.path.isfile(Logic.youtube_dl_path): # youtube-dl.exe가 없으면 + Logic.youtube_dl_update() # 편의를 위해 json 파일 생성 from plugin import plugin_info @@ -78,3 +83,14 @@ class Logic(object): logger.error(traceback.format_exc()) ######################################################### + + youtube_dl_path = 'youtube-dl' + youtube_dl_list = [] + + @staticmethod + def youtube_dl_update(): + if platform.system() == 'Windows': # 윈도우일 때 + subprocess.call(['powershell', "(new-Object System.Net.WebClient).DownloadFile('https://yt-dl.org/latest/youtube-dl.exe', '%s')" % os.path.join(path_app_root, 'bin', 'Windows', 'youtube-dl.exe')]) + else: # 나머지 Unix-like + subprocess.call(['curl', '-L', 'https://yt-dl.org/downloads/latest/youtube-dl', '-o', '/usr/local/bin/youtube-dl']) + subprocess.call(['chmod', 'a+rx', '/usr/local/bin/youtube-dl']) diff --git a/model.py b/model.py index 13749a1..542c18a 100644 --- a/model.py +++ b/model.py @@ -12,7 +12,7 @@ from framework import db, app, path_app_root from .plugin import package_name db_file = os.path.join(path_app_root, 'data', 'db', '%s.db' % package_name) -app.config['SQLALCHEMY_BINDS'][package_name] = 'sqlite:///%s' % (db_file) +app.config['SQLALCHEMY_BINDS'][package_name] = 'sqlite:///%s' % db_file class ModelSetting(db.Model): __tablename__ = 'plugin_%s_setting' % package_name diff --git a/plugin.py b/plugin.py index 8ca79be..f9d127c 100644 --- a/plugin.py +++ b/plugin.py @@ -35,12 +35,12 @@ def plugin_unload(): Logic.plugin_unload() plugin_info = { - 'version': '0.1.0', + 'version': '0.1.1', 'name': 'youtube-dl', 'category_name': 'vod', 'icon': '', 'developer': 'joyfuI', - 'description': 'youtube-dl', + 'description': '유튜브, 네이버TV 등 동영상 사이트에서 동영상 다운로드', 'home': 'https://github.com/joyfuI/youtube-dl', 'more': '' } @@ -54,10 +54,6 @@ menu = { 'category': 'vod' } -######################################################### - -youtube_dl_list = [] - ######################################################### # WEB Menu ######################################################### @@ -73,19 +69,19 @@ def detail(sub): setting_list = db.session.query(ModelSetting).all() arg = Util.db_list_to_dict(setting_list) arg['package_name'] = package_name - arg['youtube_dl_path'] = 'youtube-dl' - return render_template('%s_setting.html' % (package_name), arg=arg) + arg['youtube_dl_path'] = Logic.youtube_dl_path + return render_template('%s_setting.html' % package_name, arg=arg) elif sub == 'download': arg = { } arg['package_name'] = package_name arg['file_name'] = '%(title)s-%(id)s.%(ext)s' - return render_template('%s_download.html' % (package_name), arg=arg) + return render_template('%s_download.html' % package_name, arg=arg) elif sub == 'list': arg = { } arg['package_name'] = package_name - return render_template('%s_list.html' % (package_name), arg=arg) + return render_template('%s_list.html' % package_name, arg=arg) elif sub == 'log': return render_template('log.html', package=package_name) @@ -106,12 +102,11 @@ def ajax(sub): return jsonify(ret) elif sub == 'youtube_dl_version': - ret = subprocess.check_output(['youtube-dl', '--version']) + ret = subprocess.check_output([Logic.youtube_dl_path, '--version']) return jsonify(ret) elif sub == 'youtube_dl_update': - subprocess.call(['curl', '-L', 'https://yt-dl.org/downloads/latest/youtube-dl', '-o', '/usr/local/bin/youtube-dl']) - subprocess.call(['chmod', 'a+rx', '/usr/local/bin/youtube-dl']) + Logic.youtube_dl_update() return jsonify([]) elif sub == 'download': @@ -120,13 +115,13 @@ def ajax(sub): temp_path = Logic.get_setting_value('temp_path') save_path = Logic.get_setting_value('save_path') youtube_dl = Youtube_dl(url, filename, temp_path, save_path) - youtube_dl_list.append(youtube_dl) # 리스트 추가 + Logic.youtube_dl_list.append(youtube_dl) # 리스트 추가 youtube_dl.start() return jsonify([]) elif sub == 'list': ret = [] - for i in youtube_dl_list: + for i in Logic.youtube_dl_list: data = { } data['url'] = i.url data['filename'] = i.filename @@ -155,7 +150,7 @@ def ajax(sub): elif sub == 'stop': index = int(request.form['index']) - youtube_dl_list[index].stop() + Logic.youtube_dl_list[index].stop() return jsonify([]) except Exception as e: logger.error('Exception:%s', e) diff --git a/youtube_dl.py b/youtube_dl.py index 4c75ea8..114c374 100644 --- a/youtube_dl.py +++ b/youtube_dl.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # python import os +import platform from threading import Thread import subprocess import json @@ -9,6 +10,7 @@ from enum import Enum # 패키지 from .plugin import logger +from .logic import Logic class Status(Enum): READY = 0 @@ -53,28 +55,33 @@ class Youtube_dl(object): def run(self): command = [ - 'youtube-dl', + Logic.youtube_dl_path, '--print-json', - '-o', self.temp_path + '/' + self.filename, - '--exec', 'mv {} ' + self.save_path + '/', + '-o', os.path.join(self.temp_path, self.filename), + '--exec', 'move /y {} ' + self.save_path + '\\' if platform.system() == 'Windows' else 'mv -f {} ' + self.save_path + '/', self.url ] + logger.debug(command) self._process = subprocess.Popen(command, stdout=subprocess.PIPE, universal_newlines=True) # youtube-dl 실행 data = json.loads(self._process.stdout.readline()) # 파일 정보 - self.filename = data['_filename'].split('/')[-1] + self.filename = os.path.basename(data['_filename']) self.duration = data['duration'] self.format = data['format'] self.status = Status.START self.errorlevel = self._process.wait() # 실행 결과 + logger.debug('returncode %d', self.errorlevel) self.end_time = datetime.now() if self.errorlevel == 0: # 다운로드 성공 self.status = Status.SUCCESS else: # 다운로드 실패 - logger.debug('returncode %d', self.errorlevel) if self.status != Status.STOP: self.status = Status.FAILURE - logger.debug('rm -f ' + self.temp_path + '/' + ''.join(str.split('.')[:-1]) + '*') - os.system('rm -f ' + self.temp_path + '/' + ''.join(str.split('.')[:-1]) + '*') # 임시 파일 삭제 + if platform.system() == 'Windows': # 윈도우일 때 + logger.debug('del /q "' + self.temp_path + '\\' + ''.join(self.filename.split('.')[:-1]) + '"*') + os.system('del /q "' + self.temp_path + '\\' + ''.join(self.filename.split('.')[:-1]) + '"*') # 임시파일 삭제 + else: + logger.debug('rm -f "' + self.temp_path + '/' + ''.join(self.filename.split('.')[:-1]) + '"*') + os.system('rm -f "' + self.temp_path + '/' + ''.join(self.filename.split('.')[:-1]) + '"*') # 임시파일 삭제 def stop(self): self.status = Status.STOP