2013-12-16 66 views
1

我正在寫一個程序,從FLAC中提取元數據並批量重命名它們。爲此,我使用了py庫。Python - py.path.new unicode error

這裏是我的代碼:

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

# This program takes the information from FLAC metadata to rename the files 
# according to various naming paterns. 

""" 
rename-flac takes the information from FLAC metadata to batch rename 
the files according to various naming paterns. 

Usage: 
    rename-flac.py (-s | -v) <directory> 
    rename-flac.py (-h | --help) 
    rename-flac.py --version 

Options: 
    -h --help  Show the help screen 
    -- version  Outputs version information and exits 
    -s    Define album as single artist 
    -v    Define album as various artist 

""" 
from docopt import docopt 


import subprocess 
import sys 
import os 

from py.path import local 


# Dependency check 
programlist = ["flac", "python-py", "python-docopt"] 
for program in programlist: 
    pipe = subprocess.Popen(
     ["dpkg", "-l", program], stdout=subprocess.PIPE) 
    dependency, error = pipe.communicate() 
    if pipe.returncode: 
     print """ 
     %s is not installed: this program won't run correctly. 
     To instal %s, run: aptitude install %s 
     """ % (program, program, program) 
     sys.exit() 
    else: 
     pass 


# Defining the function that fetches metadata and formats it 
def metadata(filename): 
    filename = str(filename).decode("utf-8") 

    pipe = subprocess.Popen(
     ["metaflac", "--show-tag=tracknumber", filename], 
     stdout=subprocess.PIPE) 
    tracknumber, error = pipe.communicate() 
    tracknumber = tracknumber.decode("utf-8") 
    tracknumber = tracknumber.replace("tracknumber=", "") 
    tracknumber = tracknumber.replace("TRACKNUMBER=", "") 
    tracknumber = tracknumber.rstrip() # Remove whitespaces 
    if int(tracknumber) < 10: 
     if "0" in tracknumber: 
      pass 
     else: 
      tracknumber = "0" + tracknumber 
    else: 
     pass 

    pipe = subprocess.Popen(
     ["metaflac", "--show-tag=title", filename], 
     stdout=subprocess.PIPE) 
    title, error = pipe.communicate() 
    title = title.decode("utf-8") 
    title = title.replace("TITLE=", "") 
    title = title.replace("title=", "") 
    title = title.rstrip() 

    pipe = subprocess.Popen(
     ["metaflac", "--show-tag=artist", filename], 
     stdout=subprocess.PIPE) 
    artist, error = pipe.communicate() 
    artist = artist.decode("utf-8") 
    artist = artist.replace("ARTIST=", "") 
    artist = artist.replace("artist=", "") 
    artist = artist.rstrip() 

    return tracknumber, title, artist 


# Defining function that renames the files 
def rename(root): 
    if output == str(filename.purebasename).decode("utf-8"): 
     print "%s is already named correctly\n" % (title) 
    else: 
     filename.rename(filename.new(purebasename=output)) 

# Importing command line arguments 
args = docopt(__doc__, version="rename-flac 0.5") 
for option, value in args.iteritems(): 
    global root, choice 

    if option == "<directory>": 
     root = local(value) 

    elif option == "-s" and value == True: 
     choice = 1 

    elif option == "-v" and value == True: 
     choice = 2 

    else: 
     pass 

# 1 - Single artist 
# File naming partern: TRACKNUMBER - TITLE.flac 
if choice == 1: 
    for filename in root.visit(fil="*.flac", rec=True): 
     tracknumber, title, artist = metadata(filename) 
     output = "%s - %s" % (tracknumber, title) 
     rename(root) 
    print "Files renamed" 
else: 
    pass 

# 2 - Various artists 
# File naming pattern: TRACKNUMBER - ARTIST - TITLE.flac 
if choice == 2: 
    for filename in root.visit(fil="*.flac", rec=True): 
     tracknumber, title, artist = metadata(filename) 
     output = "%s - %s - %s" % (tracknumber, artist, title) 
     rename(root) 
    print "Files renamed" 
else: 
    pass 

我的代碼運行正常時filenameutf-8人物,但當路徑filename具有utf-8字符它收到此錯誤信息:

Traceback (most recent call last): 
    File "/media/Main/Programmes/Rename_FLAC/rename-flac.py", line 122, in <module> 
    rename(root) 
    File "/media/Main/Programmes/Rename_FLAC/rename-flac.py", line 97, in rename 
    filename.rename(filename.new(purebasename=output)) 
    File "/usr/lib/python2.7/dist-packages/py/_path/local.py", line 273, in new 
    "%(dirname)s%(sep)s%(basename)s" % kw) 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 28: ordinal not in range(128) 

這可能對於更有經驗的程序員來說似乎是顯而易見的,但我一直試圖現在解決這個錯誤幾個小時...

+0

@ r3mus不,我的終端是UTF-8 – baldurmen

回答

0

這就是問題所在:

filename.rename(filename.new(purebasename=output))墜毀是因爲output是unicode混亂。

output通過加入tracknumber,artisttitle創建。在元數據(文件名)中,我用string = string.decode("utf-8")將它們重新編碼爲unicode,但它們已經在unicode中,導致output被混亂和崩潰。

所以我刪除string = string.decode("utf-8")它的工作原理。

yay。