2018-11-29 20:08:15 +00:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Name : Video2X Setup Script
Author : K4YT3X
2019-06-15 01:11:31 +00:00
Author : BrianPetkovsek
2018-11-29 20:08:15 +00:00
Date Created : November 28 , 2018
2019-07-30 05:28:29 +00:00
Last Modified : July 30 , 2019
2019-06-25 23:25:27 +00:00
Dev : SAT3LL
2018-11-29 20:08:15 +00:00
Licensed under the GNU General Public License Version 3 ( GNU GPL v3 ) ,
available at : https : / / www . gnu . org / licenses / gpl - 3.0 . txt
2019-02-08 19:03:46 +00:00
( C ) 2018 - 2019 K4YT3X
2018-11-29 20:08:15 +00:00
Description : This script helps installing all dependencies of video2x
and generates a configuration for it .
Installation Details :
- ffmpeg : % LOCALAPPDATA % \\video2x \\ffmpeg
- waifu2x - caffe : % LOCALAPPDATA % \\video2x \\waifu2x - caffe
2019-06-25 23:25:27 +00:00
- waifu2x - cpp - converter : % LOCALAPPDATA % \\video2x \\waifu2x - converter - cpp
2019-06-25 23:50:29 +00:00
- waifu2x_ncnn_vulkan : % LOCALAPPDATA % \\video2x \\waifu2x - ncnn - vulkan
2018-11-29 20:08:15 +00:00
"""
2019-07-27 17:39:40 +00:00
# built-in imports
2019-03-26 20:18:37 +00:00
import argparse
2018-11-29 20:08:15 +00:00
import json
import os
2019-07-27 21:29:33 +00:00
import pathlib
import re
2019-06-26 03:35:42 +00:00
import shutil
2018-11-29 20:08:15 +00:00
import subprocess
2019-03-31 07:46:15 +00:00
import sys
2018-11-29 20:08:15 +00:00
import tempfile
import traceback
2019-07-27 21:29:33 +00:00
import urllib
2018-11-29 20:08:15 +00:00
import zipfile
# Requests doesn't come with windows, therefore
# it will be installed as a dependency and imported
# later in the script.
# import requests
2019-07-30 05:28:29 +00:00
VERSION = ' 1.4.0 '
2019-03-26 20:18:37 +00:00
2019-07-27 21:29:33 +00:00
# global static variables
LOCALAPPDATA = pathlib . Path ( os . getenv ( ' localappdata ' ) )
2019-03-26 20:18:37 +00:00
def process_arguments ( ) :
""" Processes CLI arguments
"""
parser = argparse . ArgumentParser ( formatter_class = argparse . ArgumentDefaultsHelpFormatter )
# video options
general_options = parser . add_argument_group ( ' General Options ' )
2019-06-25 23:50:29 +00:00
general_options . add_argument ( ' -d ' , ' --driver ' , help = ' driver to download and configure ' , action = ' store ' , choices = [ ' all ' , ' waifu2x_caffe ' , ' waifu2x_converter ' , ' waifu2x_ncnn_vulkan ' ] , default = ' all ' )
2019-03-26 20:18:37 +00:00
# parse arguments
return parser . parse_args ( )
2018-11-29 20:08:15 +00:00
class Video2xSetup :
""" Install dependencies for video2x video enlarger
This library is meant to be executed as a stand - alone
script . All files will be installed under % LOCALAPPDATA % \\video2x .
"""
2019-03-31 07:46:15 +00:00
def __init__ ( self , driver , download_python_modules ) :
2019-03-26 20:18:37 +00:00
self . driver = driver
2019-03-31 07:46:15 +00:00
self . download_python_modules = download_python_modules
2018-11-29 20:08:15 +00:00
self . trash = [ ]
def run ( self ) :
2019-03-31 07:46:15 +00:00
if self . download_python_modules :
print ( ' \n Installing Python libraries ' )
self . _install_python_requirements ( )
2018-11-29 20:08:15 +00:00
print ( ' \n Installing FFMPEG ' )
self . _install_ffmpeg ( )
2019-03-26 20:18:37 +00:00
if self . driver == ' all ' :
self . _install_waifu2x_caffe ( )
self . _install_waifu2x_converter_cpp ( )
2019-06-25 23:25:27 +00:00
self . _install_waifu2x_ncnn_vulkan ( )
2019-03-26 20:18:37 +00:00
elif self . driver == ' waifu2x_caffe ' :
self . _install_waifu2x_caffe ( )
elif self . driver == ' waifu2x_converter ' :
self . _install_waifu2x_converter_cpp ( )
2019-06-25 23:50:29 +00:00
elif self . driver == ' waifu2x_ncnn_vulkan ' :
2019-06-25 23:25:27 +00:00
self . _install_waifu2x_ncnn_vulkan ( )
2018-11-29 20:08:15 +00:00
print ( ' \n Generating Video2X configuration file ' )
self . _generate_config ( )
print ( ' \n Cleaning up temporary files ' )
self . _cleanup ( )
def _install_python_requirements ( self ) :
""" Read requirements.txt and return its content
"""
2019-06-15 01:11:31 +00:00
pip_install ( ' requirements.txt ' )
2018-11-29 20:08:15 +00:00
def _cleanup ( self ) :
""" Cleanup all the temp files downloaded
"""
for file in self . trash :
try :
2019-07-27 21:29:33 +00:00
if file . is_dir ( ) :
print ( f ' Deleting directory: { file } ' )
2019-06-26 03:35:42 +00:00
shutil . rmtree ( file )
2019-07-27 21:29:33 +00:00
else :
print ( f ' Deleting file: { file } ' )
file . unlink ( )
except Exception :
print ( f ' Error deleting: { file } ' )
traceback . print_exc ( )
2018-11-29 20:08:15 +00:00
def _install_ffmpeg ( self ) :
""" Install FFMPEG
"""
2019-03-26 20:18:37 +00:00
latest_release = ' https://ffmpeg.zeranoe.com/builds/win64/static/ffmpeg-latest-win64-static.zip '
2018-11-29 20:08:15 +00:00
ffmpeg_zip = download ( latest_release , tempfile . gettempdir ( ) )
self . trash . append ( ffmpeg_zip )
with zipfile . ZipFile ( ffmpeg_zip ) as zipf :
2019-07-27 21:29:33 +00:00
zipf . extractall ( LOCALAPPDATA / ' video2x ' )
2018-11-29 20:08:15 +00:00
def _install_waifu2x_caffe ( self ) :
""" Install waifu2x_caffe
"""
2019-03-26 20:18:37 +00:00
print ( ' \n Installing waifu2x-caffe ' )
2018-11-29 20:08:15 +00:00
import requests
# Get latest release of waifu2x-caffe via GitHub API
2019-06-15 01:37:38 +00:00
latest_release = json . loads ( requests . get ( ' https://api.github.com/repos/lltcggie/waifu2x-caffe/releases/latest ' ) . content . decode ( ' utf-8 ' ) )
2018-11-29 20:08:15 +00:00
for a in latest_release [ ' assets ' ] :
if ' waifu2x-caffe.zip ' in a [ ' browser_download_url ' ] :
waifu2x_caffe_zip = download ( a [ ' browser_download_url ' ] , tempfile . gettempdir ( ) )
self . trash . append ( waifu2x_caffe_zip )
with zipfile . ZipFile ( waifu2x_caffe_zip ) as zipf :
2019-07-27 21:29:33 +00:00
zipf . extractall ( LOCALAPPDATA / ' video2x ' )
2018-11-29 20:08:15 +00:00
2019-03-26 20:18:37 +00:00
def _install_waifu2x_converter_cpp ( self ) :
""" Install waifu2x_caffe
"""
print ( ' \n Installing waifu2x-converter-cpp ' )
import requests
# Get latest release of waifu2x-caffe via GitHub API
2019-06-15 01:37:38 +00:00
latest_release = json . loads ( requests . get ( ' https://api.github.com/repos/DeadSix27/waifu2x-converter-cpp/releases/latest ' ) . content . decode ( ' utf-8 ' ) )
2019-03-26 20:18:37 +00:00
for a in latest_release [ ' assets ' ] :
if re . search ( r ' waifu2x-DeadSix27-win64_v[0-9]* \ .zip ' , a [ ' browser_download_url ' ] ) :
waifu2x_converter_cpp_zip = download ( a [ ' browser_download_url ' ] , tempfile . gettempdir ( ) )
self . trash . append ( waifu2x_converter_cpp_zip )
with zipfile . ZipFile ( waifu2x_converter_cpp_zip ) as zipf :
2019-07-27 21:29:33 +00:00
zipf . extractall ( LOCALAPPDATA / ' video2x ' / ' waifu2x-converter-cpp ' )
2019-03-26 20:18:37 +00:00
2019-06-25 23:25:27 +00:00
def _install_waifu2x_ncnn_vulkan ( self ) :
""" Install waifu2x-ncnn-vulkan
"""
print ( ' \n Installing waifu2x-ncnn-vulkan ' )
import requests
# Get latest release of waifu2x-ncnn-vulkan via Github API
latest_release = json . loads ( requests . get ( ' https://api.github.com/repos/nihui/waifu2x-ncnn-vulkan/releases/latest ' ) . content . decode ( ' utf-8 ' ) )
for a in latest_release [ ' assets ' ] :
if re . search ( r ' waifu2x-ncnn-vulkan- \ d* \ .zip ' , a [ ' browser_download_url ' ] ) :
waifu2x_ncnn_vulkan_zip = download ( a [ ' browser_download_url ' ] , tempfile . gettempdir ( ) )
self . trash . append ( waifu2x_ncnn_vulkan_zip )
2019-07-30 05:28:29 +00:00
# extract and rename
waifu2x_ncnn_vulkan_directory = LOCALAPPDATA / ' video2x ' / ' waifu2x-ncnn-vulkan '
2019-06-25 23:25:27 +00:00
with zipfile . ZipFile ( waifu2x_ncnn_vulkan_zip ) as zipf :
2019-07-30 05:28:29 +00:00
zipf . extractall ( LOCALAPPDATA / ' video2x ' )
# if directory already exists, remove it
if waifu2x_ncnn_vulkan_directory . exists ( ) :
shutil . rmtree ( waifu2x_ncnn_vulkan_directory )
# rename the newly extracted directory
( LOCALAPPDATA / ' video2x ' / zipf . namelist ( ) [ 0 ] ) . rename ( waifu2x_ncnn_vulkan_directory )
2019-06-25 23:25:27 +00:00
2018-11-29 20:08:15 +00:00
def _generate_config ( self ) :
""" Generate video2x config
"""
2019-03-09 17:51:06 +00:00
# Open current video2x.json file as template
with open ( ' video2x.json ' , ' r ' ) as template :
template_dict = json . load ( template )
template . close ( )
2019-03-26 20:18:37 +00:00
# configure only the specified drivers
if self . driver == ' all ' :
2019-07-30 05:28:29 +00:00
template_dict [ ' waifu2x_caffe ' ] [ ' waifu2x_caffe_path ' ] = str ( LOCALAPPDATA / ' video2x ' / ' waifu2x-caffe ' / ' waifu2x-caffe-cui.exe ' )
template_dict [ ' waifu2x_converter ' ] [ ' waifu2x_converter_path ' ] = str ( LOCALAPPDATA / ' video2x ' / ' waifu2x-converter-cpp ' )
template_dict [ ' waifu2x_ncnn_vulkan ' ] [ ' waifu2x_ncnn_vulkan_path ' ] = str ( LOCALAPPDATA / ' video2x ' / ' waifu2x-ncnn-vulkan ' / ' waifu2x-ncnn-vulkan.exe ' )
2019-03-26 20:18:37 +00:00
elif self . driver == ' waifu2x_caffe ' :
2019-07-30 05:28:29 +00:00
template_dict [ ' waifu2x_caffe ' ] [ ' waifu2x_caffe_path ' ] = str ( LOCALAPPDATA / ' video2x ' / ' waifu2x-caffe ' / ' waifu2x-caffe-cui.exe ' )
2019-03-26 20:18:37 +00:00
elif self . driver == ' waifu2x_converter ' :
2019-07-30 05:28:29 +00:00
template_dict [ ' waifu2x_converter ' ] [ ' waifu2x_converter_path ' ] = str ( LOCALAPPDATA / ' video2x ' / ' waifu2x-converter-cpp ' )
2019-06-25 23:50:29 +00:00
elif self . driver == ' waifu2x_ncnn_vulkan ' :
2019-07-30 05:28:29 +00:00
template_dict [ ' waifu2x_ncnn_vulkan ' ] [ ' waifu2x_ncnn_vulkan_path ' ] = str ( LOCALAPPDATA / ' video2x ' / ' waifu2x-ncnn-vulkan ' / ' waifu2x-ncnn-vulkan.exe ' )
2019-03-26 20:18:37 +00:00
2019-07-30 05:28:29 +00:00
template_dict [ ' ffmpeg ' ] [ ' ffmpeg_path ' ] = str ( LOCALAPPDATA / ' video2x ' / ' ffmpeg-latest-win64-static ' / ' bin ' )
2019-04-29 04:06:54 +00:00
template_dict [ ' video2x ' ] [ ' video2x_cache_directory ' ] = None
2019-03-09 17:51:06 +00:00
template_dict [ ' video2x ' ] [ ' preserve_frames ' ] = False
# Write configuration into file
2018-11-29 20:08:15 +00:00
with open ( ' video2x.json ' , ' w ' ) as config :
2019-03-31 07:46:15 +00:00
json . dump ( template_dict , config , indent = 4 )
2018-11-29 20:08:15 +00:00
config . close ( )
def download ( url , save_path , chunk_size = 4096 ) :
""" Download file to local with requests library
"""
2019-03-26 20:18:37 +00:00
from tqdm import tqdm
2018-11-29 20:08:15 +00:00
import requests
2019-07-27 21:29:33 +00:00
save_path = pathlib . Path ( save_path )
# create target folder if it doesn't exist
save_path . mkdir ( parents = True , exist_ok = True )
# create requests stream for steaming file
stream = requests . get ( url , stream = True , allow_redirects = True )
# get file name
file_name = None
if ' content-disposition ' in stream . headers :
disposition = stream . headers [ ' content-disposition ' ]
try :
file_name = re . findall ( " filename=(.+) " , disposition ) [ 0 ] . strip ( ' " ' )
except IndexError :
pass
if file_name is None :
# output_file = f'{save_path}\\{stream.url.split("/")[-1]}'
output_file = save_path / stream . url . split ( ' / ' ) [ - 1 ]
else :
output_file = save_path / file_name
# decode url encoding
output_file = pathlib . Path ( urllib . parse . unquote ( str ( output_file ) ) )
# get total size for progress bar if provided in headers
total_size = 0
if ' content-length ' in stream . headers :
total_size = int ( stream . headers [ ' content-length ' ] )
# print download information summary
2019-07-27 17:39:40 +00:00
print ( f ' Downloading: { url } ' )
2019-07-27 21:29:33 +00:00
print ( f ' Total size: { total_size } ' )
2019-07-27 17:39:40 +00:00
print ( f ' Chunk size: { chunk_size } ' )
print ( f ' Saving to: { output_file } ' )
2018-11-29 20:08:15 +00:00
# Write content into file
with open ( output_file , ' wb ' ) as output :
2019-03-26 20:18:37 +00:00
with tqdm ( total = total_size , ascii = True ) as progress_bar :
for chunk in stream . iter_content ( chunk_size = chunk_size ) :
if chunk :
output . write ( chunk )
progress_bar . update ( len ( chunk ) )
2018-11-29 20:08:15 +00:00
2019-07-27 21:29:33 +00:00
# return the full path of saved file
2018-11-29 20:08:15 +00:00
return output_file
2019-06-15 01:11:31 +00:00
def pip_install ( file ) :
2018-11-29 20:08:15 +00:00
""" Install python package via python pip module
2019-06-18 02:34:45 +00:00
2018-11-29 20:08:15 +00:00
pip . main ( ) is not available after pip 9.0 .1 , thus
pip module is not used in this case .
"""
2019-06-15 01:11:31 +00:00
return subprocess . run ( [ sys . executable , ' -m ' , ' pip ' , ' install ' , ' -U ' , ' -r ' , file ] ) . returncode
2018-11-29 20:08:15 +00:00
2019-06-15 18:35:22 +00:00
if __name__ == ' __main__ ' :
2018-11-29 20:08:15 +00:00
try :
2019-03-26 20:18:37 +00:00
args = process_arguments ( )
2019-03-31 07:46:15 +00:00
print ( ' Video2X Setup Script ' )
2019-07-27 17:39:40 +00:00
print ( f ' Version: { VERSION } ' )
2019-03-31 07:46:15 +00:00
# do not install pip modules if script
# is packaged in exe format
download_python_modules = True
if sys . argv [ 0 ] . endswith ( ' .exe ' ) :
print ( ' \n Script is packaged as exe, skipping pip module download ' )
download_python_modules = False
setup = Video2xSetup ( args . driver , download_python_modules )
2018-11-29 20:08:15 +00:00
setup . run ( )
2019-03-31 07:46:15 +00:00
print ( ' \n Script finished successfully ' )
2018-11-29 20:08:15 +00:00
except Exception :
2019-07-30 05:28:29 +00:00
2018-11-29 20:08:15 +00:00
traceback . print_exc ( )
print ( ' An error has occurred ' )
print ( ' Video2X Automatic Setup has failed ' )
2019-07-30 05:28:29 +00:00
# in case of a failure, try cleaning up temp files
try :
setup . _cleanup ( )
except Exception :
traceback . print_exc ( )
print ( ' An error occurred while trying to cleanup files ' )
2018-11-29 20:08:15 +00:00
exit ( 1 )