From e38df8f9fa4d715513453928591346f680dbe298 Mon Sep 17 00:00:00 2001 From: pukkandan Date: Fri, 29 Jan 2021 23:15:27 +0530 Subject: [PATCH] Refactor `update-version`, `pyinst.py` and related files * Refactor update-version * Moved pyinst, update-version and icon into devscripts * pyinst doesn't bump version anymore * Merge pyinst and pyinst32. Usage: `pyinst.py [32|64]` * Add mutagen as requirement * Remove make_win and related files --- .github/workflows/build.yml | 22 +++-- README.md | 16 +-- {win/icon => devscripts}/cloud.ico | Bin devscripts/pyinst.py | 69 +++++++++++++ ...-version-workflow.py => update-version.py} | 17 ++-- make_win.bat | 1 - pyinst.py | 92 ------------------ pyinst32.py | 92 ------------------ setup.py | 8 +- test/test_unicode_literals.py | 2 - win/ver.txt | 45 --------- youtube_dlc/postprocessor/embedthumbnail.py | 2 +- 12 files changed, 108 insertions(+), 258 deletions(-) rename {win/icon => devscripts}/cloud.ico (100%) create mode 100644 devscripts/pyinst.py rename devscripts/{update-version-workflow.py => update-version.py} (56%) delete mode 100644 make_win.bat delete mode 100644 pyinst.py delete mode 100644 pyinst32.py delete mode 100644 win/ver.txt diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ad175cf44..77544f9e9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,8 +25,8 @@ jobs: run: sudo apt-get -y install zip pandoc man - name: Bump version id: bump_version - run: python devscripts/update-version-workflow.py - - name: Check the version + run: python devscripts/update-version.py + - name: Print version run: echo "${{ steps.bump_version.outputs.ytdlc_version }}" - name: Run Make run: make @@ -84,11 +84,14 @@ jobs: with: python-version: '3.8' - name: Install Requirements - run: pip install pyinstaller + run: pip install pyinstaller mutagen - name: Bump version - run: python devscripts/update-version-workflow.py + id: bump_version + run: python devscripts/update-version.py + - name: Print version + run: echo "${{ steps.bump_version.outputs.ytdlc_version }}" - name: Run PyInstaller Script - run: python pyinst.py + run: python devscripts/pyinst.py 64 - name: Upload youtube-dlc.exe Windows binary id: upload-release-windows uses: actions/upload-release-asset@v1 @@ -119,11 +122,14 @@ jobs: python-version: '3.4.4' architecture: 'x86' - name: Install Requirements for 32 Bit - run: pip install pyinstaller==3.5 + run: pip install pyinstaller==3.5 mutagen - name: Bump version - run: python devscripts/update-version-workflow.py + id: bump_version + run: python devscripts/update-version.py + - name: Print version + run: echo "${{ steps.bump_version.outputs.ytdlc_version }}" - name: Run PyInstaller Script for 32 Bit - run: python pyinst32.py + run: python devscripts/pyinst.py 32 - name: Upload Executable youtube-dlc_x86.exe id: upload-release-windows32 uses: actions/upload-release-asset@v1 diff --git a/README.md b/README.md index d21093f22..24b5f6ea6 100644 --- a/README.md +++ b/README.md @@ -99,16 +99,15 @@ ### UPDATE ### COMPILE **For Windows**: -To build the Windows executable yourself (without version info!) +To build the Windows executable, you must have pyinstaller (and optionally mutagen for embedding thumbnail in opus/ogg files) + + python -m pip install --upgrade pyinstaller mutagen + +For the 64bit version, run `py devscripts\pyinst.py 64` using 64bit python3. Similarly, to install 32bit version, run `py devscripts\pyinst.py 32` using 32bit python (preferably 3) + +You can also build the executable without any version info or metadata by using: - python -m pip install --upgrade pyinstaller pyinstaller.exe youtube_dlc\__main__.py --onefile --name youtube-dlc - -Or simply execute the `make_win.bat` if pyinstaller is installed. -There will be a `youtube-dlc.exe` in `/dist` - -New way to build Windows is to use `python pyinst.py` (please use python3 64Bit) -For 32Bit Version use a 32Bit Version of python (3 preferred here as well) and run `python pyinst32.py` **For Unix**: You will need the required build tools @@ -117,6 +116,7 @@ ### COMPILE make +**Note**: In either platform, `devscripts\update-version.py` can be used to automatically update the version number # DESCRIPTION **youtube-dlc** is a command-line program to download videos from youtube.com many other [video platforms](docs/supportedsites.md). It requires the Python interpreter, version 2.6, 2.7, or 3.2+, and it is not platform specific. It should work on your Unix box, on Windows or on macOS. It is released to the public domain, which means you can modify it, redistribute it or use it however you like. diff --git a/win/icon/cloud.ico b/devscripts/cloud.ico similarity index 100% rename from win/icon/cloud.ico rename to devscripts/cloud.ico diff --git a/devscripts/pyinst.py b/devscripts/pyinst.py new file mode 100644 index 000000000..a7fb59af0 --- /dev/null +++ b/devscripts/pyinst.py @@ -0,0 +1,69 @@ +from __future__ import unicode_literals +import sys + +from PyInstaller.utils.win32.versioninfo import ( + VarStruct, VarFileInfo, StringStruct, StringTable, + StringFileInfo, FixedFileInfo, VSVersionInfo, SetVersion, +) +import PyInstaller.__main__ + + +assert len(sys.argv) > 1 and sys.argv[1] in ("32", "64") +_x86 = "_x86" if sys.argv[1] == "32" else "" + +FILE_DESCRIPTION = 'Media Downloader%s' % (" (32 Bit)" if _x86 else '') +SHORT_URLS = {"32": "git.io/JUGsM", "64": "git.io/JLh7K"} + + +exec(compile(open('youtube_dlc/version.py').read(), 'youtube_dlc/version.py', 'exec')) +VERSION = locals()['__version__'] + +VERSION_LIST = VERSION.replace('-', '.').split('.') +VERSION_LIST = list(map(int, VERSION_LIST)) + [0] * (4 - len(VERSION_LIST)) + +print('Version: %s%s' % (VERSION, _x86)) +print('Remember to update the version using devscipts\\update-version.py') + +VERSION_FILE = VSVersionInfo( + ffi=FixedFileInfo( + filevers=VERSION_LIST, + prodvers=VERSION_LIST, + mask=0x3F, + flags=0x0, + OS=0x4, + fileType=0x1, + subtype=0x0, + date=(0, 0), + ), + kids=[ + StringFileInfo([ + StringTable( + "040904B0", [ + StringStruct("Comments", "Youtube-dlc%s Command Line Interface." % _x86), + StringStruct("CompanyName", "pukkandan@gmail.com"), + StringStruct("FileDescription", FILE_DESCRIPTION), + StringStruct("FileVersion", VERSION), + StringStruct("InternalName", "youtube-dlc%s" % _x86), + StringStruct( + "LegalCopyright", + "pukkandan@gmail.com | UNLICENSE", + ), + StringStruct("OriginalFilename", "youtube-dlc%s.exe" % _x86), + StringStruct("ProductName", "Youtube-dlc%s" % _x86), + StringStruct("ProductVersion", "%s%s | %s" % (VERSION, _x86, SHORT_URLS[sys.argv[1]])), + ])]), + VarFileInfo([VarStruct("Translation", [0, 1200])]) + ] +) + +PyInstaller.__main__.run([ + '--name=youtube-dlc%s' % _x86, + '--onefile', + '--icon=devscripts/cloud.ico', + '--exclude-module=youtube_dl', + '--exclude-module=test', + '--exclude-module=ytdlp_plugins', + '--hidden-import=mutagen', + 'youtube_dlc/__main__.py', +]) +SetVersion('dist/youtube-dlc%s.exe' % _x86, VERSION_FILE) diff --git a/devscripts/update-version-workflow.py b/devscripts/update-version.py similarity index 56% rename from devscripts/update-version-workflow.py rename to devscripts/update-version.py index 4ac130a0d..c9698875a 100644 --- a/devscripts/update-version-workflow.py +++ b/devscripts/update-version.py @@ -3,26 +3,27 @@ # import urllib.request # response = urllib.request.urlopen('https://blackjack4494.github.io/youtube-dlc/update/LATEST_VERSION') -# _LATEST_VERSION = response.read().decode('utf-8') +# old_version = response.read().decode('utf-8') exec(compile(open('youtube_dlc/version.py').read(), 'youtube_dlc/version.py', 'exec')) -_LATEST_VERSION = locals()['__version__'] +old_version = locals()['__version__'] -_OLD_VERSION = _LATEST_VERSION.replace('-', '.').split(".", 4) +old_version_list = old_version.replace('-', '.').split(".", 4) -old_ver = '.'.join(_OLD_VERSION[:3]) -old_rev = _OLD_VERSION[3] if len(_OLD_VERSION) > 3 else '' +old_ver = '.'.join(old_version_list[:3]) +old_rev = old_version_list[3] if len(old_version_list) > 3 else '' ver = datetime.now().strftime("%Y.%m.%d") rev = str(int(old_rev or 0) + 1) if old_ver == ver else '' -version = '.'.join((ver, rev)) if rev else ver +VERSION = '.'.join((ver, rev)) if rev else ver +# VERSION_LIST = [(int(v) for v in ver.split(".") + [rev or 0])] -print('::set-output name=ytdlc_version::' + version) +print('::set-output name=ytdlc_version::' + VERSION) file_version_py = open('youtube_dlc/version.py', 'rt') data = file_version_py.read() -data = data.replace(_LATEST_VERSION, version) +data = data.replace(old_version, VERSION) file_version_py.close() file_version_py = open('youtube_dlc/version.py', 'wt') diff --git a/make_win.bat b/make_win.bat deleted file mode 100644 index a3d98155b..000000000 --- a/make_win.bat +++ /dev/null @@ -1 +0,0 @@ -py -m PyInstaller youtube_dlc\__main__.py --onefile --name youtube-dlc --version-file win\ver.txt --icon win\icon\cloud.ico --upx-exclude=vcruntime140.dll --exclude-module ytdlp_plugins \ No newline at end of file diff --git a/pyinst.py b/pyinst.py deleted file mode 100644 index 6e5faf5a9..000000000 --- a/pyinst.py +++ /dev/null @@ -1,92 +0,0 @@ -from __future__ import unicode_literals -from PyInstaller.utils.win32.versioninfo import ( - VarStruct, VarFileInfo, StringStruct, StringTable, - StringFileInfo, FixedFileInfo, VSVersionInfo, SetVersion, -) -import PyInstaller.__main__ - -from datetime import datetime - -FILE_DESCRIPTION = 'Media Downloader' - -exec(compile(open('youtube_dlc/version.py').read(), 'youtube_dlc/version.py', 'exec')) - -_LATEST_VERSION = locals()['__version__'] - -_OLD_VERSION = _LATEST_VERSION.rsplit("-", 1) - -if len(_OLD_VERSION) > 0: - old_ver = _OLD_VERSION[0] - -old_rev = '' -if len(_OLD_VERSION) > 1: - old_rev = _OLD_VERSION[1] - -now = datetime.now() -# ver = f'{datetime.today():%Y.%m.%d}' -ver = now.strftime("%Y.%m.%d") -rev = '' - -if old_ver == ver: - if old_rev: - rev = int(old_rev) + 1 - else: - rev = 1 - -_SEPARATOR = '-' - -version = _SEPARATOR.join(filter(None, [ver, str(rev)])) - -print(version) - -version_list = ver.split(".") -_year, _month, _day = [int(value) for value in version_list] -_rev = 0 -if rev: - _rev = rev -_ver_tuple = _year, _month, _day, _rev - -version_file = VSVersionInfo( - ffi=FixedFileInfo( - filevers=_ver_tuple, - prodvers=_ver_tuple, - mask=0x3F, - flags=0x0, - OS=0x4, - fileType=0x1, - subtype=0x0, - date=(0, 0), - ), - kids=[ - StringFileInfo( - [ - StringTable( - "040904B0", - [ - StringStruct("Comments", "Youtube-dlc Command Line Interface."), - StringStruct("CompanyName", "theidel@uni-bremen.de"), - StringStruct("FileDescription", FILE_DESCRIPTION), - StringStruct("FileVersion", version), - StringStruct("InternalName", "youtube-dlc"), - StringStruct( - "LegalCopyright", - "theidel@uni-bremen.de | UNLICENSE", - ), - StringStruct("OriginalFilename", "youtube-dlc.exe"), - StringStruct("ProductName", "Youtube-dlc"), - StringStruct("ProductVersion", version + " | git.io/JLh7K"), - ], - ) - ] - ), - VarFileInfo([VarStruct("Translation", [0, 1200])]) - ] -) - -PyInstaller.__main__.run([ - '--name=youtube-dlc', - '--onefile', - '--icon=win/icon/cloud.ico', - 'youtube_dlc/__main__.py', -]) -SetVersion('dist/youtube-dlc.exe', version_file) diff --git a/pyinst32.py b/pyinst32.py deleted file mode 100644 index ea20a69e5..000000000 --- a/pyinst32.py +++ /dev/null @@ -1,92 +0,0 @@ -from __future__ import unicode_literals -from PyInstaller.utils.win32.versioninfo import ( - VarStruct, VarFileInfo, StringStruct, StringTable, - StringFileInfo, FixedFileInfo, VSVersionInfo, SetVersion, -) -import PyInstaller.__main__ - -from datetime import datetime - -FILE_DESCRIPTION = 'Media Downloader 32 Bit Version' - -exec(compile(open('youtube_dlc/version.py').read(), 'youtube_dlc/version.py', 'exec')) - -_LATEST_VERSION = locals()['__version__'] - -_OLD_VERSION = _LATEST_VERSION.rsplit("-", 1) - -if len(_OLD_VERSION) > 0: - old_ver = _OLD_VERSION[0] - -old_rev = '' -if len(_OLD_VERSION) > 1: - old_rev = _OLD_VERSION[1] - -now = datetime.now() -# ver = f'{datetime.today():%Y.%m.%d}' -ver = now.strftime("%Y.%m.%d") -rev = '' - -if old_ver == ver: - if old_rev: - rev = int(old_rev) + 1 - else: - rev = 1 - -_SEPARATOR = '-' - -version = _SEPARATOR.join(filter(None, [ver, str(rev)])) - -print(version) - -version_list = ver.split(".") -_year, _month, _day = [int(value) for value in version_list] -_rev = 0 -if rev: - _rev = rev -_ver_tuple = _year, _month, _day, _rev - -version_file = VSVersionInfo( - ffi=FixedFileInfo( - filevers=_ver_tuple, - prodvers=_ver_tuple, - mask=0x3F, - flags=0x0, - OS=0x4, - fileType=0x1, - subtype=0x0, - date=(0, 0), - ), - kids=[ - StringFileInfo( - [ - StringTable( - "040904B0", - [ - StringStruct("Comments", "Youtube-dlc_x86 Command Line Interface."), - StringStruct("CompanyName", "theidel@uni-bremen.de"), - StringStruct("FileDescription", FILE_DESCRIPTION), - StringStruct("FileVersion", version), - StringStruct("InternalName", "youtube-dlc_x86"), - StringStruct( - "LegalCopyright", - "theidel@uni-bremen.de | UNLICENSE", - ), - StringStruct("OriginalFilename", "youtube-dlc_x86.exe"), - StringStruct("ProductName", "Youtube-dlc_x86"), - StringStruct("ProductVersion", version + "_x86 | git.io/JUGsM"), - ], - ) - ] - ), - VarFileInfo([VarStruct("Translation", [0, 1200])]) - ] -) - -PyInstaller.__main__.run([ - '--name=youtube-dlc_x86', - '--onefile', - '--icon=win/icon/cloud.ico', - 'youtube_dlc/__main__.py', -]) -SetVersion('dist/youtube-dlc_x86.exe', version_file) diff --git a/setup.py b/setup.py index 7cc2bff48..c1e2ec727 100644 --- a/setup.py +++ b/setup.py @@ -7,10 +7,12 @@ import sys from distutils.spawn import spawn + # Get the version from youtube_dlc/version.py without importing the package exec(compile(open('youtube_dlc/version.py').read(), 'youtube_dlc/version.py', 'exec')) + DESCRIPTION = 'Command-line program to download videos from YouTube.com and many other other video platforms.' LONG_DESCRIPTION = '\n\n'.join(( @@ -18,6 +20,9 @@ '**PS**: Many links in this document will not work since this is a copy of the README.md from Github', open("README.md", "r", encoding="utf-8").read())) +REQUIREMENTS = ['mutagen'] + + if len(sys.argv) >= 2 and sys.argv[1] == 'py2exe': print("inv") else: @@ -61,7 +66,7 @@ def run(self): ) -packages = find_packages(exclude=("youtube_dl","test",)) +packages = find_packages(exclude=("youtube_dl", "test", "ytdlp_plugins")) setup( name="yt-dlp", @@ -73,6 +78,7 @@ def run(self): long_description_content_type="text/markdown", url="https://github.com/pukkandan/yt-dlp", packages=packages, + install_requires=REQUIREMENTS, project_urls={ 'Documentation': 'https://github.com/pukkandan/yt-dlp#yt-dlp', 'Source': 'https://github.com/pukkandan/yt-dlp', diff --git a/test/test_unicode_literals.py b/test/test_unicode_literals.py index e6627a3e5..6c1b7ec91 100644 --- a/test/test_unicode_literals.py +++ b/test/test_unicode_literals.py @@ -15,8 +15,6 @@ 'setup.py', # http://bugs.python.org/issue13943 'conf.py', 'buildserver.py', - 'pyinst.py', - 'pyinst32.py', ] IGNORED_DIRS = [ diff --git a/win/ver.txt b/win/ver.txt deleted file mode 100644 index 2d0e1bc25..000000000 --- a/win/ver.txt +++ /dev/null @@ -1,45 +0,0 @@ -# UTF-8 -# -# For more details about fixed file info 'ffi' see: -# http://msdn.microsoft.com/en-us/library/ms646997.aspx -VSVersionInfo( - ffi=FixedFileInfo( - # filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4) - # Set not needed items to zero 0. - filevers=(16, 9, 2020, 0), - prodvers=(16, 9, 2020, 0), - # Contains a bitmask that specifies the valid bits 'flags'r - mask=0x3f, - # Contains a bitmask that specifies the Boolean attributes of the file. - flags=0x0, - # The operating system for which this file was designed. - # 0x4 - NT and there is no need to change it. - # OS=0x40004, - OS=0x4, - # The general type of file. - # 0x1 - the file is an application. - fileType=0x1, - # The function of the file. - # 0x0 - the function is not defined for this fileType - subtype=0x0, - # Creation date and time stamp. - date=(0, 0) - ), - kids=[ - StringFileInfo( - [ - StringTable( - u'040904B0', - [StringStruct(u'Comments', u'Youtube-dlc Command Line Interface.'), - StringStruct(u'CompanyName', u'theidel@uni-bremen.de'), - StringStruct(u'FileDescription', u'Media Downloader'), - StringStruct(u'FileVersion', u'16.9.2020.0'), - StringStruct(u'InternalName', u'youtube-dlc'), - StringStruct(u'LegalCopyright', u'theidel@uni-bremen.de | UNLICENSE'), - StringStruct(u'OriginalFilename', u'youtube-dlc.exe'), - StringStruct(u'ProductName', u'Youtube-dlc'), - StringStruct(u'ProductVersion', u'16.9.2020.0 | git.io/JUGsM')]) - ]), - VarFileInfo([VarStruct(u'Translation', [0, 1200])]) - ] -) diff --git a/youtube_dlc/postprocessor/embedthumbnail.py b/youtube_dlc/postprocessor/embedthumbnail.py index b9205a5ca..24750e3bd 100644 --- a/youtube_dlc/postprocessor/embedthumbnail.py +++ b/youtube_dlc/postprocessor/embedthumbnail.py @@ -153,7 +153,7 @@ def is_webp(path): elif info['ext'] in ['ogg', 'opus']: if not _has_mutagen: - raise EmbedThumbnailPPError('module mutagen was not found. Please install') + raise EmbedThumbnailPPError('module mutagen was not found. Please install using `python -m pip install mutagen`') size_regex = r',\s*(?P\d+)x(?P\d+)\s*[,\[]' size_result = self.run_ffmpeg(thumbnail_filename, thumbnail_filename, ['-hide_banner']) mobj = re.search(size_regex, size_result)