Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
128 commits
Select commit Hold shift + click to select a range
bec818c
v0.5.0-alpha.0 new branch for upcoming changes. See CHANGELOG.md for…
sylikc Mar 13, 2021
b565c53
breaks compatibility of constructor. executable_ -> executable
sylikc Mar 17, 2021
efbf835
get the tests to pass in the way that makes sense
sylikc Mar 17, 2021
52d60ca
be explicit in the warning returned in start()
sylikc Mar 17, 2021
beb2085
make the rest of the class consistently named for now
sylikc Mar 17, 2021
64d44de
add some TODOs to check code and consider whether to refactor later
sylikc Mar 17, 2021
f414057
make block_size a property which can be set to define a read block size
sylikc Apr 1, 2021
51837da
as per comment https://gist.github.com/techtonik/4368898#gistcomment-…
sylikc Apr 1, 2021
85e9d3a
change the targeting of Python version to 3.6+
sylikc Apr 1, 2021
46711d4
as per discussion https://github.com/sylikc/pyexiftool/discussions/10…
sylikc Apr 1, 2021
e94eccf
(temporary until decided) return None right now when JSON result come…
sylikc Apr 2, 2021
05986d5
make the execute() work with a synchronization number.
sylikc Apr 2, 2021
56af0a9
added code to read from stderr as well. I think I'll be able to dete…
sylikc Apr 2, 2021
5a87388
change how terminate() works on Windows when __del__ is in progress. …
sylikc Apr 6, 2021
7a28188
change the function signature of terminate() to match subprocess API,…
sylikc Apr 6, 2021
c8167e8
change the way ExifTool.running is detected. In the event that exift…
sylikc Apr 7, 2021
8700d32
fixed the bug that freezes on windows because stderr is empty on os.r…
sylikc Apr 8, 2021
1cff835
extracted all high-level functionality out of the ExifTool class. th…
sylikc Apr 8, 2021
06a8fac
consolidate the get_metadata functionality to take either a str or a …
sylikc Apr 8, 2021
f36acb2
fixed a bug where if the filename is a number (it doesn't happen ofte…
sylikc Apr 8, 2021
ca5141b
remove get_tags and rename get_tags_batch to get_tags, similar to the…
sylikc Apr 8, 2021
a4b5710
fix tests to isolate the ExifTool and ExifToolHelper tests
sylikc Apr 8, 2021
dbc4c18
moved for extraneous functionality over from exiftool to helper
sylikc Apr 8, 2021
46411dc
fixed the tests and now it's entirely working on Windows with the kill()
sylikc Apr 8, 2021
17cf6ea
merge the handling of of get_metadata and get_tags... since they esse…
sylikc Apr 8, 2021
370b7a7
fix the warning on helper_test so it doesn't terminate if not running
sylikc Apr 8, 2021
b6e1904
Merge branch 'master' into v0.5.x-py3-refactor
sylikc Apr 8, 2021
3197049
fix small bugs in the merging and make sure all tests pass
sylikc Apr 9, 2021
e65775f
add the test that warns when the process dies after it was detected a…
sylikc Apr 9, 2021
b85ac1a
added the config_file property to do error checking
sylikc Apr 17, 2021
9ad8706
commented out the fscodec() code that was first introduced in commit …
sylikc Apr 17, 2021
8abc387
as per recommendations in consistent testing, I wrote some Windows ba…
sylikc Apr 17, 2021
42c794b
start with legwork of getting annotations and such working with mypy,…
sylikc Apr 17, 2021
00df51b
mypy helped fix a bug in terminate() referring to a bad variable in T…
sylikc Apr 17, 2021
fc234d5
simplify the format of the sequences with Python 3.6 f-strings
sylikc Apr 18, 2021
ed07bbd
more type hints
sylikc Apr 18, 2021
7488436
added stub for logging
sylikc Apr 18, 2021
738b00c
add in empty placeholder for the tests/tmp dir
sylikc Apr 19, 2021
18519b6
update gitignore for the tests/tmp/ dir
sylikc Apr 19, 2021
5db3efd
convert helper to using pathlib.Path for better clarity.
sylikc Apr 19, 2021
9531777
update tests for more coverage
sylikc Apr 19, 2021
8281a5e
fix pytest-cov script to only show coverage for exiftool, and not oth…
sylikc Apr 19, 2021
ebbc465
exiftool logger is still a WIP, not really implemented yet
sylikc Apr 19, 2021
64371d5
Merge branch 'master' into v0.5.x-py3-refactor
sylikc Apr 19, 2021
d2f43ef
pulled out the @staticmethod to the module-level since it's really no…
sylikc Apr 19, 2021
7fc5857
fixed an indent bug (from the merge) and annotation bug in helper.py
sylikc Apr 20, 2021
ee4bbab
exiftool.py:
sylikc Apr 20, 2021
f85c215
rename the 'doc' to 'docs' to follow more with the convention of the …
sylikc Apr 20, 2021
500f758
trying to get documentation working again, need to document as we mov…
sylikc Apr 20, 2021
fb8b4f9
added the version and version_tuple properties which is the exiftool …
sylikc Apr 22, 2021
4597b54
adjust copyright
sylikc Apr 22, 2021
2f2872b
add some rudimentary logging into ExifTool class
sylikc Apr 22, 2021
590bfe2
put in some stub for Logger testing, but I encountered a freeze when …
sylikc Apr 24, 2021
63de62f
Merge branch 'master' into v0.5.x-py3-refactor
sylikc Apr 29, 2021
ad85272
added some other extensions to sphinx to generate cooler documentatio…
sylikc May 5, 2021
da8827d
created a little private method that just unsets all the variables pe…
sylikc May 5, 2021
d54af01
removing now-defunct devnull code, since we now read from stderr and …
sylikc May 5, 2021
f5d5ca3
remove the logging.debug()
sylikc May 5, 2021
7aa1482
unified the call to subprocess.Popen so it's clearer in someways that…
sylikc May 5, 2021
57b72cd
super duper hacky fix to some Python interpreter vs exiftool interact…
sylikc May 6, 2021
b4ab5f9
removed unnecessary check, as get_tags() has this parameter checking …
sylikc May 6, 2021
93bfb15
Test basic functionality
jangop May 11, 2021
a66c4b1
Merge branch 'master' into v0.5.x-py3-refactor
sylikc May 20, 2021
c1a52a9
I messed up when merging PRs from GitHub... working with multiple rem…
sylikc May 20, 2021
1089e24
move the TestTagCopying to ExifToolHelper test script
sylikc May 20, 2021
956f1c9
decided that execute_json() will return None if no output came back f…
sylikc May 26, 2021
2e8f26b
add in last_status. This is the exit status from the previous comman…
sylikc May 26, 2021
578e899
update copyright on LICENSE file to reflect years as per standard
sylikc May 26, 2021
d4d57f3
make the python.exe call explicit with .EXE extension in the batch files
sylikc May 28, 2021
0d7b3ff
add in a README which shows the requirements file for existing ones
sylikc May 28, 2021
854cc7f
exiftool.py fix all the:
sylikc May 28, 2021
2eefce0
fix the DeprecationWarning: Please use assertEqual instead.
sylikc May 28, 2021
b3a279d
fix all: E261 at least two spaces before inline comment
sylikc May 28, 2021
09b43f2
changed ExifTool common_args=None means that an empty list is set. A…
sylikc May 28, 2021
452f50a
fix most of the: E265 block comment should start with '# '
sylikc May 28, 2021
bb3783e
fix some more PEP8 stuff and other things caught in static analysis b…
sylikc May 28, 2021
dd31ca1
adding restore of config file before doing the create/test/set that w…
sylikc May 28, 2021
0c7c01c
adding current flake8 configuration as per discussion on PEP8 coding …
sylikc May 28, 2021
d7ceb0c
made changes back in May, some extra comments and optimizing a few th…
sylikc Aug 19, 2021
bec1765
as per https://github.com/sylikc/pyexiftool/pull/24 , loguru is a pos…
sylikc Aug 23, 2021
fa4a1a1
Merge branch 'master' into v0.5.x-py3-refactor
sylikc Aug 23, 2021
4bf2ccf
ExifToolHelper - add auto_start feature. Demonstrate overriding exec…
sylikc Aug 23, 2021
e6f7b90
ExifToolHelper - fix bug that if you pass in common_args=[] it breaks…
sylikc Aug 23, 2021
8325f64
ExifToolHelper - changed the way the constructor works
sylikc Sep 11, 2021
ec028a5
ExifToolHelper - support Path-like objects in get_tags()
sylikc Sep 11, 2021
7b61701
Exiftool main class code cleanup.
sylikc Oct 3, 2021
1beaaad
ExifToolHelper() - added terminate() overload
sylikc Oct 3, 2021
53eb0a7
ExifTool main class
sylikc Oct 3, 2021
7b3f384
ExifToolHelper - fix technically incorrect comment... overload -> ove…
sylikc Oct 3, 2021
b03c373
ExifTool - fix some bugs that caused actual use error... also, appare…
sylikc Oct 3, 2021
15792bd
IMPORTANT: API signature of get_tags() has been changed.. `files` and…
sylikc Oct 3, 2021
ead8c46
Represent all “files” as strings
jangop Oct 3, 2021
f4c62a9
Merge branch 'jangop-v0.5.x-py3-refactor' into v0.5.x-py3-refactor
sylikc Oct 3, 2021
137c0e2
ExifTool() - added `encoding` constructor parameter (requires Python …
sylikc Oct 3, 2021
78ec074
Tests tests tests
sylikc Oct 3, 2021
4420cb6
Parse and compare versions of exiftool
jangop Oct 4, 2021
1e33d76
* update documentation in ExifTool() class.
sylikc Jan 31, 2022
314427c
ExifTool - add comment that ${status} only supported on exiftool v12.10+
sylikc Jan 31, 2022
873eece
Examine PR https://github.com/sylikc/pyexiftool/pull/20
sylikc Jan 31, 2022
b20fa3c
Merge Pull request which adds some basic tests to the ExifToolHelper
sylikc Jan 31, 2022
6e08c1c
Merge branch 'v0.5.x-py3-refactor' of github.com:sylikc/pyexiftool in…
sylikc Jan 31, 2022
8cad1b3
merged jangop changes but reverted some of the removed comments. kep…
sylikc Feb 14, 2022
73a57f2
Merge PR https://github.com/sylikc/pyexiftool/pull/32 by https://gith…
sylikc Feb 14, 2022
0fe2ab0
Pull the latest changes (GitHub workflows lint-and-test) from master …
sylikc Feb 14, 2022
d94ff05
Add versioning information __version__ to the package.
sylikc Feb 14, 2022
8c5a3c2
invalid syntax fix
sylikc Feb 14, 2022
0bdbc81
* was in the process of adding a version check, but realized it may n…
sylikc Feb 15, 2022
5a5cf0b
update README.rst to prepare for initial Python3 release. Removed ou…
sylikc Feb 15, 2022
69a34fc
test_helper.py
sylikc Feb 15, 2022
b30f01a
Adding a GitHub workflow to make sure the minimum required version of…
sylikc Feb 15, 2022
3889b77
GitHub action - try again to get the PATH variable to the test steps
sylikc Feb 15, 2022
7b64b19
merge the v0.4.13 changelog in from master one last time
sylikc Feb 15, 2022
608c1f3
Update year on LICENSE
sylikc Feb 15, 2022
1c57f25
Add a "Brief History" section to README for some insight to how all o…
sylikc Feb 15, 2022
4297399
ExifTool - changed the win_shell default (I actually am not sure this…
sylikc Feb 15, 2022
6bc95c0
updated COMPATABILITY.txt with some of the changed features. It's no…
sylikc Feb 15, 2022
a65abbe
Update README.rst
sylikc Feb 15, 2022
c86b269
more refinements to README.rst
sylikc Feb 15, 2022
715cfc8
ExifToolHelper - changed files invalid files parameter to a ValueError
sylikc Feb 15, 2022
dc27b77
test_exiftool.py - added a few tests to increase code coverage
sylikc Feb 15, 2022
3bdf346
update .gitignore as per https://github.com/sylikc/pyexiftool/pull/39
sylikc Feb 27, 2022
4ff74af
ExifTool
sylikc Feb 28, 2022
7460296
.gitignore changed again... not sure why /tmp/ was added in the PR
sylikc Feb 28, 2022
fb23490
ExifTool / ExifToolHelper
sylikc Feb 28, 2022
0d023ce
forgot to import xceptions into helper
sylikc Feb 28, 2022
aa6e4f3
ExifTool
sylikc Feb 28, 2022
48da066
TestExifToolHelper
sylikc Feb 28, 2022
cbca475
* ExifTool - add some typing and documentation updates (better docstr…
sylikc Feb 28, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion .github/workflows/lint-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.7, 3.8, 3.9]
python-version: [3.6, 3.7, 3.8, 3.9]

steps:
- uses: actions/checkout@v2
Expand All @@ -22,7 +22,28 @@ jobs:
python -m pip install --upgrade pip
python -m pip install flake8 pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi

# latest version not yet available on Ubuntu Focal 20.04 LTS, but it's better to install it with all dependencies first
sudo apt-get install -qq libimage-exiftool-perl
exiftool -ver

# get just the minimum version to build and compile, later we can go with latest version to test
export EXIFTOOL_VER=12.15
wget http://backpan.perl.org/authors/id/E/EX/EXIFTOOL/Image-ExifTool-$EXIFTOOL_VER.tar.gz
tar xf Image-ExifTool-$EXIFTOOL_VER.tar.gz
cd Image-ExifTool-$EXIFTOOL_VER/

# https://exiftool.org/install.html#Unix
perl Makefile.PL
make test

export PATH=`pwd`:$PATH
cd ..
exiftool -ver

# save this environment for subsequent steps
# https://brandur.org/fragments/github-actions-env-vars-in-env-vars
echo "PATH=`pwd`:$PATH" >> $GITHUB_ENV
- name: Install pyexiftool
run: |
python -m pip install .
Expand Down
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,12 @@ dist/
MANIFEST

*.egg-info/

# pytest-cov db
.coverage

# tests will be made to write to temp directories with this prefix
tests/exiftool-tmp-*

# IntelliJ
.idea
14 changes: 9 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Date (Timezone) | Version | Comment
---------------------------- | ------- | -------
07/17/2019 12:26:16 AM (PDT) | 0.2.0 | Source was pulled directly from https://github.com/smarnach/pyexiftool with a complete bare clone to preserve all history. Because it's no longer being updated, I will pull all merge requests in and make updates accordingly
07/17/2019 12:50:20 AM (PDT) | 0.2.1 | Convert leading spaces to tabs
07/17/2019 12:50:20 AM (PDT) | 0.2.1 | Convert leading spaces to tabs. (I'm aware of [PEP 8](https://www.python.org/dev/peps/pep-0008/#tabs-or-spaces) recommending spaces over tabs, but I <3 tabs)
07/17/2019 12:52:33 AM (PDT) | 0.2.2 | Merge [Pull request #10 "add copy_tags method"](https://github.com/smarnach/pyexiftool/pull/10) by [Maik Riechert (letmaik) Cambridge, UK](https://github.com/letmaik) on May 28, 2014<br> *This adds a small convenience method to copy any tags from one file to another. I use it for several month now and it works fine for me.*
07/17/2019 01:05:37 AM (PDT) | 0.2.3 | Merge [Pull request #25 "Added option for keeping print conversion active. #25"](https://github.com/smarnach/pyexiftool/pull/25) by [Bernhard Bliem (bbliem)](https://github.com/bbliem) on Jan 17, 2019<br> *For some tags, disabling print conversion (as was the default before) would not make much sense. For example, if print conversion is deactivated, the value of the Composite:LensID tag could be reported as something like "8D 44 5C 8E 34 3C 8F 0E". It is doubtful whether this is useful here, as we would then need to look up what this means in a table supplied with exiftool. We would probably like the human-readable value, which is in this case "AF-S DX Zoom-Nikkor 18-70mm f/3.5-4.5G IF-ED".*<br>*Disabling print conversion makes sense for a lot of tags (e.g., it's nicer to get as the exposure time not the string "1/2" but the number 0.5). In such cases, even if we enable print conversion, we can disable it for individual tags by appending a # symbol to the tag name.*
07/17/2019 01:20:15 AM (PDT) | 0.2.4 | Merge with slight modifications to variable names for clarity (sylikc) [Pull request #27 "Add "shell" keyword argument to ExifTool initialization"](https://github.com/smarnach/pyexiftool/pull/27) by [Douglas Lassance (douglaslassance) Los Angeles, CA](https://github.com/douglaslassance) on 5/29/2019<br>*On Windows this will allow to run exiftool without showing the DOS shell.*<br>**This might break Linux but I don't know for sure**<br>Alternative source location with only this patch: https://github.com/blurstudio/pyexiftool/tree/shell-option
Expand Down Expand Up @@ -35,18 +35,22 @@ Date (Timezone) | Version | Comment
08/22/2021 08:34:45 PM (PDT) | 0.4.11 | no functional code changes. Changed setup.py with updated version and Documentation link pointed to sylikc.github.io -- as per issue #27 by @derMart
08/22/2021 09:02:33 PM (PDT) | 0.4.12 | fixed a bug ExifTool.terminate() where there was a typo. Kept the unused outs, errs though. -- from suggestion in pull request #26 by @aaronkollasch
02/13/2022 03:38:45 PM (PST) | 0.4.13 | (NOTE: Barring any critical bug, this is expected to be the LAST Python 2 supported release!) added GitHub actions. fixed bug in execute_json_wrapper() 'error' was not defined syntactically properly -- merged pull request #30 by https://github.com/jangop
03/13/2021 01:54:44 PM (PST) | 0.5.0a0 | no functional code changes ... yet. this is currently on a separate branch referring to [Break down Exiftool into 2+ classes, a raw Exiftool, and helper classes](https://github.com/sylikc/pyexiftool/discussions/10) and [Deprecating Python 2.x compatibility](https://github.com/sylikc/pyexiftool/discussions/9) . In time this refactor will be the future of PyExifTool, once it stabilizes. I'll make code-breaking updates in this branch from build to build and take comments to make improvements. Consider the 0.5.0 "nightly" quality. Also, changelog versions were modified because I noticed that the LAST release from smarnach is tagged with v0.2.0
02/28/2022 12:39:57 PM (PST) | 0.5.0 | complete refactor of the PyExifTool code. Lots of changes. Some code breaking changes. Not directly backwards-compatible with v0.4.x. See COMPATIBILITY.TXT to understand all the code-breaking changes.


On version changes, update setup.py to reflect version
On version changes, update __int__.py to reflect version


# Changes around the web

Check for changes at the following resources to make sure we have the latest and greatest. While we have the most active fork, I'm just one of the many forks, spoons, and knives!
Check for changes at the following resources to see if anyone has added some nifty features. While we have the most active fork, I'm just one of the many forks, spoons, and knives!

We can also direct users here or answer existing questions as to how to use the original version of ExifTool.

(last checked 5/19/2021 all)
(last checked 2/28/2022 all)

search "pyexiftool github" to see if you find any more random ports/forks
check for updates https://github.com/smarnach/pyexiftool/pulls
check for updates on elodie https://github.com/jmathai/elodie/commits/master/elodie/external/pyexiftool.py
check for new open issues https://github.com/smarnach/pyexiftool/issues?q=is%3Aissue+is%3Aopen

55 changes: 55 additions & 0 deletions COMPATIBILITY.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
PyExifTool does not guarantee source-level compatibility from one release to the next.

That said, efforts will be made to provide well-documented API-level compatibility,
and if there are major API changes, migration documentation will be provided, when
possible.

----

v0.1.x - v0.2.0 = smarnach code, API compatible
v0.2.1 - v0.4.13 = code with all PRs, a superset of functionality on Exiftool class
v0.5.0 - = not API compatible with the v0.4.x series. See comments below:


----
API changes between v0.4.x and v0.5.0:

PYTHON CHANGE: Old: Python 2.6 supported. New: Python 3.6+ required

CHANGED: Exiftool constructor:
RENAME: "executable_" parameter to "executable"
DEFAULT BEHAVIOR: "common_args" defaults to ["-G", "-n"] instead of None. Old behavior set -G and -n if "common_args" is None. New behavior "common_args" = [] if common_args is None.
DEFAULT: Old: "win_shell" defaults to True. New: "win_shell" defaults to False.
NEW: "encoding" parameter
NEW: "logger" parameter

NEW PROPERTY GET/SET: a lot of properties were added to do get/set validation, and parameters can be changed outside of the constructor.

METHOD RENAME: starting the process was renamed from "start" to "run"

MINIMUM TOOL VERSION: exiftool command line utility minimum requirements. Old: 8.60. New: 12.15

ENCODING CHANGE: execute() and execute_json() no longer take bytes, but is guided by the encoding set in constructor/property

ERROR CHANGE: execute_json() when no json was not returned (such as a set metadata operation) => Old: raised an error. New: returns custom ExifToolException

FEATURE REMOVAL: execute_json() no longer detects the '-w' flag being passed used in common_args.
If a user uses this flag, expect no output.
(detection in common_args was clunky anyways because -w can be passed as a per-run param for the same effect)


all methods other than execute() and execute_json() moved to ExifToolHelper or ExifToolAlpha class.

ExifToolHelper adds methods:
get_metadata()
get_tags()

NEW CONVENTION: all methods take "files" first, "tags" second (if needed) and "params" last


ExifToolAlpha adds all remaining methods in an alpha-quality way

NOTE: ExifToolAlpha has not been updated yet to use the new convention, and the edge case code may be removed/changed at any time.
If you depend on functionality provided by ExifToolAlpha, please submit an Issue to start a discussion on cleaning up the code and moving it into ExifToolHelper
----

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
PyExifTool <http://github.com/sylikc/pyexiftool>

Copyright 2012 Sven Marnach, Kevin M (sylikc)
Copyright 2012-2014 Sven Marnach, 2019-2022 Kevin M (sylikc)

PyExifTool is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down
195 changes: 163 additions & 32 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
**********
PyExifTool
==========
**********

PyExifTool is a Python library to communicate with an instance of Phil
Harvey's excellent ExifTool_ command-line application. The library
Expand All @@ -11,70 +12,200 @@ single instance needs to be launched and can be reused for many
queries. This is much more efficient than launching a separate
process for every single query.

.. _ExifTool: http://www.sno.phy.queensu.ca/~phil/exiftool/
.. _ExifTool: https://exiftool.org/

Example Usage
=============

.. code-block:: python
:caption: Quick Sample
:linenos:

import exiftool

files = ["a.jpg", "b.png", "c.tif"]
with exiftool.ExifToolHelper() as et:
metadata = et.get_metadata(files)
for d in metadata:
print("{:20.20} {:20.20}".format(d["SourceFile"],
d["EXIF:DateTimeOriginal"]))


Getting PyExifTool
------------------
==================

PyPI
------------

Easiest: Install a version from the official `PyExifTool PyPI`_

::

python -m pip install -U pyexiftool

.. _PyExifTool PyPI: https://pypi.org/project/PyExifTool/


From Source
------------

The source code can be checked out from the github repository with

::

git clone git://github.com/sylikc/pyexiftool.git

Alternatively, you can download a tarball_.
Alternatively, you can download a tarball_.

.. _tarball: https://github.com/sylikc/pyexiftool/tarball/master

Official releases are on PyPI
Run

::

https://pypi.org/project/PyExifTool/
python setup.py install [--user|--prefix=<installation-prefix]

to automatically install this module from source.

.. _tarball: https://github.com/sylikc/pyexiftool/tarball/master

Installation
------------
PyExifTool Dependencies
=======================

Python
------

PyExifTool runs on **Python 3.6+**. (If you need Python 2.6 support,
please use version v0.4.x). PyExifTool has been tested on Windows and
Linux, and probably also runs on other Unix-like platforms.

PyExifTool runs on Python 2.6 and above, including 3.x. It has been
tested on Windows and Linux, and probably also runs on other Unix-like
platforms.
Phil Harvey's exiftool
----------------------

You need an installation of the ``exiftool`` command-line tool. The
code has been tested with version 8.60, but should work with version
8.40 or above (which was the first production version of exiftool
featuring the ``-stay_open`` option for batch mode).
For PyExifTool to function, ``exiftool`` command-line tool must exist on
the system. If ``exiftool`` is not on the ``PATH``, you can specify the full
pathname to it by using ``ExifTool(executable=<full path>)``.

PyExifTool currently only consists of a single module, so you can
simply copy or link this module to a place where Python finds it, or
you can call
PyExifTool requires a **minimum version of 12.15** (which was the first
production version of exiftool featuring the options to allow exit status
checks used in conjuction with ``-echo3`` and ``-echo4`` parameters).

(It is being slowly re-factored to a module to keep exiftool.py from
growing astronomically)
To check your ``exiftool`` version:

::

python setup.py install [--user|--prefix=<installation-prefix]
exiftool -ver

to automatically install that module.

Testing
-------------
Windows/Mac
^^^^^^^^^^^

Run tests to make sure it's functional
Windows/Mac users can download the latest version of exiftool:

::

python -m unittest -v tests/test_exiftool.py
https://exiftool.org

Linux
^^^^^

Most current Linux distributions have a package which will install ``exiftool``.
Unfortunately, some do not have the minimum required version, in which case you
will have to `build from source`_.

* Ubuntu
::

sudo apt install libimage-exiftool-perl

* CentOS/RHEL
::

yum install perl-Image-ExifTool

.. _build from source: https://exiftool.org/install.html#Unix


Documentation
-------------
=============

The documentation is available at `sylikc.github.io`_.
It is slightly outdated at the moment but will be improved as the
project moves forward

::

http://sylikc.github.io/pyexiftool/

.. _sylikc.github.io: http://sylikc.github.io/pyexiftool/


Package Structure
-----------------

PyExifTool consists of a few modules, each with increasingly more features.

The base ``ExifTool`` class is the most rudimentary, and each successive class
inherits and adds functionality.

* ``ExifTool`` is the base class with functionality which will not likely change.
It contains the core features with no extra fluff. The API is considered stable
and should not change much with new versions.

* ``ExifToolHelper`` adds the most commonly used functionality. It overloads
some functions to turn common errors into warnings or makes checks to make
``ExifTool`` easier to use. More methods may be added or slight tweaks may
come with new versions.

* ``ExifToolAlpha`` includes some of the community functionality that contributors
added for edge use cases. It is *not* up to the rigorous testing standard of both
``ExifTool`` or ``ExifToolHelper``. There may be old or defunct code at any time.
This is the least polished of the classes and functionality/API may be
changed/added/removed at any time.


Brief History
=============

PyExifTool was originally developed by `Sven Marnach`_ in 2012 to answer a
stackoverflow question `Call exiftool from a python script?`_. Over time,
Sven refined the code, added tests, documentation, and a slew of improvements.
While PyExifTool gained popularity, Sven `never intended to maintain it`_ as
an active project. The `original repository`_ was last updated in 2014.

In early 2019, `Martin Čarnogurský`_ created a `PyPI release`_ from the
2014 code. Coincidentally in mid 2019, `Kevin M (sylikc)`_ forked the original
repository and started merging PR and issues which were reported on Sven's
issues/PR page.

In late 2019 and early 2020 there was a discussion started to
`Provide visibility for an active fork`_. There was a conversation to
transfer ownership of the original repository, have a coordinated plan to
communicate to PyExifTool users, amongst other things, but it never materialized.

Kevin M (sylikc) made the first release to PyPI repository in early 2021.
At the same time, discussions were starting revolving around
`Deprecating Python 2.x compatibility`_ and `refactoring the code and classes`_.

The latest version is the result of all of those discussions, designs,
and development. Special thanks to the community contributions, especially
`Jan Philip Göpfert`_, `Seth P`_, and `Kolen Cheung`_.

The documentation is available at
http://sylikc.github.io/pyexiftool/.
.. _Sven Marnach: https://github.com/smarnach/pyexiftool
.. _Call exiftool from a python script?: https://stackoverflow.com/questions/10075115/call-exiftool-from-a-python-script/10075210#10075210
.. _never intended to maintain it: https://github.com/smarnach/pyexiftool/pull/31#issuecomment-569238073
.. _original repository: https://github.com/smarnach/pyexiftool
.. _Martin Čarnogurský: https://github.com/RootLUG
.. _PyPI release: https://pypi.org/project/PyExifTool/0.1.1/#history
.. _Kevin M (sylikc): https://github.com/sylikc
.. _Provide visibility for an active fork: https://github.com/smarnach/pyexiftool/pull/31
.. _Deprecating Python 2.x compatibility: https://github.com/sylikc/pyexiftool/discussions/9
.. _refactoring the code and classes: https://github.com/sylikc/pyexiftool/discussions/10
.. _Jan Philip Göpfert: https://github.com/jangop
.. _Seth P: https://github.com/csparker247
.. _Kolen Cheung: https://github.com/ickc

Licence
-------
=======

PyExifTool is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -85,4 +216,4 @@ PyExifTool is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See COPYING.GPL or COPYING.BSD for more details.
See ``LICENSE`` for more details.
Loading