thebigmunch / audio-metadata

A library for reading and, in the future, writing audio metadata. https://audio-metadata.readthedocs.io/
https://forum.thebigmunch.me
MIT License
53 stars 11 forks source link

Can't perform operations on the files in a for loop, since file is still open #7

Closed kalmengr closed 4 years ago

kalmengr commented 4 years ago

So i was doing a for loop with os.listdir(). I couldn't perform operations on these files because they were still open from audio_metadata.open(). this is easily fixable. I'll create a PR

thebigmunch commented 4 years ago

I'm well aware that the file objects aren't closed. It's that way for a reason (which may become more relevant in the future).

What exactly was your code that you ran into trouble with?

kalmengr commented 4 years ago

My code was the following

k = 0
for f in os.listdir(base_dir):
    k+=1
    try:
        metadata = load(f"C:/Users/kal/Desktop/flac/{f}")
        title = metadata.tags.title[0]
        os.rename(f"{base_dir}{f}", f"{base_dir}{title}.flac")
        print(f"{title}: {k} out of {len(os.listdir(base_dir))}")
    except:
        continue

I think it's pretty clear what im trying to do. rename files in a folder sequentially. i wasn't able to rename the files as they were open. i add a 'with' context manager so the file closes as soon as the metadata extraction is done. Thanks for the awesome lib. it was useful.

thebigmunch commented 4 years ago

A couple quick comments on your code:

In Python, you generally shouldn't use manual counting when looping over a collection; the enumerate builtin is there for that: for k, f in enumerate(os.listdir(base_dir)):. And it's generally best to put the minimum amount of code in the try block.

As for your PR, there's another case where this could be changed in the code that would need a change as well. And a CHANGELOG entry would need to be made. But the big issue is that audio_metadata.load also accepts file-like objects that the user should manage themselves, not audio-metadata. Your change closes the file-like object in that case as well as the case of passing a string/path-like object, and it probably shouldn't. I'll have to dive into this myself to make a decision on that and implement something.

thebigmunch commented 4 years ago

Also, mostly so I don't forget it, it's possible (and part of the public API) to load through the format classes themselves, skipping the high-level API functions. This case would need to be handled. I'll probably close this specific issue later in favor of a more general issue on how to better handle file-like objects throughout audio-metadata.

thebigmunch commented 4 years ago

Give the master branch a try (pip install -U git+https://github.com/thebigmunch/audio-metadata). That should hopefully solve things.