Giter VIP home page Giter VIP logo

pyexiftool's Introduction

PyExifTool

PyExifTool is a Python library to communicate with an instance of Phil Harvey's excellent ExifTool command-line application. The library provides the class exiftool.ExifTool that runs the command-line tool in batch mode and features methods to send commands to that program, including methods to extract meta-information from one or more image files. Since exiftool is run in batch mode, only a 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.

Getting PyExifTool

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

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

Alternatively, you can download a tarball. There haven't been any releases yet.

Installation

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.

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).

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

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

to automatically install that module.

Documentation

The documentation is available at http://smarnach.github.com/pyexiftool/.

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 the Free Software Foundation, either version 3 of the licence, or (at your option) any later version, or the BSD licence.

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.

pyexiftool's People

Contributors

smarnach avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyexiftool's Issues

pyexiftool resulting in OSError: [Errno 8] Exec format error

i encountered the following error :

Traceback (most recent call last):
  File "yeah.py", line 21, in <module>
    with exiftool.ExifTool("/usr/local/lib/python2.7/dist-packages/exiftool.py") as et:
  File "/usr/local/lib/python2.7/dist-packages/exiftool.py", line 191, in __enter__
    self.start()
  File "/usr/local/lib/python2.7/dist-packages/exiftool.py", line 174, in start
    stderr=devnull)
  File "/usr/lib/python2.7/subprocess.py", line 394, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1047, in _execute_child
    raise child_exception
OSError: [Errno 8] Exec format error

the way i got around this was by modifying start()

def start(self):
     """Start an ``exiftool`` process in batch mode for this instance.

     This method will issue a ``UserWarning`` if the subprocess is
     already running.  The process is started with the ``-G`` and
     ``-n`` as common arguments, which are automatically included
     in every command you run with :py:meth:`execute()`.
     """
     if self.running:
         warnings.warn("ExifTool already running; doing nothing.")
         return
     with open(os.devnull, "w") as devnull:
         self._process = subprocess.Popen(
             [self.executable, "-stay_open", "True",  "-@", "-",
              "-common_args", "-G", "-n"],
             stdin=subprocess.PIPE, stdout=subprocess.PIPE,
             stderr=devnull,shell=True)
     self.running = True

see https://askubuntu.com/questions/801493/python-subprocess-call-not-working-as-expected

Functions to set/modify tags

Hi smarnach

Like the concept of your wrapper - simple, but effective! And works great for reading tags.

Writing tags is possible via execute, but the parameters for this have to be constructed by hand. I thought of a function like set_tags_batch (and derivatives). Might start writing some. Not sure what to do with errors though.

Cheers, Leo

Dedicated method(s) for modification of keywords tag

The keywords tag contains a list of keywords. Adding and removing keywords are common operations on this tag supported by exiftool's command line interface. So we should implement methods for this in the wrapper.

Looking good

Want to merge your changes into the main repo?

Add logging facilities

We should add logging to help with debugging. Since error handling is non-existent, this has even higher importance than usual. Thanks to Leo Broska for the suggestion.

Getting help to install and run pyexiftool?

Dear Author,

I am using the Anaconda distribution of Python and did not manage to run your tool to access the exiftools functions from within Python. Would it be possible to get some assistance?

Thanks for your efforts,

René

Inconsistent use of tab and space broke test on project relying on Sweepatic-PyExifTool-0.2

Sweepatic-PyExifTool-0.2 use inconsistent use of tab and space, that why on project relying on test doesn't work correctly with pytest on python 3.5

    import exiftool
E     File "/home/XXX/Public/preview-generator/venv/lib/python3.5/site-packages/exiftool.py", line 228
E       for i in inputready:
E                          ^
E   TabError: inconsistent use of tabs and spaces in indentation

There is already a fix in a github fork of the project : playsignage@69159f7

OSError: [WinError 10038] An operation was attempted on something that is not a socket

When I run the test_exiftool.py

ERROR: test_get_metadata (main.TestExifTool)

Traceback (most recent call last):
File "C:/Users/af3bd/Downloads/pyexiftool-master/pyexiftool-master/test/test_exiftool.py", line 67, in test_get_metadata
actual_data = self.et.get_metadata_batch(source_files)
File "C:\ProgramData\Anaconda3\lib\site-packages\exiftool.py", line 264, in get_metadata_batch
return self.execute_json(*filenames)
File "C:\ProgramData\Anaconda3\lib\site-packages\exiftool.py", line 256, in execute_json
return json.loads(self.execute(b"-j", *params).decode("utf-8"))
File "C:\ProgramData\Anaconda3\lib\site-packages\exiftool.py", line 227, in execute
inputready,outputready,exceptready = select.select([fd],[],[])
OSError: [WinError 10038] An operation was attempted on something that is not a socket


Ran 4 tests in 1.850s

FAILED (errors=1)

Could any one help me with this error? Thanks.

Allow to pass additional options to exiftool

It would be very useful to allow pass additional parameters to exiftool. For example, currently if photos contains user-defined or simply unknown tags it is impossible to get this tags via pyexiftool get_metadata() method because this tags only extracted when exiftool is runned with option "-u"

writing to to Exif header using the execute() method

My goal is to write data into the Exif-header of an image.
Looking over a post from 2015 link on how to use Exiftool to write to the Exif header. I gave it a try:

import exiftool
fileno=r'DSC00001.JPG
with exiftool.ExifTool() as et:
    et.execute("EXIF:GPSLongitude=100",fileno)
    et.execute("EXIF:GPSLatitude=100",fileno)

In response, I got the following error:

TypeError: sequence item 0: expected a bytes-like object, str found

Then as specified in the documentation, execute takes byte commands, so I bites, so I tried that too:

with exiftool.ExifTool() as et:
   et.execute(bytes("EXIF:GPSLongitude=100", 'utf-8'),fileno)
   et.execute(bytes("EXIF:GPSLatitude=50",'utf-8'),fileno)

But still got the same error :

TypeError: sequence item 1: expected a bytes-like object, str found

I am not sure what am I doing wrong, and if Exiftool can write to file.
Thanks for the help. This question was also posted on StackOverflow here

Set GPS coordinates

This is a nice wrapper but is there a way to pass GPS coordinates for exiftool to set them?

How to write yaw,pitch,roll information to an image?

I want to write yaw pitch roll of the image ,but don't know how to do,the following can't work

import exiftool

img_name = 'sam.jpg'

with exiftool.ExifTool() as et:
    et.execute("-Yaw=21.123\n-Pitch=10.101\n-Roll=-7.252", img_name)

TypeError: a bytes-like object is required, not 'str'

I am trying to do something super simple. Well that I thought was simple. I spent like 20 min writing the code and about 2 hours trying to figure out why it doesn't work...

I keep getting a typeError from subprocess called from the exiftool start(). I am sure I am doing something wrong but I cant figure it out. I thought i would post here on the very slim chance this is a bug and not my fault.

"""
Used to take pictures seperated into folders based on date like year/month/photo.jpg, and 
change the create date of photo to the year and month from the folder names.

The script assumes that exiftool.exe and script are in the same directory. year folders are 
in same dir as well.
"""

import os
from glob import glob
import exiftool

class collection:
    def __init__(self):
        self.dateFile = []
        self.fileList = {}
        self.paths = glob('**/**')
        self.curDir = os.getcwd()
        self.exifTool = os.path.join(self.curDir.encode(), 'exiftool.exe'.encode())

    def setVariables(self):
        for path in self.paths:
            globPath = os.path.join(path, '*.*')
            picturPath = glob(globPath)
            pictures = []
            for pic in picturPath:
                pictures.append(os.path.join(self.curDir, pic))
            date = str.replace(path, '\\', ':') + ':01 00:01:01'
            self.fileList = {'date':date, 'pictures':pictures}
            self.dateFile.append(self.fileList)

class changeDate:
    def __init__(self, collection):
        self.dateFile = collection.dateFile
        self.exifTool = exiftool.fsencode(collection.exifTool)

    def buildEXIFcommand(self):
        for filelist in self.dateFile:
            date = filelist['date']
            for picfile in filelist['pictures']:
                modDate = '"' + '-FileCreateDate=' + date + '"'
                modDate.encode()
                picfile = exiftool.fsencode(picfile)
                self.exifChange(modDate, picfile)

    def exifChange(self, modDate, picfile):
        with exiftool.ExifTool(self.exifTool) as et:
            et.execute(modDate, picfile)

if __name__ == "__main__":
    Collection = collection()
    Collection.setVariables()
    ChangeDate = changeDate(Collection)
    ChangeDate.buildEXIFcommand()

Traceback (most recent call last):
  File "c:\Users\trevo\.vscode\extensions\ms-python.python-2019.10.44104\pythonFiles\ptvsd_launcher.py", line 43, in <module>
    main(ptvsdArgs)
  File "c:\Users\trevo\.vscode\extensions\ms-python.python-2019.10.44104\pythonFiles\lib\python\old_ptvsd\ptvsd\__main__.py", line 432, in main
    run()
  File "c:\Users\trevo\.vscode\extensions\ms-python.python-2019.10.44104\pythonFiles\lib\python\old_ptvsd\ptvsd\__main__.py", line 316, in run_file
    runpy.run_path(target, run_name='__main__')
  File "C:\Users\trevo\AppData\Local\Programs\Python\Python37-32\lib\runpy.py", line 263, in run_path
    pkg_name=pkg_name, script_name=fname)
  File "C:\Users\trevo\AppData\Local\Programs\Python\Python37-32\lib\runpy.py", line 96, in _run_module_code
    mod_name, mod_spec, pkg_name, script_name)
  File "C:\Users\trevo\AppData\Local\Programs\Python\Python37-32\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "c:\Users\trevo\OneDrive\Desktop\pics\datchange.py", line 46, in <module>
    ChangeDate.buildEXIFcommand()
  File "c:\Users\trevo\OneDrive\Desktop\pics\datchange.py", line 36, in buildEXIFcommand
    self.exifChange(modDate, picfile)
  File "c:\Users\trevo\OneDrive\Desktop\pics\datchange.py", line 39, in exifChange
    with exiftool.ExifTool(self.exifTool) as et:
  File "C:\Users\trevo\AppData\Local\Programs\Python\Python37-32\lib\site-packages\exiftool.py", line 192, in __enter__
    self.start()
  File "C:\Users\trevo\AppData\Local\Programs\Python\Python37-32\lib\site-packages\exiftool.py", line 175, in start
    stderr=devnull)
  File "C:\Users\trevo\AppData\Local\Programs\Python\Python37-32\lib\subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "C:\Users\trevo\AppData\Local\Programs\Python\Python37-32\lib\subprocess.py", line 1119, in _execute_child
    args = list2cmdline(args)
  File "C:\Users\trevo\AppData\Local\Programs\Python\Python37-32\lib\subprocess.py", line 530, in list2cmdline
    needquote = (" " in arg) or ("\t" in arg) or not arg
TypeError: a bytes-like object is required, not 'str'

Read from BytesIO image?

Is it possible to retrieve exiftools metadata from a BytesIO object? I am trying the following, with error below.

img = Image.open('bus.jpg')
buf = io.BytesIO()
img.save(buf, 'jpeg')
imgbytes = buf.getvalue()
exif = exiftool.ExifTool.get_metadata(imgbytes)
pprint.pprint(exif)
 testexif.py
Traceback (most recent call last):
  File "C:\test\testexif.py", line 8, in <module>
    exif = exiftool.ExifTool.get_metadata(imgbytes)
TypeError: get_metadata() missing 1 required positional argument: 'filename'

Writing custom metadata tags

I would like to write custom metadata tags in a .tiff image.

The problem is that the library or exiftool program does not recognize the tags as standard format and they are not written in the metadata parameters at image. It only recognizes the 'Exposure' tag and writes as an XMP tag.
The code I am using to write is:

image = "IMG_1_2.tiff"
message_1 = "-Exposure=300"
message_2 = "-Gain=16"
exiftoolPath = os.environ.get('exiftoolpath') 
with exiftool.ExifTool(exiftoolPath) as et:
    et.execute(message_1.encode('utf8', 'ignore'), image.encode('utf8', 'ignore'))  
    et.execute(message_2.encode('utf8', 'ignore'), image.encode('utf8', 'ignore'))

The code for reading metadata:

image = "IMG_1_2.tiff"
exiftoolPath = os.environ.get('exiftoolpath')
with exiftool.ExifTool(exiftoolPath) as exift:
    metadata = exift.get_metadata(image)

Attached is the image.
Any help would be appreciated.

Thanks.

Using get_tags_batch() always includes the SourceFile field

This makes it difficult to easily serialize the output of the return values for use with CSV or the like. I did not expect this in the returned dictionary, and it's not specified in the comments. It should be at least specified in the comments, but I would also argue that it shouldn't be added to the returned data and this function should only return explicitly-requested fields.

decoding to utf-8 issues

I am using your excellent library to extract EXIF from a largish repository of images (100k+). I've encountered an encoding-related issue. Basically exiftool returns a garbage tag value and it breaks the call to decode('utf-8') in execute_json().

If I'm reading it correctly, your code assumes that whatever it reads from exiftool will capable of being decoded to utf-8 (is valid JSON). But this does not seem to always be the case:

% exiftool -s -SerialNumber -charset UTF8 P3090087.JPG
SerialNumber                    : #ທ.L.9.-.<.#K%
% exiftool -s -SerialNumber -charset UTF8 P3090087.JPG > file
% cat -v test.json 
Serial Number                   : M-O;#M-`M-:M-^W.M--M-OM-ILM-i}.9.-M-..M-vM-^PM-=M-#<.M-^QM-dG#M-%K%
% exiftool -j -SerialNumber P3090087.JPG     
[{
  "SourceFile": "P3090087.JPG",
  "SerialNumber": "?;#ທ\u0008???L?}\u001F9\u000B-?\u001E<\u0014??G#?K%"
}]

Per the exiftool author, the fix for this seems to be to add the -b (binary output) flag to the call to Popen. This way base64-encoded strings are returned, which cannot trigger a unicode decoding error. Overall encoding is pretty tricky so I thought I'd post and see if you think this is a bug. If nothing else perhaps this will be useful to someone else with a similar problem. Let me know if you'd like further diagnostics.

execute() runs but doesn't write tags

Hello, I'm using the following code to embed metadata to JPEGs:

def embed_metadata(self):
        with ExifTool(executable_=os.environ["EXIFTOOL"]) as et:
            for param in self.__metadata:
                param = param.encode(encoding="utf-8")
                dest = os.path.join(os.environ["JPG"], self.__jpg).encode(
                    encoding="utf-8"
                )
                et.execute(param, dest)

It runs fine, but nothing really happens. No tags get embedded and no jpg_original files are created, as it happened before
with an almost identical function. I have checked the tags content and the destination is built correctly. What am I missing here?

OSError when passing config file to exiftool

When I try to init exiftool with custom config-file that describes some additional user tags I get this error:

  File "/home/alex/.qgis2/python/plugins/geotagphotos/exiftool.py", line 193, in __enter__
    self.start()
  File "/home/alex/.qgis2/python/plugins/geotagphotos/exiftool.py", line 176, in start
    stderr=devnull)
  File "/usr/lib64/python2.7/subprocess.py", line 679, in __init__
    errread, errwrite)
  File "/usr/lib64/python2.7/subprocess.py", line 1249, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

Here is my simplified code:

etPath = "exiftool"
cfgFile = "/path/to/config/file"
etPath += " -config " + unicode(cfgFile)
et = exiftool.ExifTool(etPath)
with et:
  md = et.get_metadata("/path/to/photo")
  print md

Sample files:

Date Formating (-d) Appears to Be Ignored

Launching the tool in Python it appears to be ignoring the "-d" parameter for the date format and just using the internal default.

with ExifToolHelper(logger = logger) as et: result = et.execute("-verbose", "-d", "%Y%m%d-%H%M%S%%-c.%%e", "-FileName<DateTimeOriginal", sub_dir)

Verbose, Filename and the directory are all accounted for and no error is logged

DEBUG:root:ExifToolHelper.execute: IN params = ('-verbose', '-d', '%Y%m%d-%H%M%S%%-c.%%e', '-FileName<DateTimeOriginal', './import') DEBUG:root:ExifToolHelper.execute: OUT stdout = "======== ./import/20230128084030-20230127223016-REDACTED_12.jpg Setting new values from ./import/20230128084030-20230127223016-REDACTED_12.jpg './import/20230128084030-20230127223016-REDACTED_12.jpg' --> './import/2004:01:29 14:35:03' ======== ./import/20230128084030-20230127223016-REDACTED_06.jpg Setting new values from ./import/20230128084030-20230127223016-REDACTED_06.jpg './import/20230128084030-20230127223016-REDACTED_06.jpg' --> './import/2004:01:29 14:18:24'

The following seems to work just fine:

exiftool_command = ["exiftool", "-verbose", "-d", "%Y%m%d-%H%M%S%%-c.%%e", "-FileName<DateTimeOriginal", sub_dir] process = subprocess.run(exiftool_command)

Almost same issue as this but they had a missed comma between the parameters:

https://stackoverflow.com/questions/74305074/renaming-image-files-with-pyexiftool-0-5-4-exiftool-in-python

MacOS 12.6.2
Exiftool 12.52
PyExifTool 0.5.5
Python 3.10.4

Generic exiftool parameters -G and -n are hidden

The functions execute(*params) and execute_json(*params) allow to set exiftool parameters.
Unfortunately the documentation of both functions doesn't mention that two exiftool parameters are set in a generic way (with the -common_args parameter as a kind of prefix): -G and -n (see the start(self) function of the Exiftool class).
The confusing issue is: this presetting of -G overrides other settings of group families in the params of the two execute functions, like -G1 to get more granular group names of the tags. Adding -G1 to the params does not show the exiftool family 1 group names of the tags. And the why is not documented.

Use multiprocessing for further speedups

Currently pyexiftool leverages the stay_open feature of exiftool to get a speed up compared to invoking one exiftool instance for each image. What if we took the ball further and used the python multiprocessing module to invoke multiple exiftool stay_open instances and split the load between them? Here is a script that compares the "internal" batch mode of exiftool, the "external" batchmode using pyexiftool and the "multiprocessed external" batchmode using multiprocessing:

import os
import timeit
import time
import multiprocessing

import exiftool



metadatadir = r"E:\dev\exiftool\test\sampleImages\Canon" #adapt to your path
result_queue = multiprocessing.Queue(1)

def exiftool_internal_batch():
    """internal batchmode of exiftool - ET itself finds out which files to read"""
    md = os.popen(r"exiftool.exe -j %s\\*.jpg" % metadatadir).read()
    return md

def get_filelist():
    files = []
    for sample in os.listdir(metadatadir):
        files.append(os.path.join(metadatadir, sample))
    return files

def chunk_list(l, n):
    """Yield successive n-sized chunks from l."""
    result = []
    for i in xrange(0, len(l), n):
        result.append(l[i:i+n])
    return result


def exiftool_stay_open(files, mp = None):
    """external batchmode of exiftool - ET is invoked by pyexiftool using a stay_open with a filelist
        filelist - list of files to read
        mp - make function multiprocessing aware yes/no (results will be stuffed into a queue)
    """
    with exiftool.ExifTool() as et:
        metadata = et.get_metadata_batch(files)
    if mp is not None:
        result_queue.put(metadata)
    return metadata

if __name__ == '__main__':

    internal_batch_start = time.clock()
    exiftool_internal_batch()
    internal_batch_end = time.clock()
    print ("Exiftool internal batch took %s" % (internal_batch_end - internal_batch_start))

    external_batch_start = time.clock()
    files = get_filelist()
    exiftool_stay_open(files)
    external_batch_end = time.clock()
    print ("Exiftool Stay Open/External batch took %s" % (external_batch_end - external_batch_start))

    """invoke three exiftool stay_open instances at once to split the load between them"""

    mbs_start = time.clock()
    jobs = []
    files = get_filelist()
    fl_chunks = chunk_list(files, 3)

    et1 = multiprocessing.Process(target=exiftool_stay_open, args=(fl_chunks[0],True))
    et2 = multiprocessing.Process(target=exiftool_stay_open, args=(fl_chunks[1],True))
    et3 = multiprocessing.Process(target=exiftool_stay_open, args=(fl_chunks[2],True))

    jobs.append(et1)
    jobs.append(et2)
    jobs.append(et3)

    et1.start()
    et2.start()
    et3.start()

    et1.join()
    et2.join()
    et3.join()


    mbs_end = time.clock()
    print ("Exiftool multiprocessing batch took %s" % (mbs_end - mbs_start))

When I run this script on the Canon sample images of Phil Harvey's metadata repository, I get these results on my machine:

Exiftool internal batch took 14.2978597714 sec
Exiftool Stay Open/External batch took 12.7552563562 sec
Exiftool multiprocessing batch took 0.714086082069 sec

I have to admit 0,71 for multiprocessing sounds to good to be true, so there might be some error in the script. nevertheless, a previous version with two workers took 7,77 seconds, so there is quite a performance gain possible.

Do you plan to add multiprocessing functionality to pyexiftool?

missing git tag / github release

There are no git tags that result in github automatically creating a release tarball that can be used to download a specific version.
I try to package your tool for a distribution and it would be awesome if you can push release tags like 0.1.29 or something like that so the upstream release tracking and distribution packaging is easier
I think it may be in your interests 😄

Currently I'm packaging it from HEAD as custom defined version 0.1.29 (the .29 are the current amount of commits). It would be incredibly awesome if you can push a tag which is greater or equal to that version numbers so its not recognized to be an older version 😢

hope you push git tags soon,
sincerely,
anthraxx

'-CreateDate<filename' doesn't appear to work via et.execute

You can use exiftool '-CreateDate<filename' to attempt to parse the file name as a date and set that to the CreateDate tag, on the command line. However, I am running into difficulties with doing this via pyexiftool.

with exiftool.ExifToolHelper(config_file="./exiftool.config", logger = logging.getLogger()) as et:
     et.execute("-CreateDate<filename", f)

I'm seeing 1 image files updated when I print the return state but after running exiftool -time:all on that file, the date has not been updated. There are also no warnings/errors in the debug log.

INFO 2022-09-04 17:31:21,743 - Method 'run': Exiftool version '12.42' (pid 42558) launched with args '['/usr/local/bin/exiftool', '-config', './exiftool.config', '-stay_open', 'True', '-@', '-', '-common_args', '-G', '-n']'
INFO 2022-09-04 17:31:21,743 - Method 'execute': Command sent = [b'-CreateDate<filename', b'redacted/20090506121211.png', b'-echo4', b'=${status}=post694948']
DEBUG 2022-09-04 17:31:21,928 - ExifToolHelper.execute: IN  params = ('-CreateDate<filename', 'redacted/20090506121211.png')
DEBUG 2022-09-04 17:31:21,928 - ExifToolHelper.execute: OUT stdout = "1 image files updated

Could you assist? Thanks

WINERROR 10038

Hi guys i coding a chatroom with socket modul in python an i get this error.
I think you can help me.
My code is bellow

`import socket
from tkinter import *
import tkinter as tkinter
import threading
from tkinter import simpledialog
from tkinter import scrolledtext
HOST ="192.168.1.6"
PORT =5051

class Client:
def init(self, host, port):
self.sock =socket.socket(socket.AF_INET, socket.SOCK_STREAM )
self.sock.connect((host, port))
msg = tkinter.Tk()
msg.withdraw()

	self.nickname = simpledialog.askstring('Nickname', "Please choose a Nickname", parent=msg)
	self.gui_done = False
	
	self.running =True
	
	gui_thread = threading.Thread(target =self.gui_loop)
	receive_thread = threading.Thread(target = self.receive)
	
	gui_thread.start()
	receive_thread.start()
	
def gui_loop(self):
	self.win =tkinter.Tk()
	self.win.configure(bg="lightgray")
	
	self.chat_label = tkinter.Label(self.win, text="chat", bg="lightgray")
	self.chat_label.config(font=("Arial ", 12))
	self.chat_label.pack(padx=20, pady=5)
	
	
	self.chat_area= scrolledtext.ScrolledText(self.win)
	self.chat_area.pack(padx=20, pady=5)
	self.chat_area.config(state="disabled")
	
	self.msg_label = tkinter.Label(self.win, text="Message :", bg="lightgray")
	self.msg_label.config(font=("Arial" , 12))
	self.msg_label.pack(padx=20, pady=5)
	
	
	self.input_area = tkinter.Text(self.win, height=3, width=50)
	self.input_area.pack(padx=20, pady=5)

	self.send_button =tkinter.Button(self.win, text="Send", command=self.write)
	self.send_button.config(font=("Arial", 12))
	self.send_button.pack(padx=20, pady=5)
	
	self.gui_done = True

	self.win.protocol("WM_DELETE_WINDOW", self.stop)
	
	self.win.mainloop()
	
	
	
	
def write(self):
	message = f"{self.nickname}: {self.input_area.get('1.0', 'end')}"
            ####17 I get here an WINERROR 10038 I dont understand help me
	self.sock.send(message.encode('utf-8'))
            ####
	self.input_area.delete('1.0', 'end')
		
def stop(self):
	self.running= False
	self.win.destroy()
	self.sock.close()
	exit(0)	
	
def receive(self):
	while self.running:
		try:
			message = self.sock.recv(1024).decode('utf-8')
			if message =='NICK':
				self.sock.send(self.nickname.encode('utf-8'))
			else:
				if self.gui_done:
					self.text_area.config(state='normal')
					self.text_area.insert('end', message)
					self.text_area.yview('end')
					self.text_area.config(state='disabled')
		except ConnectionAbortedError :
			break
		except:
			print('Error')	
			self.sock.close()
			break

client= Client(HOST, PORT)
`

Add version information to module

It's helpful when checking dependencies programmatically or for a developer to be able to retrieve version information from the modules __version__ attribute (see PEP396).

Our use case is a check_dependencies.py script that the developer can run to verify they have all necessary packages installed and that they're the correct version.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.