{"id":21206189,"url":"https://github.com/rtmigo/framefile_py","last_synced_at":"2025-07-18T14:32:38.057Z","repository":{"id":57432128,"uuid":"410701053","full_name":"rtmigo/framefile_py","owner":"rtmigo","description":"File name patterns for Blender 3D and ffmpeg","archived":false,"fork":false,"pushed_at":"2021-10-24T02:00:53.000Z","size":92,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-20T22:19:30.013Z","etag":null,"topics":["glob","hash","package","pattern","python","regex","string","text"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/framefile/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rtmigo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-09-27T01:04:56.000Z","updated_at":"2022-02-13T23:53:50.000Z","dependencies_parsed_at":"2022-09-19T08:02:24.150Z","dependency_job_id":null,"html_url":"https://github.com/rtmigo/framefile_py","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtmigo%2Fframefile_py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtmigo%2Fframefile_py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtmigo%2Fframefile_py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtmigo%2Fframefile_py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rtmigo","download_url":"https://codeload.github.com/rtmigo/framefile_py/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243658274,"owners_count":20326467,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["glob","hash","package","pattern","python","regex","string","text"],"created_at":"2024-11-20T20:54:44.663Z","updated_at":"2025-03-14T23:11:50.435Z","avatar_url":"https://github.com/rtmigo.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![PyPI version shields.io](https://img.shields.io/pypi/v/framefile.svg)](https://pypi.python.org/pypi/framefile/)\n[![Generic badge](https://img.shields.io/badge/Python-3.7+-blue.svg)](#)\n[![Generic badge](https://img.shields.io/badge/Tested_on-Windows%20|%20Linux%20|%20MacOS-blue.svg)](#)\n[![Downloads](https://pepy.tech/badge/framefile/month)](https://pepy.tech/project/framefile)\n\n# [framefile](https://github.com/rtmigo/framefile_py#readme)\n\nPython library for parsing and matching file name patterns like `IMG_####.JPG` or \n`IMG_%04d.JPG`.\n\n---\n\nSuch files are often created by cameras and video production software.\nAs a rule, this is a set of images with consecutive numbers, \nlike `IMG_0001.JPG`, `IMG_0002.JPG`, `IMG_0003.JPG` and so on.\n\nTo handle files such as video sequences, [Blender](https://www.blender.org/)\nand [AE](https://www.adobe.com/products/aftereffects.html) use patterns like\n`IMG_####.JPG`. [ffmpeg](https://www.ffmpeg.org/) uses patterns like\n`IMG_%04d.JPG`.\n\nThis package can create and parse patterns in both formats.\n\n# Install\n\n```\npip3 install framefile\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eother options\u003c/summary\u003e\n\n#### Install pre-release from GitHub:\n```\npip3 install git+https://github.com/rtmigo/framefile_py@staging#egg=framefile\n```\n\n\u003c/details\u003e\n\n# Use\n\n## Guess pattern from file name\n\n```python3\nfrom framefile import filename_to_pattern, Format\n\nprint(filename_to_pattern(Format.hash, \"IMG_4567.JPG\"))  # IMG_####.JPG\nprint(filename_to_pattern(Format.percent, \"IMG_4567.JPG\"))  # IMG_%04d.JPG\n```\n\nAny names with numbers in them are supported. The path can also be part of \nthe file name.\n\n```python3\nfrom framefile import filename_to_pattern, Format\n\nprint(filename_to_pattern(Format.hash, \"/video/frame-01234.png\"))\n\n# /video/frame-#####.png\n```\n\nIf there are several number sequences in the file name, only the last of them \nwill be considered a pattern. And only if its length is more than one digit.\n\n```python\nfrom framefile import filename_to_pattern, Format\n\nprint(filename_to_pattern(Format.hash, \"/video/take505_frame01234.cr2\"))\n\n# /video/take505_frame#####.cr2\n```\n\n## Guess pattern from directory path\n\nThe `directory_to_pattern` function returns the most common file name pattern \nfound in particular directory.\n\n```python\nfrom pathlib import Path\nfrom framefile import directory_to_pattern, Format\n\nprint(directory_to_pattern(Format.hash, Path(\"/path/to/my_timelapse\")))\n\n# /path/to/my_timelapse/img####.jpg\n\nprint(directory_to_pattern(Format.percent, Path(\"/path/to/my_timelapse\")))\n\n# /path/to/my_timelapse/img%04d.jpg\n```\n\n\n\n## Find files by pattern\n\n```python\nimport glob\nimport framefile\n\n# print all files matching /path/to/img####.jpg\nfile_mask = framefile.hash_pattern_to_glob('/path/to/img####.jpg')\nprint(glob.glob(file_mask))\n\n# print all files matching /path/to/img%04d.jpg\nfile_mask = framefile.pct_pattern_to_glob('/path/to/img%04d.jpg')\nprint(glob.glob(file_mask))\n```\n\n## Match file names as strings\n\n```python\nimport re\nimport framefile\n\nregex = framefile.hash_pattern_to_regex('img####.jpg')\n# or framefile.pct_pattern_to_regex('img%04d.jpg')\n\na = re.match(regex, 'img0023.jpg')\nprint(a.group(0))  # img0023.jpg\nprint(a.group(1))  # 0023\n\nb = re.match(regex, 'anything.txt')\nprint(b)  # None\n```\n\n## Extract number from file name\n\n```python\nimport framefile\n\nx: int = framefile.hash_extract_number(\"img####.jpg\", \"img0023.jpg\")\nprint(x)  # 23\n\ny: int = framefile.pct_extract_number(\"img%04d.jpg\", \"img0023.jpg\")\nprint(y)  # 23\n```\n\nIf the name does not match the pattern, both functions throw the same `PatternMismatchError`.\n\n```python\nimport framefile\n\ntry:\n    z = framefile.hash_extract_number(\"img####.jpg\", \"thumbs.db\")\nexcept framefile.PatternMismatchError:\n    print(\"Oops!\")\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frtmigo%2Fframefile_py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frtmigo%2Fframefile_py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frtmigo%2Fframefile_py/lists"}