2007-12-03, 22:16
  #1
Medlem
eriikhs avatar
Har nu skrivit mitt första egna program, dock så kommer funktionerna från www.diveintopython.org

Man lägger programmet i en valfri mapp på datorn, detta kan då läsa igenom alla id3-taggar i de mp3-filer som finns där och skriva ut <title> - <artist> till en fil som kommer att heta tracklist.txt. Ett exempel på vad tracklist.txt kan innehålla:

Kod:
# Tracklist.txt
# Generated by ID3TagWriter_v1.0 by eriikh

Berätta det för lina - Lillasyster
Kräkas - Lillasyster
Svin - Lillasyster
Hårdrock - Lillasyster
Nu har jag fått nog - Lillasyster
Barn utan ben - Lillasyster
Kometen - Lillasyster
Spänn hjälmen - Lillasyster
Stukaplan - Lillasyster
Varfördärför - Lillasyster

Det går jättefint att göra så här tills programmet kommer på en fil där antingen <title> eller <artist> saknas i id3. Då skrivs ingenting alls i tracklist.txt och den förblir tom. Jag vill att om <title> eller <artist> saknas så ska mp3filens namn istället skrivas ut. Har provat allt möjligt men inte lyckas lösa detta. Kan någon hjälpa mig?

Kod:
# ID3Tagwriter_1.0 by eriikh
# This text should not be removed
# Everything before "Main:" comes from www.diveintopython.org and are written by Mark Pilgrim 2001.

import os
import sys
from UserDict import UserDict

def stripnulls(data):
    "strip whitespace and nulls"
    return data.replace("\00", " ").strip()

class FileInfo(UserDict):
    "store file metadata"
    def __init__(self, filename=None):
        UserDict.__init__(self)
        self["name"] = filename
    
class MP3FileInfo(FileInfo):
    "store ID3v1.0 MP3 tags"
    tagDataMap = {"title"   : (  3,  33, stripnulls),
                  "artist"  : ( 33,  63, stripnulls)}
    
    def __parse(self, filename):
        "parse ID3v1.0 tags from MP3 file"
        self.clear()
        try:
            fsock = open(filename, "rb", 0)
            try:
                fsock.seek(-128, 2)
                tagdata = fsock.read(128)
            finally:
                fsock.close()
            if tagdata[:3] == 'TAG':
                for tag, (start, end, parseFunc) in self.tagDataMap.items():
                    self[tag] = parseFunc(tagdata[start:end])
        except IOError:
            pass

    def __setitem__(self, key, item):
        if key == "name" and item:
            self.__parse(item)
        FileInfo.__setitem__(self, key, item)

def listDirectory(directory, fileExtList):
    "get list of file info objects for files of particular extensions"
    fileList = [os.path.normcase(f) for f in os.listdir(directory)]
    fileList = [os.path.join(directory, f) for f in fileList \
                if os.path.splitext(f)[1] in fileExtList]
    def getFileInfoClass(filename, module=sys.modules[FileInfo.__module__]):
        "get file info class from filename extension"
        subclass = "%sFileInfo" % os.path.splitext(filename)[1].upper()[1:]
        return hasattr(module, subclass) and getattr(module, subclass) or FileInfo
    return [getFileInfoClass(f)(f) for f in fileList]

# Main:
if __name__ == "__main__":                      # Forsakra att programmet anvands som fristaende 
    trackfile = open("tracklist.txt", "w")
    trackfile.write("# Tracklist.txt")
    trackfile.write("\n") 
    trackfile.write("# Generated by ID3TagWriter_v1.0 by eriikh")
    trackfile.write("\n")
    trackfile.write("\n") 
    for info in listDirectory("", [".mp3"]):    # "" = leta i egen mapp
         trackfile.write(info["title"])         # Skriv ut title-tag
         trackfile.write(" - ")
         trackfile.write(info["artist"])        # Skriv ut artist-tag
         trackfile.write("\n")                  # Retur      
    trackfile.close()                           # Stang fil
    print file("tracklist.txt").read()          # Skriv ut fil i kommandofonstret
Citera
2007-12-06, 12:59
  #2
Medlem
munsårs avatar
Kan du inte lägga till ett villkor som kontrollerar att om title eller artist saknas och i sådana fall skriver ut filnamnet istället?

Vet inte riktigt om det indikeras genom att returerna NULL eller en tom sträng...någon liknande...koden är förmodligen helt felaktigt men du får en idé i varje. Men du kansk redan testat det...

Kod:
if info["title"] == NULL | info["artist"] == NULL then 
       trackfile.write(filename)             # Bör kanske strippas på filändelsen om den åker med
else       
       trackfile.write(info["title"])         # Skriv ut title-tag
       trackfile.write(" - ")
       trackfile.write(info["artist"])       # Skriv ut artist-tag
       trackfile.write("\n")                  # Retur      
end
Citera
2007-12-08, 19:42
  #3
Medlem
eriikhs avatar
Jo det funkade, om man gjorde om "filename" till global. Men den skriver ut hela sökvägen och inte bara filnamnet (som ju är det enda som är relevant.)



s = "G:\music\acdc - tnt.mp3"

Detta vill jag då plocka ut "acdc - tnt.mp3" ur.

t = s.split("\") funkar inte då den klagar på att jag inte stängt citeringstecknen?

det skulle ju funka fint om man sedan bara tog ut det sista elementet ur listan t[].
Citera
2007-12-08, 21:31
  #4
Medlem
eriikhs avatar
Fixade det själv, man var tvungen att skriva \\ när man menade \

Nästa problem:
Hur får man python att skirva åäö till en fil? Får UnicodeEncodeError som jag har nu.
Citera
2007-12-13, 03:03
  #5
Medlem
Fittsnopps avatar
Citat:
Ursprungligen postat av eriikh
Fixade det själv, man var tvungen att skriva \\ när man menade \

Nästa problem:
Hur får man python att skirva åäö till en fil? Får UnicodeEncodeError som jag har nu.
Börja programmet med:
# -*- coding: cp1252 -*-
Citera
2008-01-05, 10:01
  #6
Medlem
Annars har du diverse ID3-läsningslibs här och var. Ett jag tyckte var jädra fint när jag skrev mitt arkiveringsskript (som tog bort 50% av min musik, ...) var "id3reader".

Edit: id3reader läser ID3v2 också.

För att besvara UnicodeDecodeError, så:

Du har str i Python, strängar. "Hej" är en strängliteral som blir till ett strängobjekt. Python ser på denna som 'bara massa bytes'. Om Python någonsin måste avkoda detta görs detta automatiskt med ASCII, om du inte gör det själv då.

För att koda av "hej" med UTF-8, "hej".decode("utf-8")

All text är i någon sorts kodning, oundvikligen.
Citera

Skapa ett konto eller logga in för att kommentera

Du måste vara medlem för att kunna kommentera

Skapa ett konto

Det är enkelt att registrera ett nytt konto

Bli medlem

Logga in

Har du redan ett konto? Logga in här

Logga in