检测媒体文件的类型

检测媒体文件的类型

如何检测缺少文件扩展名的媒体文件的文件扩展名?我不小心将其删除了。

自问自答。该问题已经问过了这里这里,但问题已被关闭。

答案1

以下 Python 脚本可完成此任务。如果可以检测到,它将替换/附加正确的文件类型。

  • 安装Python
  • pip install filetype在控制台中运行(更多信息
  • 将脚本和要检查的媒体文件移动到单独的目录
  • 双击脚本
  • 按照说明进行操作

在 Windows 7 上测试。如果发现错误,请改进答案。公共领域。

其他可能的解决方案

脚本,例如命名它fix_fileextensions.py

if __name__ == '__main__':

    # make the commandline window stay open on error
    from contextlib import contextmanager
    from traceback import format_exc
    stay_open = False
    @contextmanager
    def stay_open_on_error():
        global stay_open
        try:
            yield
        except SystemExit:
            stay_open = True
        except:
            print(format_exc())
            stay_open = True
        if stay_open:
            input('Press key to close')

    with stay_open_on_error():

        # import some modules from the Python standard lib
        import sys, os
        from time import sleep
        from pathlib import Path

        # import the filetype package or inform user what to do
        try:
            from filetype import guess
        except ModuleNotFoundError:
            print(
                'This script uses the "filetype" package '
                'to guess the file type. '
                'Please open a console and type:\n\n'
                '    pip install filetype\n\n'
                'More info here: https://pypi.org/project/filetype/\n\n'
                'Nothing was changed.\n'
            )
            sys.exit(1)

        # define scriptpath and workdir
        scriptpath = Path(__file__).resolve()
        scriptargs = sys.argv
        if len(scriptargs) > 1:
            workdir = Path(scriptargs[1]).resolve()
            if not workdir.exists():
                raise Exception(f'Directory {workdir} does not exist')
            elif workdir.is_file():
                raise Exception('{workdir} is not a directory')
        else:
            workdir = scriptpath.parent
        scriptpath = str(scriptpath)

        # define movetodir
        c = 2
        movetodir = workdir / 'renamed'
        while movetodir.exists():
            movetodir = workdir / f'renamed ({c})'
            c += 1
        movetodir.mkdir()

        # define filesbytype
        filesbytype = {}
        for entry in os.scandir(workdir):
            filepath = entry.path
            if entry.is_dir() or filepath == scriptpath:
                continue
            else:
                info = guess(filepath)
                if info is not None:
                    info = info.extension, info.mime
                if info not in filesbytype:
                    filesbytype[info] = []
                filesbytype[info].append(entry.name)

        if filesbytype:

            # tool for printing unprintable filenames
            def safeprint(filename):
                try:
                    print(filename)
                except UnicodeEncodeError:
                    print(filename.encode('ascii', 'replace').decode())

            # tool to print a prettyprinted list of filenames
            def print_filenames(filenames):
                sep = 0
                for name in filenames:
                    sep = max(sep, len(name))
                sep = (sep + 2) * '-'
                print(sep)
                for filename in filenames:
                    safeprint('* ' + filename)
                print(sep)

            # print these filenames and optionally rename them
            for info, filenames in sorted(filesbytype.items()):
                if info is not None:
                    print_filenames(filenames)
                    filetype, mime = info
                    print(
                        "\nThese files seemingly have the file type "
                        f"'.{filetype}' and the MIME type '{mime}'."
                    )
                    ok = input(
                        'Do you want me to append/change their extension '
                        f'to ".{filetype}"? (y/n)\n> '
                    )
                    if ok.lower() == 'y':
                        for filename in filenames:
                            now = workdir / filename
                            then = (movetodir / filename).with_suffix(
                                f'.{filetype}'
                            )
                            now.rename(then)
                        print(
                            f'Ok, {len(filenames)} files were renamed '
                            f'and moved to {movetodir}'
                        )
                    else:
                        print('Ok, will not rename these files')
                    print()

            # Maybe show the files for which the type could not be detected
            if None in filesbytype:
                print_filenames(filesbytype[None])
                print(
                    '\nSorry, could not detect the file type '
                    'for these files.\n'
                )

        # When the workdir is empty, print message and do nothing
        else:
            print(f'Found no files to rename in {workdir}')

        # remove the output directory when no files have been renamed
        try:
            movetodir.rmdir()
        except OSError:
            pass

        print('DONE')
        sleep(2)

相关内容