Psycojoker / prosopopee

a static website generator to make beautiful customizable pictures galleries that tell a story
http://prosopopee.readthedocs.org
GNU General Public License v3.0
318 stars 55 forks source link

autogen: UnboundLocalError: local variable 'datetime' referenced before assignment #112

Closed gangelop closed 3 years ago

gangelop commented 3 years ago

version 1.0.1 On running prosopopee autogen -d $somedir it fails with:

Traceback (most recent call last):
  File "/bin/prosopopee", line 33, in <module>
    sys.exit(load_entry_point('prosopopee==1.0.1', 'console_scripts', 'prosopopee')())
  File "/usr/lib/python3.8/site-packages/prosopopee/prosopopee.py", line 621, in main
    autogen(arguments['<folder>'], arguments['--force'])
  File "/usr/lib/python3.8/site-packages/prosopopee/autogen.py", line 81, in autogen
    build_template(folder, force)
  File "/usr/lib/python3.8/site-packages/prosopopee/autogen.py", line 68, in build_template
    files=sorted(files_grabbed, key=get_exif)
  File "/usr/lib/python3.8/site-packages/prosopopee/autogen.py", line 48, in get_exif
    return datetime
UnboundLocalError: local variable 'datetime' referenced before assignment

This is the offending function. Clearly there is one case where datetime does not get set.

def get_exif(filename):
    exif_data = {}
    exif = Image.open(filename)._getexif()
    if exif is not None:
        for (tag, value) in exif.items():
            decoded = TAGS.get(tag, tag)
            exif_data[decoded] = value
        if 'DateTime' in exif_data:
            datetime = exif_data['DateTime']
    else:
        datetime = strftime("%Y:%m:%d %H:%M:00", gmtime(os.path.getmtime(filename)))
    return datetime

I can't look into it further right now. I might later.

gangelop commented 3 years ago

This would fix the bug but there's got to be a more elegant way to write it.

def get_exif(filename):
    exif_data = {}
    exif = Image.open(filename)._getexif()
    if exif is not None:
        for (tag, value) in exif.items():
            decoded = TAGS.get(tag, tag)
            exif_data[decoded] = value
        if 'DateTime' in exif_data:
            datetime = exif_data['DateTime']
        else:
            datetime = strftime("%Y:%m:%d %H:%M:00", gmtime(os.path.getmtime(filename)))
    else:
        datetime = strftime("%Y:%m:%d %H:%M:00", gmtime(os.path.getmtime(filename)))
    return datetime
gangelop commented 3 years ago

of course there was a more elegant solution. We first attempt to populate the exif_data and then if it's populated we use it else we use getmtime so it's always one or the other. No error here because exif_data is already initialized as {}.

def get_exif(filename):
    exif_data = {}
    exif = Image.open(filename)._getexif()
    if exif is not None:
        for (tag, value) in exif.items():
            decoded = TAGS.get(tag, tag)
            exif_data[decoded] = value
    if 'DateTime' in exif_data:
        datetime = exif_data['DateTime']
    else:
        datetime = strftime("%Y:%m:%d %H:%M:00", gmtime(os.path.getmtime(filename)))
    return datetime