You are not logged in.

#1 2009-07-10 16:40:30

MONODA
Member
Registered: 2008-02-09
Posts: 256

walk() behaving weirdly in python

I am making a script which manipulates ID3 tags. I want a certain function to be used on every file in a directory recursively. I have written the script but it is not behaving like I would expect in some cases.

If I give it exec perms and put it in /usr/bin and run 'script.py', the walk function doesnt seem to do its job properly and no files are passed to my function at all. If I try to run the script (which is in my cwd) in a directory filled with other directories, only one of the folders gets passed to my function. I don't think you will understand what I mean until you try the script. I have verified that all the parts work when run independently but they dont work well as a script...
Oh an btw I am using mutagen which you can get from http://code.google.com/p/mutagen/

#!/usr/bin/python

import mutagen.oggvorbis, mutagen.mp3, os, sys, re

user_input = raw_input("Please enter a file path.\n")

def rmtrcknum(trck):
    fileogg = re.compile(".ogg$")
    filemp3 = re.compile(".mp3$")
    pattern = re.compile("^\d+ - ")
    if fileogg.search(trck) == None:
        if filemp3.search(trck) == None:
            pass
        else:
            track = mutagen.mp3.EasyMP3(trck)
            track['title'] = pattern.sub("", track['title'][0])
            print track.pprint()
            track.save()
            os.rename(trck, os.path.abspath(os.path.dirname(trck)) + '/' + track['title'][0] + '.mp3')
    else:
        track = mutagen.oggvorbis.Open(trck)
        track['title'] = pattern.sub("", track['title'][0])
        print track.pprint()
        track.save()
        os.rename(trck, os.path.abspath(os.path.dirname(trck)) + '/' + track['title'][0] + '.ogg')

if __name__ == "__main__":
    print os.getcwd()
    for root, dir, files in os.walk(os.path.abspath(os.path.dirname(sys.argv[0]))):
        filelist = [ os.path.join(root,fi) for fi in files ]
    if user_input == '':
        for track in filelist:
            rmtrcknum(track)
    else:
        rmtrcknum(user_input)

Any ideas?

Last edited by MONODA (2009-07-10 16:44:53)

Offline

#2 2009-07-10 16:45:57

MONODA
Member
Registered: 2008-02-09
Posts: 256

Re: walk() behaving weirdly in python

ARGH! sorry I was broswing the screenshots forums and accidentily put this here could someone move it?

Offline

#3 2009-07-10 18:44:32

BetterLeftUnsaid
Member
From: My Happy Place
Registered: 2007-11-04
Posts: 78

Re: walk() behaving weirdly in python

 for root, dir, files in os.walk(os.path.abspath(os.path.dirname(sys.argv[0]))):
        filelist = [ os.path.join(root,fi) for fi in files ]

The problem seems to be here, as for every new directory, your filelist gets overwritten to only include the files in that directory.  Since this for loop does nothing else, filelist is going to end up being a list of files in whatever the last directory given by walk() is.  To fix this, you just need to call rmtrcknum() before filelist changes, which can be done simply by indenting the rest of the statements:

for root, dir, files in os.walk(os.path.abspath(os.path.dirname(sys.argv[0]))):
    filelist = [ os.path.join(root,fi) for fi in files ]
    if user_input == '':
        for track in filelist:
            rmtrcknum(track)
    else:
        rmtrcknum(user_input)

Last edited by BetterLeftUnsaid (2009-07-10 18:44:50)

Offline

#4 2009-07-10 19:49:13

MONODA
Member
Registered: 2008-02-09
Posts: 256

Re: walk() behaving weirdly in python

That makes sense. Thanks a lot. I try that as soon as I get home!

Offline

#5 2009-07-10 23:39:24

iphitus
Forum Fellow
From: Melbourne, Australia
Registered: 2004-10-09
Posts: 4,927

Re: walk() behaving weirdly in python

You're using sys.argv[0].

iphitus(~)$ cat test.py 
#! /usr/bin/python
import sys
print sys.argv
iphitus(~)$ ./test.py one two
['./test.py', 'one', 'two']
iphitus(~)$ python test.py one two
['test.py', 'one', 'two']

Offline

#6 2009-07-11 05:44:05

MONODA
Member
Registered: 2008-02-09
Posts: 256

Re: walk() behaving weirdly in python

@iphitis: Sorry but I really don't understand what you're saying. I don't really understand what sys.argv is but I've seen other scripts use it so I tried it.

So now recursion works but I can't run the script when it is in a different working directory than mine.

I am also getting this error:

Traceback (most recent call last):
  File "rmtracknum.py", line 33, in <module>
    rmtrcknum(track)
  File "rmtracknum.py", line 16, in rmtrcknum
    track['title'] = pattern.sub("", track['title'][0])
  File "/usr/lib/python2.6/site-packages/mutagen/__init__.py", line 85, in __getitem__
    if self.tags is None: raise KeyError, key
KeyError: 'title'

which I don't completely understand.

EDIT: Nevermind, I got it to work thanks a lot for your help. I just needed to add a try: except:
EDIT2: the only thing left for me to do is to be able to make the script run properly when I am not in the directory that it is located it.

Last edited by MONODA (2009-07-11 06:12:33)

Offline

#7 2009-07-11 09:44:30

iphitus
Forum Fellow
From: Melbourne, Australia
Registered: 2004-10-09
Posts: 4,927

Re: walk() behaving weirdly in python

nevermind what I said, I misread the code. Thats what I get for posting first thing in the morning.

Last edited by iphitus (2009-07-11 09:46:42)

Offline

#8 2009-07-11 19:03:24

BetterLeftUnsaid
Member
From: My Happy Place
Registered: 2007-11-04
Posts: 78

Re: walk() behaving weirdly in python

MONODA wrote:

the only thing left for me to do is to be able to make the script run properly when I am not in the directory that it is located it.

Are you wanting the script to run through the files of the current directory?  If so, the following should work:

for root, dir, files in os.walk(os.getcwd()):

The loop using sys.argv will make the script only loop through the directory that the script is located in instead of the user's current directory.

Offline

#9 2009-07-11 22:15:10

MONODA
Member
Registered: 2008-02-09
Posts: 256

Re: walk() behaving weirdly in python

Thanks, thats what I did and now it works.

Offline

Board footer

Powered by FluxBB