Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d6bc4e09e | ||
|
|
3e14b718ef | ||
|
|
1ae6270561 | ||
|
|
55a601c07e | ||
|
|
7d67b81879 |
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. Dates are d
|
|||||||
|
|
||||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||||
|
|
||||||
|
#### [v0.45.6](https://github.com/RhetTbull/osxphotos/compare/v0.45.5...v0.45.6)
|
||||||
|
|
||||||
|
> 5 February 2022
|
||||||
|
|
||||||
|
- Fix for unicode in query strings, #618 [`9b247ac`](https://github.com/RhetTbull/osxphotos/commit/9b247acd1cc4b2def59fdd18a6fb3c8eb9914f11)
|
||||||
|
- Fix for --name searching only original_filename on Photos 5+, #594 [`cd02144`](https://github.com/RhetTbull/osxphotos/commit/cd02144ac33cc1c13a20358133971c84d35b8a57)
|
||||||
|
|
||||||
#### [v0.45.5](https://github.com/RhetTbull/osxphotos/compare/v0.45.4...v0.45.5)
|
#### [v0.45.5](https://github.com/RhetTbull/osxphotos/compare/v0.45.4...v0.45.5)
|
||||||
|
|
||||||
> 5 February 2022
|
> 5 February 2022
|
||||||
|
|||||||
12
MANIFEST.in
12
MANIFEST.in
@@ -1,7 +1,7 @@
|
|||||||
include README.md
|
include osxphotos/*.json
|
||||||
include README.rst
|
include osxphotos/*.md
|
||||||
include osxphotos/templates/*
|
|
||||||
include osxphotos/phototemplate.tx
|
include osxphotos/phototemplate.tx
|
||||||
include osxphotos/phototemplate.md
|
include osxphotos/queries/*
|
||||||
include osxphotos/tutorial.md
|
include osxphotos/templates/*
|
||||||
include osxphotos/queries/*
|
include README.md
|
||||||
|
include README.rst
|
||||||
@@ -1725,7 +1725,7 @@ Substitution Description
|
|||||||
{lf} A line feed: '\n', alias for {newline}
|
{lf} A line feed: '\n', alias for {newline}
|
||||||
{cr} A carriage return: '\r'
|
{cr} A carriage return: '\r'
|
||||||
{crlf} a carriage return + line feed: '\r\n'
|
{crlf} a carriage return + line feed: '\r\n'
|
||||||
{osxphotos_version} The osxphotos version, e.g. '0.45.6'
|
{osxphotos_version} The osxphotos version, e.g. '0.45.8'
|
||||||
{osxphotos_cmd_line} The full command line used to run osxphotos
|
{osxphotos_cmd_line} The full command line used to run osxphotos
|
||||||
|
|
||||||
The following substitutions may result in multiple values. Thus if specified for
|
The following substitutions may result in multiple values. Thus if specified for
|
||||||
@@ -3629,7 +3629,7 @@ The following template field substitutions are availabe for use the templating s
|
|||||||
|{lf}|A line feed: '\n', alias for {newline}|
|
|{lf}|A line feed: '\n', alias for {newline}|
|
||||||
|{cr}|A carriage return: '\r'|
|
|{cr}|A carriage return: '\r'|
|
||||||
|{crlf}|a carriage return + line feed: '\r\n'|
|
|{crlf}|a carriage return + line feed: '\r\n'|
|
||||||
|{osxphotos_version}|The osxphotos version, e.g. '0.45.6'|
|
|{osxphotos_version}|The osxphotos version, e.g. '0.45.8'|
|
||||||
|{osxphotos_cmd_line}|The full command line used to run osxphotos|
|
|{osxphotos_cmd_line}|The full command line used to run osxphotos|
|
||||||
|{album}|Album(s) photo is contained in|
|
|{album}|Album(s) photo is contained in|
|
||||||
|{folder_album}|Folder path + album photo is contained in. e.g. 'Folder/Subfolder/Album' or just 'Album' if no enclosing folder|
|
|{folder_album}|Folder path + album photo is contained in. e.g. 'Folder/Subfolder/Album' or just 'Album' if no enclosing folder|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Sphinx build info version 1
|
# Sphinx build info version 1
|
||||||
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
|
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
|
||||||
config: 3c4bdd115410fda411407689f33d7c4c
|
config: bf43bf49b725c31ce72a8823e4f8012b
|
||||||
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
||||||
|
|||||||
2
docs/_static/documentation_options.js
vendored
2
docs/_static/documentation_options.js
vendored
@@ -1,6 +1,6 @@
|
|||||||
var DOCUMENTATION_OPTIONS = {
|
var DOCUMENTATION_OPTIONS = {
|
||||||
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
|
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
|
||||||
VERSION: '0.45.6',
|
VERSION: '0.45.8',
|
||||||
LANGUAGE: 'None',
|
LANGUAGE: 'None',
|
||||||
COLLAPSE_INDEX: false,
|
COLLAPSE_INDEX: false,
|
||||||
BUILDER: 'html',
|
BUILDER: 'html',
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||||
|
|
||||||
<title>osxphotos command line interface (CLI) — osxphotos 0.45.6 documentation</title>
|
<title>osxphotos command line interface (CLI) — osxphotos 0.45.8 documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
||||||
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Index — osxphotos 0.45.6 documentation</title>
|
<title>Index — osxphotos 0.45.8 documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
||||||
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||||
|
|
||||||
<title>Welcome to osxphotos’s documentation! — osxphotos 0.45.6 documentation</title>
|
<title>Welcome to osxphotos’s documentation! — osxphotos 0.45.8 documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
||||||
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||||
|
|
||||||
<title>osxphotos — osxphotos 0.45.6 documentation</title>
|
<title>osxphotos — osxphotos 0.45.8 documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
||||||
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||||
|
|
||||||
<title>osxphotos package — osxphotos 0.45.6 documentation</title>
|
<title>osxphotos package — osxphotos 0.45.8 documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
||||||
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Search — osxphotos 0.45.6 documentation</title>
|
<title>Search — osxphotos 0.45.8 documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ datas = [
|
|||||||
("osxphotos/phototemplate.tx", "osxphotos"),
|
("osxphotos/phototemplate.tx", "osxphotos"),
|
||||||
("osxphotos/phototemplate.md", "osxphotos"),
|
("osxphotos/phototemplate.md", "osxphotos"),
|
||||||
("osxphotos/tutorial.md", "osxphotos"),
|
("osxphotos/tutorial.md", "osxphotos"),
|
||||||
|
("osxphotos/exiftool_filetypes.json", "osxphotos"),
|
||||||
]
|
]
|
||||||
package_imports = [["photoscript", ["photoscript.applescript"]]]
|
package_imports = [["photoscript", ["photoscript.applescript"]]]
|
||||||
for package, files in package_imports:
|
for package, files in package_imports:
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
""" version info """
|
""" version info """
|
||||||
|
|
||||||
__version__ = "0.45.6"
|
__version__ = "0.45.8"
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import html
|
|||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import pathlib
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -19,11 +20,12 @@ from functools import lru_cache # pylint: disable=syntax-error
|
|||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"escape_str",
|
"escape_str",
|
||||||
"unescape_str",
|
"exiftool_can_write",
|
||||||
"terminate_exiftool",
|
|
||||||
"get_exiftool_path",
|
|
||||||
"ExifTool",
|
"ExifTool",
|
||||||
"ExifToolCaching",
|
"ExifToolCaching",
|
||||||
|
"get_exiftool_path",
|
||||||
|
"terminate_exiftool",
|
||||||
|
"unescape_str",
|
||||||
]
|
]
|
||||||
|
|
||||||
# exiftool -stay_open commands outputs this EOF marker after command is run
|
# exiftool -stay_open commands outputs this EOF marker after command is run
|
||||||
@@ -33,6 +35,24 @@ EXIFTOOL_STAYOPEN_EOF_LEN = len(EXIFTOOL_STAYOPEN_EOF)
|
|||||||
# list of exiftool processes to cleanup when exiting or when terminate is called
|
# list of exiftool processes to cleanup when exiting or when terminate is called
|
||||||
EXIFTOOL_PROCESSES = []
|
EXIFTOOL_PROCESSES = []
|
||||||
|
|
||||||
|
# exiftool supported file types, created by utils/exiftool_supported_types.py
|
||||||
|
EXIFTOOL_FILETYPES_JSON = "exiftool_filetypes.json"
|
||||||
|
with (pathlib.Path(__file__).parent / EXIFTOOL_FILETYPES_JSON).open("r") as f:
|
||||||
|
EXIFTOOL_SUPPORTED_FILETYPES = json.load(f)
|
||||||
|
|
||||||
|
|
||||||
|
def exiftool_can_write(suffix: str) -> bool:
|
||||||
|
"""Return True if exiftool supports writing to a file with the given suffix, otherwise False"""
|
||||||
|
if not suffix:
|
||||||
|
return False
|
||||||
|
suffix = suffix.lower()
|
||||||
|
if suffix[0] == ".":
|
||||||
|
suffix = suffix[1:]
|
||||||
|
return (
|
||||||
|
suffix in EXIFTOOL_SUPPORTED_FILETYPES
|
||||||
|
and EXIFTOOL_SUPPORTED_FILETYPES[suffix]["write"]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def escape_str(s):
|
def escape_str(s):
|
||||||
"""escape string for use with exiftool -E"""
|
"""escape string for use with exiftool -E"""
|
||||||
|
|||||||
4976
osxphotos/exiftool_filetypes.json
Normal file
4976
osxphotos/exiftool_filetypes.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
import glob
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
@@ -33,7 +32,7 @@ from ._constants import (
|
|||||||
)
|
)
|
||||||
from ._version import __version__
|
from ._version import __version__
|
||||||
from .datetime_utils import datetime_tz_to_utc
|
from .datetime_utils import datetime_tz_to_utc
|
||||||
from .exiftool import ExifTool
|
from .exiftool import ExifTool, exiftool_can_write
|
||||||
from .export_db import ExportDB_ABC, ExportDBNoOp
|
from .export_db import ExportDB_ABC, ExportDBNoOp
|
||||||
from .fileutil import FileUtil
|
from .fileutil import FileUtil
|
||||||
from .photokit import (
|
from .photokit import (
|
||||||
@@ -1260,11 +1259,27 @@ class PhotoExporter:
|
|||||||
|
|
||||||
exiftool_results = ExportResults()
|
exiftool_results = ExportResults()
|
||||||
|
|
||||||
|
# don't try to write if unsupported file type for exiftool
|
||||||
|
if not exiftool_can_write(os.path.splitext(src)[-1]):
|
||||||
|
exiftool_results.exiftool_warning.append(
|
||||||
|
(
|
||||||
|
dest,
|
||||||
|
f"Unsupported file type for exiftool, skipping exiftool for {dest}",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# set file signature so the file doesn't get re-exported with --update
|
||||||
|
export_db.set_data(
|
||||||
|
dest,
|
||||||
|
uuid=self.photo.uuid,
|
||||||
|
exif_stat=fileutil.file_sig(src),
|
||||||
|
exif_json=self._exiftool_json_sidecar(options=options),
|
||||||
|
)
|
||||||
|
return exiftool_results
|
||||||
|
|
||||||
# determine if we need to write the exif metadata
|
# determine if we need to write the exif metadata
|
||||||
# if we are not updating, we always write
|
# if we are not updating, we always write
|
||||||
# else, need to check the database to determine if we need to write
|
# else, need to check the database to determine if we need to write
|
||||||
run_exiftool = not options.update
|
run_exiftool = not options.update
|
||||||
current_data = "foo"
|
|
||||||
if options.update:
|
if options.update:
|
||||||
files_are_different = False
|
files_are_different = False
|
||||||
old_data = export_db.get_exifdata_for_file(dest)
|
old_data = export_db.get_exifdata_for_file(dest)
|
||||||
|
|||||||
@@ -6125,57 +6125,60 @@ def test_export_cleanup_exiftool_accented_album_name_same_filenames():
|
|||||||
runner = CliRunner()
|
runner = CliRunner()
|
||||||
cwd = os.getcwd()
|
cwd = os.getcwd()
|
||||||
# pylint: disable=not-context-manager
|
# pylint: disable=not-context-manager
|
||||||
with tempfile.TemporaryDirectory() as tempdir:
|
with tempfile.TemporaryDirectory() as report_dir:
|
||||||
result = runner.invoke(
|
# keep report file out of of expor dir for --cleanup
|
||||||
export,
|
report_file = os.path.join(report_dir, "test.csv")
|
||||||
[
|
with tempfile.TemporaryDirectory() as tempdir:
|
||||||
os.path.join(cwd, CLI_PHOTOS_DB),
|
result = runner.invoke(
|
||||||
tempdir,
|
export,
|
||||||
"-V",
|
[
|
||||||
"--cleanup",
|
os.path.join(cwd, CLI_PHOTOS_DB),
|
||||||
"--directory",
|
tempdir,
|
||||||
"{album[/,.|:,.]}",
|
"-V",
|
||||||
"--exiftool",
|
"--cleanup",
|
||||||
"--exiftool-merge-keywords",
|
"--directory",
|
||||||
"--exiftool-merge-persons",
|
"{album[/,.|:,.]}",
|
||||||
"--keyword-template",
|
"--exiftool",
|
||||||
"{keyword}",
|
"--exiftool-merge-keywords",
|
||||||
"--report",
|
"--exiftool-merge-persons",
|
||||||
"test.csv",
|
"--keyword-template",
|
||||||
"--skip-original-if-edited",
|
"{keyword}",
|
||||||
"--update",
|
"--report",
|
||||||
"--touch-file",
|
report_file,
|
||||||
"--not-hidden",
|
"--skip-original-if-edited",
|
||||||
],
|
"--update",
|
||||||
)
|
"--touch-file",
|
||||||
assert "Deleted: 0 files, 0 directories" in result.output
|
"--not-hidden",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
assert "Deleted: 0 files, 0 directories" in result.output
|
||||||
|
|
||||||
# do it again
|
# do it again
|
||||||
result = runner.invoke(
|
result = runner.invoke(
|
||||||
export,
|
export,
|
||||||
[
|
[
|
||||||
os.path.join(cwd, CLI_PHOTOS_DB),
|
os.path.join(cwd, CLI_PHOTOS_DB),
|
||||||
tempdir,
|
tempdir,
|
||||||
"-V",
|
"-V",
|
||||||
"--cleanup",
|
"--cleanup",
|
||||||
"--directory",
|
"--directory",
|
||||||
"{album[/,.|:,.]}",
|
"{album[/,.|:,.]}",
|
||||||
"--exiftool",
|
"--exiftool",
|
||||||
"--exiftool-merge-keywords",
|
"--exiftool-merge-keywords",
|
||||||
"--exiftool-merge-persons",
|
"--exiftool-merge-persons",
|
||||||
"--keyword-template",
|
"--keyword-template",
|
||||||
"{keyword}",
|
"{keyword}",
|
||||||
"--report",
|
"--report",
|
||||||
"test.csv",
|
report_file,
|
||||||
"--skip-original-if-edited",
|
"--skip-original-if-edited",
|
||||||
"--update",
|
"--update",
|
||||||
"--touch-file",
|
"--touch-file",
|
||||||
"--not-hidden",
|
"--not-hidden",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert "exported: 0, updated: 0" in result.output
|
assert "exported: 0, updated: 0" in result.output
|
||||||
assert "updated EXIF data: 0" in result.output
|
assert "updated EXIF data: 0" in result.output
|
||||||
assert "Deleted: 0 files, 0 directories" in result.output
|
assert "Deleted: 0 files, 0 directories" in result.output
|
||||||
|
|
||||||
|
|
||||||
def test_save_load_config():
|
def test_save_load_config():
|
||||||
|
|||||||
57
utils/exiftool_supported_types.py
Normal file
57
utils/exiftool_supported_types.py
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
"""Read the "Supported File Types" table from exiftool.org and build a json file from the table"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
url = "https://www.exiftool.org/"
|
||||||
|
json_file = "exiftool_filetypes.json"
|
||||||
|
|
||||||
|
html_content = requests.get(url).text
|
||||||
|
|
||||||
|
soup = BeautifulSoup(html_content, "html.parser")
|
||||||
|
|
||||||
|
# uncomment to see all table classes
|
||||||
|
# print("Classes of each table:")
|
||||||
|
# for table in soup.find_all("table"):
|
||||||
|
# print(table.get("class"))
|
||||||
|
|
||||||
|
# strip footnotes in <span> tags
|
||||||
|
for span_tag in soup.findAll("span"):
|
||||||
|
span_tag.replace_with("")
|
||||||
|
|
||||||
|
# find the table for Supported File Types
|
||||||
|
table = soup.find("table", class_="sticky tight sm bm")
|
||||||
|
|
||||||
|
# get table headers
|
||||||
|
table_headers = [tx.text.lower() for tx in table.find_all("th")]
|
||||||
|
|
||||||
|
# get table data
|
||||||
|
table_data = []
|
||||||
|
for tr in table.find_all("tr"):
|
||||||
|
if row := [td.text for td in tr.find_all("td")]:
|
||||||
|
table_data.append(row)
|
||||||
|
|
||||||
|
# make a dictionary of the table data
|
||||||
|
supported_filetypes = {}
|
||||||
|
for row in table_data:
|
||||||
|
row_dict = dict(zip(table_headers, row))
|
||||||
|
for key, value in row_dict.items():
|
||||||
|
if value == "-":
|
||||||
|
row_dict[key] = None
|
||||||
|
row_dict["file type"] = row_dict["file type"].split(",")
|
||||||
|
row_dict["file type"] = [ft.strip() for ft in row_dict["file type"]]
|
||||||
|
row_dict["read"] = "R" in row_dict["support"]
|
||||||
|
row_dict["write"] = "W" in row_dict["support"]
|
||||||
|
row_dict["create"] = "C" in row_dict["support"]
|
||||||
|
filetypes = [ft.lower() for ft in row_dict["file type"]]
|
||||||
|
for filetype in filetypes:
|
||||||
|
supported_filetypes[filetype] = {"extension": filetype, **row_dict}
|
||||||
|
|
||||||
|
with open(json_file, "w") as jsonfile:
|
||||||
|
print(f"Writing {json_file}...")
|
||||||
|
json.dump(supported_filetypes, jsonfile, indent=4)
|
||||||
Reference in New Issue
Block a user