Διαχείριση MP3/Ogg αρχείων με Python

Ανώνυμος (χωρίς επαλήθευση) | Τρί, 11/04/2008 - 16:52 | 29' | 1

Ονειρεύεστε κι εσείς την ημέρα που τα σπίτια μας θα αποκτήσουν “μαγικές” ικανότητες; Μια μέρα που, όταν θα τελειώνουμε με ένα αντικείμενο, θα μπορούμε να το ρίχνουμε σε ένα καλάθι και εκείνο να το σκανάρει και να το ....τηλεμεταφέρει αυτόματα στην κατάλληλη θέση, ώστε να είναι διαθέσιμο όταν το ξαναζητήσουμε; Δυστυχώς, αυτή η τεχνολογία μόνο στο Star Trek υπάρχει...

Σε αυτό το tutorial θα ασχοληθούμε με κάτι πιο ταπεινό: τη μουσική μας συλλογή. Το πιθανότερο είναι ότι έχετε εκατοντάδες CDs/DVDs (BlueRays;) με αρχεία μουσικής, που το καθένα έχει διαφορετικό όνομα, γραμματοσειρές, γλώσσες κλπ για τα μεταδεδομένα. Ένας χαμός δηλαδή. Ευτυχώς, η διανομή Linux που έχετε εγκαταστήσει στον υπολογιστή σας μπορεί να σας βοηθήσει να βάλετε τάξη στο χάος! Πως; Με την Python!

Η Python είναι μια πολύ εύκολη γλώσσα προγραμματισμού για να διαχειρίζεστε τη συλλογή των αρχείων σας. Μπορεί να χειριστεί ονόματα αρχείων και εντολές του Linux μέσω μιας γκάμας έτοιμων συναρτήσεων, είναι εύκολο να τρέξετε ένα εξωτερικό πρόγραμμα, έχει μια μεγάλη βιβλιοθήκη από modules για να κάνετε διάφορες δουλειές και είναι πολύ εύκολη στην εκμάθηση. Είναι ιδανική για να φτιάξετε πρωτότυπα μελλοντικών εφαρμογών, αλλά και για να φτιάξτε κανονικές, πλήρεις εφαρμογές. Η' τουλάχιστον, να γράψετε μικρά σκριπτάκια που θα κάνουν κάποιο συγκεκριμένο πράγμα.

Στόχος μας εδώ είναι να φτιάξουμε σκριπτάκια που θα βάλουν σε μια τάξη τη συλλογή των MP3/OGG αρχείων μας.

Θεωρούμε ότι τα αρχεία βρίσκονται σε ένα φάκελο 'Music', μέσα στον οποίο υπάρχουν, όπως είναι λογικό, υποφάκελοι με τους καλλιτέχνες, μετά με τα άλμπουμ και τέλος τα μεμονωμένα αρχεία μουσικής. Συνήθως, ένας νέος χρήστης έχει αρκετά προβλήματα με τα αρχεία μουσικής στο Linux. Να μερικά από αυτά (προσθέστε και τα δικά σας!):

  1. Τα ονόματα των αρχείων είναι μεγάλα και χωρίς την ίδια μορφή. Αυτό οφείλεται συνήθως στο ότι τα MP3 που αγοράζουμε έχουν ονόματα που περιλαμβάνουν: αριθμό, καλλιτέχνη, τίτλο, κλπ. Εμείς θέλουμε όλα τα ονόματα να έχουν την ίδια μορφή, χωρίς περίεργους χαρακτήρες.
  2. Κάποια αρχεία έχουν ID3v1 tags, αλλά όχι ID3v2 tags. Αυτό δεν είναι κακό, αλλά δεν μπορούμε να εκμεταλλευτούμε τις έξτρα πληροφορίες του ID3v2.
  3. Αντίθετα, κάποια άλλα έχουν ID3v2 tags, αλλά όχι ID3v1 tags! Έτσι, δεν διαβάζονται σωστά στα παλιά MP3 player (ειδικά των αυτοκινήτων).
  4. Κάποια από αυτά δεν παίζουν καθόλου. Θα ήταν καλό να είχαμε μια λίστα με τα προβληματικά αρχεία, ώστε να τα σβήσουμε ή να τα αντικαταστήσουμε...
  5. Κάποια αρχεία έχουν περίεργα formats που δεν παίζουν σε μερικές φορητές συσκευές. Θα ήταν επίσης καλό να είχαμε μια λίστα και από αυτά τα αρχεία.

Πως λοιπόν θα καταφέρουμε να λύσουμε με μιας όλα αυτά τα προβλήματα; Δεν είναι σίγουρο ότι θα τα λύσουμε όλα και με τη μία, αλλά αξίζει την προσπάθεια ειδικά αν ξέρουμε από που να ξεκινήσουμε. Βλέπετε, η Python έχει ένα στάνταρ module, το os, που προσφέρει πρόσβαση στις συνήθεις εντολές του Linux, και ιδιαιτερα όσες αφορούν στο σύστημα αρχείων. Η Python επιπλέον παίζει και σε άλλα λειτουργικά ...παραθύρια, οπότε η χρήση του os είναι διαφορετική σε κάθε πλατφόρμα, αλλά το αποτέλεσμα είναι πάντα ίδιο: θα έχουμε πρόσβαση στις εντολές του λειτουργικό με ένα ενιαίο interface. Μία από τις πιο χρήσιμες συναρτήσεις του os module είναι η walk(). Όταν της δώσετε ένα όνομα φακέλου, η walk() θα επιστρέψει μια σειρά από τιμές tuple (δείτε σχετικό πλαίσιο), που περιέχουν το όνομα του φακέλου, μια λίστα με όλους τους υποφακέλους και μια λίστα με όλα τα αρχεία. Έτσι, για να πάρουμε μια λίστα με τα ονόματα των αρχείων μας, μαζί με το πλήρες path τους, αρκεί να τρέξουμε την walk() στο φάκελο που θέλουμε και να επεξεργαστούμε τα αποτελέσματα με ένα βρόχο for:

import os
topdir=”/usr/share/music/”
walklist = os.walk(topdir)
for dirs in walklist:
if(dirs[2]):
for file in dirs[2]:
// κάνε κάτι
print os.path.join(dirs[0],file)
else:
for entry in dirs[1]:
print dirs[1]

Στην 1η γραμμή εισάγουμε το os module, και μετά ορίζουμε το topdir (τον φάκελο απ' όπου θα ξεκινήσουμε). Η κλήση της walk() παράγει ένα αντικείμενο που αποθηκεύουμε στην μεταβλητή walklist. Έπειτα, με τη for, χρησιμοποιούμε τον γνωστό τρόπο της Python για να περιηγηθούμε σε μια λίστα εξετάζοντας κάθε στοιχείο της μεμονωμένα. Να έχετε υπόψην ότι τα δεδομένα της walklist είναι κάπως έτσι:

(‘/usr/share/music/Blonde_Redhead’, [‘1980 Forward’, ‘23’], [])
(‘/usr/share/music/Blonde_RedHead/1980 Forward’, [], [‘18-Magic Mountain.mp3’])
(‘/usr/share/music/Blonde_Redhead/23’, [], [‘10-My Impure Hair. mp3’,’1-23.mp3’, ‘7-Publisher.mp3’, ‘3-The Dress.mp3’, ‘6-Silently. mp3’])

Σε κάθε βήμα της for, λοιπόν, εξετάζουμε μία τέτοια γραμμή. Εάν υπάρχει μια εγγραφή αρχείου (μπορεί να είναι ένα ή περισσότερα) θέλουμε να κάνει κάτι. Η if ελέγχει αν υπάρχει κάποιο αρχείο, και αν αληθεύει (το dirs[2] δεν είναι κενό), εκτελούμε μια νέα for, αυτή τη φορά για τα αρχεία. Προς το παρόν, δεν το βάζουμε να κάνει κάτι με τα αρχεία, οπότε του λέμε απλώς να τυπώνει τα ονόματα στην κονσόλα. Εδώ χρησιμοποιούμε μία ακόμα χρήσιμη συνάρτηση, την os.path.join(), η οποία ενώνει κομμάτια του path ώστε να είναι έγκυρα μονοπάτια στο εκάστοτε λειτουργικό. Έτσι είναι πολύ καλύτερο από το να τα ενώναμε με μια /, γιατί αυτό θα ίσχυε μόνο για το Linux.

Έχουμε βάλει επίσης και μια δήλωσε else, σε περίπτωση που θέλουμε να κάνουμε κάτι στους ίδιους τους φακέλους (π.χ. να τους μετονομάσουμε). Για την ώρα, τρέξτε το σκριπτάκι για να δείτε αν δουλεύει. Σιγουρευτείτε ότι στην topdir θα βάλετε ένα φάκελο που περιέχει MP3 αρχεία.

Έλεγχος format

Ας προσθέσουμε τώρα λίγη λειτουργικότητα στο σκριπτάκι μας. Πριν ασχοληθούμε με τα ίδια τα αρχεία, το πρώτο πράγμα που θα θέλουμε να τσεκάρουμε είναι ότι είναι όντως αρχεία μουσικής! Εννοείται ότι τα αρχεία MP3 έχουν κατάληξη .mp3 ενώ τα OGG σε .ogg. Οπότε μέσα στο βρόχο της for μπορούμε να ελέγχουμε τα αρχεία και να εντοπίζουμε άσχετα είδη. Θα μπορούσαμε να κάνουμε μια απλή σύγκριση if, αλλά επειδή μπορεί να χρειαστεί να το κάνουμε πολλές φορές είναι πιο αποδοτικό να περάσουμε την κατάληξη του αρχείου σε μια μεταβλητή και μετά να κάνουμε τη σύγκριση. Για να “πάρουμε” την κατάληξη, θα χρειαστούμε τα Python slices. Πρόκειται για ένα εύκολο και γρήγορο τρόπο χειρισμού strings και άλλων ειδών μεταβλητών (δείτε το σχετικό πλαίσιο). Μόλις πάρουμε την κατάληξη, θα ελέγξουμε για μερικά συνήθη formats π.χ. ‘.wma’ και .’ogg’, μια και μπορεί να θέλουμε να κάνουμε κάτι και με αυτά. Στην Python δεν υπάρχει ‘switch ...case’ δομή, οπότε θα χρησιμοποιήσουμε μια αλληλουχία από if, elif (else if) και else δηλώσεις. Το # στην Python δηλώνει πάντα ότι η γραμμή είναι σχόλιο όχι κώδικας. Να πως θα είναι τώρα η βασική μας λούπα:

for file in dirs[2]:
fullpath = os.path.join(dirs[0],file)
extension = file[-4:]
if (extension!=’.mp3’):
#δεν είναι MP3; Έλεγξε για άλλες καταλήξεις.
if (extension ==’.wma’):
wmalist.append(fullpath)
elif (extension ==’.ogg’):
ogglist.append(fullpath)
else:
unknownlist.append(fullpath)
else:
# είναι MP3
# Κάνε κάτι
print fullpath

Είναι προφανές ότι πρέπει να ορίσουμε τρεις νέες μεταβλητές στον κυρίως κώδικα (wmalist, ogglist, unknownlist). Μπορείτε αν θέλετε να επεκτείνετε τον κώδικα είτε για να κάνει κάτι με αυτά τα αρχεία είτε για να ψάχνει και για άλλα είδη. Για να είμαστε τυπικοί, κρατάμε και μια λίστα με άγνωστα είδη αρχείων, όπου μπορούμε να εντοπίσουμε κάτι που μας ξέφυγε.

Είναι καιρός τώρα να κάνουμε κάτι με τα MP3 αρχεία μας. Οι προδιαγραφές του ID3v1 είναι απλές: απλώς προσθέτει στο τέλος του αρχείου 128 bytes δεδομένων, οπότε είναι σχετικά εύκολο να γράψουμε έναν parser για να μαζεύει αυτά τα δεδομένα και να κάνει κάτι. Αντίθετα, το ID3v2 είναι μια διαφορετική ιστορία. Οι πληροφορίες του ID3v2 αποθηκεύονται στην αρχή κάθε αρχείου, με μια δομή frame με μεταβλητό μήκος και, για να πούμε την αλήθεια, θα χρειαζόταν πολύς κόπος, δυσανάλογα με τον σκοπό του μικρού μας script. Γι' αυτό θα κάνουμε ότι θα έκανε κάθε καλός προγραμματιστής: θα “κλέψουμε”! Υπάρχουν ήδη αρκετά modules της Python για ανάγνωση δεδομένων από MP3, γι' αυτό θα αξιοποιήσουμε ένα από αυτά. Το EyeD3 είναι από τα καλύτερα, μια και έχει ότι χρειαζόμαστε. Θα το βρείτε στο http://eyed3.nicfit.net.

Αυτό το module κάνει ένα σωρό μαγικά, τα περισσότερα από τα οποία δεν μας απασχολούν. Θα βρείτε περισσότερες πληροφορίες στο website του, αλλά για τους σκοπούς μας αρκεί να το εισάγουμε και να δούμε τις συναρτήσεις του που μας είναι χρήσιμες.

Το eyeD3 είναι πολύ απλό στη χρήση. Θα χειριζόμαστε ένα μόνο αντικείμενο, το eyeD3.Tag, που περιέχει όλη τη δομή και των ID3v1 αλλά και των ID3v2 tags. Για να το “γεμίσουμε” με δεδομένα από ένα αρχείο μουσικής, χρησιμοποιούμε την μέθοδο link() του αντικειμένου με παράμετρο το όνομα του αρχείου:


mytag=eyeD3.Tag()
mytag.link(‘/usr/share/music/Blonde_Redhead/23/1-23.mp3’)
print mytag.getArtist()
print mytag.getAlbum()
print mytag.getTrackNum()

Όταν κάνουμε τις αλλαγές μας στα tags, απλώς καλούμε τη μέθοδο tag.update() για να γράψουμε τις αλλαγές στο αρχείο. Οπότε πρέπει να αποφασίσουμε τι θα κάνουμε με τα αρχεία μας. Μια καλή αρχή είναι να γράψουμε σε σχόλια ότι ενέργειες θέλουμε και μετά να τις σπάσουμε σε μικρότερες ή, αν δεν γίνεται άλλο, να γράψουμε απευθείας τον κώδικα για κάθε ενέργεια. Να λοιπόν μια πιθανή λίστα ενεργειών:

  • Πάρε την κατάληξη του αρχείου
  • Τελειώνει σε .mp3;
  • Έλεγξε αν είναι όντως mp3
  • Διάβασε τα ID3v2 tags
  • Διάβασε τα ID3v1 tags
  • Εάν έχει μόνο ένα είδος, αντέγραψε το στο άλλο
  • Εάν δεν υπάρχουν tags, κάνε μια προειδοποίηση
  • Φτιάξε το σωστό όνομα από τα tags
  • Πρότεινε/γράψε το νέο όνομα
  • Συμφωνεί το όνομα του άλμπουμ με το όνομα του φακέλου;
  • Εάν δεν είναι MP3, είναι κάτι άλλο; βάλτο σε λίστα.

Αυτά μπορείτε να τα γράψετε σε σχόλια όπως είπαμε πριν. Μετά μπορείτε να ξεκινήσετε από την αρχή υλοποιώντας μία προς μία τις ενέργειες. Τα ιδιαίτερα δύσκολα κομμάτια ή όσα χρησιμοποιούνται ξανά αλλού, μπορείτε να τα βάλετε σε συνάρτηση. Υπάρχουν καλά και κακά σε αυτό. Το καλό είναι ότι όσο περισσότερα βγάζετε από τον κύριο κώδικα του προγράμματος, τόσο περισσότερο φαίνεται η λειτουργία του. Το κακό είναι ότι όσο περισσότερα βγάζετε, μολονότι φαίνεται η δομή του κώδικα, θα πρέπει να πηγαίνετε συνεχώς πάνω-κάτω για να βλέπετε τι ακριβώς γίνεται. Εσείς κάνετε ότι προτιμάτε!

Έλεγχος ειδών

Θα προχωρήσουμε τώρα και θα γράψουμε κώδικα για να κάνουμε αυτές τις ενέργειες. Πρώτα, θα ξεκινήσουμε με ένα string slice της Python για να πάρουμε την κατάληξη, την οποία θα ελέγξουμε για να δούμε αν πρόκειται για MP3 ή όχι. Μετά θα χρησιμοποιούμε το eyeD3 για να εξετάσουμε στα σίγουρα αν το αρχείο είναι κανονικό MP3.

Μετά με τις συγκρίσεις if, ελέγχουμε κάθε είδος αρχείου και εκτελούμε κάποιες ενέργειες. Πρώτα, εξετάζουμε τα “εξωτικά” είδη (WMA, OGG) και μετά τα MP3. Γιατί; Γιατί είναι πολύ εύκολο να ξεχάσουμε να κάνουμε κάτι σε όσα πράγματα δεν μας ενδιαφέρουνε άμεσα οπότε, αν είναι δυνατό να ξεμπερδεύουμε μαζί τους με μερικές γραμμές κώδικα, είναι καλύτερα να το κάνουμε στην αρχή. Θα μπορούσατε φυσικά να κάνετε την ίδια δουλειά με μια συνάρτηση...

Στον παρακάτω κώδικα, θα δείτε αναφορές σε μια συνάρτηση ‘sanitize’ για το string που φτιάχνουμε. Απομονώσαμε τον κώδικα της, για να είναι πιο ευανάγνωστος ο υπόλοιπος κώδικας (και να μπορείτε να την επαναχρησιμοποιήσετε αλλού), αλλά δεν την γράψαμε εδώ (για να χωρέσουμε σε 4 σελίδες!). Μπορείτε όμως να βρείτε το πλήρες script στο http://tinyurl.com/2pgxzk

if (extension !=’.mp3’):
#δεν είναι MP3; Έλεγξε για άλλες καταλήξεις.
if (extension == ‘.wma’):
wmalist.append(fullpath)
#logger.warn(“silly wma file %s”,fullpath)
elif (extension == ‘.ogg’):
ogglist.append(fullpath)
else:
unknownlist.append(fullpath)
else:
# είναι MP3;
if eyeD3.isMp3File(fullpath):
# read ID3V2 tag
tag2 = eyeD3.Tag()
tag1 = eyeD3.Tag()
a = tag2.link(fullpath,eyeD3.ID3_V2)
b = tag1.link(fullpath,eyeD3.ID3_V1)
if b and not a:
#βρήκε μόνο ID3v1 tag
print “version1 only”
# φτιάξε tag2 από το tag1
print fullpath
artist = tag1.getArtist()
album = tag1.getAlbum()
title = tag1.getTitle()
print artist,album,title
tag1.update(eyeD3.ID3_V2)
#έλεγξε ότι είναι ΟΚ τα tags
elif a and not b:
#βρήκε μόνο ID3v2 tags
print fullpath
artist = tag2.getArtist()
album = tag2.getAlbum()
title = tag2.getTitle()
print artist,album,title
try:
tag2.update(eyeD3.ID3_V1_1)
except UnicodeEncodeError:
logger.error(“tag invalid for v1.1 in file %s”, fullpath)
elif a and b:
#βρήκε και τα δύο
logger.info( “both versions fine %s”, fullpath)
else:
#δεν βρήκε τίποτε
logger.warn(‘this file has no tags! %s’, fullpath)
error_flag = True
#ίσως να φτιάχναμε κάτι από το όνομα του φακέλου!
if not error_flag:
#επέλεξε το όνομα του αρχείου
# number-name.mp3
title=tag2.getTitle()
title = title.replace(‘ ‘,’_’)
n=tag2.getTrackNum()
#έχουμε αριθμό
ns = str(n[0])
if len(ns)==1:
ns= ‘0’+ns
ns=ns+’-’+title+’.mp3’
#αφαίρεσε τους κακούς χαρακτήρες
ns=sanitize(ns)
if (file!=ns):
logger.info(“change filename suggested for %s, to %s!”,filename,ns)
os.rename(fullpath, os.path.join(dirs[0],ns)
else:
#logαρε μια προειδοποίηση
logger.warn(“ file %s does not seem to be a valid mp3 file”,fullpath)

Σημειώστε ότι το σκριπτάκι δεν είναι ολοκληρωμένο, ενώ δεν είναι σίγουρο ότι δεν θα χαλάσει τελείως τη συλλογή σας! Θα μπορούσατε για παράδειγμα, να το επεκτείνετε ώστε να ελέγχει για Unicode χαρακτήρες στα ID3v2 tags (που δεν μπαίνουν στα v1 tags). Ή να του προσθέσετε ενέργειες για τα OGG.

Του λείπουν επίσης μηχανισμοί εντοπισμού λαθών. Στην Python υπάρχει μια δομή try: ... except: για να πιάνετε τις εξαιρέσεις με Unicode tags, αλλά θα μπορούσατε να την χρησιμοποιήσετε και σε άλλα μέρη (π.χ. όταν ένα από τα αρχεία μουσικής δεν είναι εγγράψιμο!). Πάντως, ελπίζουμε να καταλάβατε τη λογική ώστε να μπορείτε να γράψετε ένα σκριτπάκι Python που να κάνει κάτι χρήσιμο....

ΣΥΜΒΟΥΛΕΣ ΚΑΙ ΕΠΕΞΗΓΗΣΕΙΣ ΕΝΝΟΙΩΝ

ΜΟΡΦΟΠΟΙΗΣΗ ΚΩΔΙΚΑ PYTHON
Ένα πράγμα που ενοχλεί πολλούς χρήστες, αλλά στην πράξη είναι απλό και λογικό, είναι η επιμονή της Python στην καλή μορφοποίηση του κώδικα. Βασικά, ο κώδικας πρέπει να έχει εσοχές του ίδιου μήκους (κενά ή tabs). Γιατί, οι εσοχές σημαίνουν κάτι. Εάν κοιτάξετε τον κώδικα θα δείτε ότι δεν υπάρχουν άγκιστρα στις δηλώσεις if/for ή κάτι άλλο που να δηλώνει κομμάτια κώδικα. Η Python καταλαβαίνει πότε τελειώνει ένα μπλοκ κώδικα, από την εσοχή! Αυτό έχει 2 μεγάλα πλεονεκτήματα: κάνει τον κώδικα πιο ευανάγνωστο και δεν χρειάζεται να βάζετε άγκιστρα παντού.

ΤΙ ΕΙΝΑΙ Η TUPLE;
H tuple είναι μια δομή λίστας που αποτελείται από πολλές τιμές και χρησιμοποιείται πολύ στην Python. Ένα καλό παράδειγμα όπου θα θέλατε να χρησιμοποιήσετε μια tuple είναι ένα χρώμα. Αντί να αποθηκεύετε τρεις τιμές σε τρεις μεταβλητές για το κόκκινο, πράσινο και μπλε, μπορείτε να έχετε μία μεταβλητή με τρεις τιμές μέσα της! Μια τέτοια tuple θα τυπώνεται από την Python κάπως έτσι:
(123,255,17). Μπορείτε να έχετε πρόσβαση στα ξεχωριστά στοιχεία της tuple με δείκτες, δηλαδή έναν αριθμό σε αγκύλες μετά το όνομα της tuple, π.χ. η print Colour[1] θα τύπωνε “255” στο προηγούμενο παράδειγμα. Όπως πάντα (!), οι δείκτες ξεκινούν από το μηδέν.

ΤΙ ΕΙΝΑΙ ΤΑ SLICES;
Η Python χρησιμοποιεί δείκτες για να “τεμαχιζει” strings, λίστες και άλλες μεταβλητές. Έτσι αν έχετε το string “plop.mp3” μπορείτε να πάρετε οποιοδήποτε κομμάτι του θέλετε. Από ένα τερματικό, δώστε python για να μπείτε στο interactive mode της γλώσσας, και δοκιμάστε τα εξής:

>>>string = ‘plop.mp3’
>>>print string[1]
l
>>> print string[:2]
pl
>>> print string [-0]
p
>>> print string [-1]
3
>>> print string [-4:]
.mp3
>>>

Η τελευταία εντολή μας δίνει τους τέσσερις τελευταίους χαρακτήρες της συμβολοσειράς, ξεκινώντας από το τέλος της. Δηλαδή οι αρνητικοί δείκτες ξεκινούν από το τέλος του string, αλλά θα πρέπει να προσέχετε τι δίνετε καθώς και την άνω-κάτω τελεία όταν θέλετε περισσότερους από έναν χαρακτήρες. Και πάλι το μηδέν είναι η αρχή των πάντων...

ΚΑΤΑΓΡΑΦΕΣ ΣΕ LOG
Οι περισσότεροι χρήστες που γράφουν λίγο κώδικα, συνηθίζουν να τον γεμίζουν με εντολές print για να ξέρουν τι γίνεται. Αυτό δεν είναι κακό, μόνο που σε κάποιο σημείο θα θέλετε να αλλάξετε τις εντολές print, να τις σχολιάσετε, κλπ και θα γίνει χαμός. Είναι πιο εύκολο να χρησιμοποιήσετε το ενσωματωμένο logging module για καταγραφές της γλώσσας. O logger μπορεί και πάλι να τυπώνει στην κονσόλα (αν θέλετε), αλλά η ομορφιά του είναι ότι προσφέρει διάφορα επίπεδα μηνυμάτων, οπότε αρκεί να αλλάξετε μια μόνο γραμμή στον κώδικα για να τον κάνετε λιγότερο ή περισσότερο εύγλωττο. Προσθέστε το logging στη λίστα των modules σας και προσθέστε τα εξής στην αρχή του script:


logger = logging.getLogger(“pymusic”)
#φτιάξε ένα handler για κονσόλα
handler = logging.StreamHandler()
#φτιάξε ένα μορφοποιητή και βάλε το handler να το χρησιμοποιεί
formatter = logging.Formatter(“%(asctime)s - %(name)s - %(levelname)s - %(message)s”)
handler.setFormatter(formatter)
#πρόσθεσε το handler στο logger
logger.addHandler(handler)
logger.setLevel(logging.WARN)

Μερικά από αυτά μπορεί να σας φαινονται κινέζικα, και αρκετοί παραπονούνται ότι το logging module είναι υπερβολικά περίπλοκο, αλλά στην πραγματικότα είναι πολύ εύκολο να ορίσετε την καταγραφή στην κονσόλα με αυτόν τον τρόπο. Για να μάθετε περισσότερα, η τεκμηρίωση του logging module βρίσκεται στο http://docs.python.org/lib/module-logging.html. Σημειώστε επίσης ότι μπορείτε να χρησιμοποιήσετε τα στάνταρ μηνύματα για να ελέγχετε την έξοδο, ανάλογα με το επίπεδο logging. Έτσι για παράδειγμα ο παρακάτω κώδικας:

logger.warn(“ file %s does not seem to be a valid mp3 file”,fullpath)

θα τυπώσει αυτό το μήνυμα μόνο όταν το επίπεδο logging είναι στο WARN ή χαμηλότερο (η σειρά είναι Critical, Error, Warning, Info, Debug). Μπορείτε ακόμα να ορίσετε τα δικά σας επίπεδα αλλά ας το αφήσουμε για μια άλλη φορά αυτό...

ΓΡΗΓΟΡΕΣ ΣΥΜΒΟΥΛΕΣ

  • Τα ID3v1 μπορεί να δημιουργήσουν το γνωστό θόρυβο στην εναλλαγή τραγουδιών, ειδικά σε παλιότερα MP3 players. Αυτό μπορείτε να το λύσετε αν τα μετατρέψετε σε ID3v2, μια και τα παλιά MP3 players δεν διαβάζουν αυτά τα tags. Θα ακούτε τη μουσική, αλλά δεν θα βλέπετε πληροφορίες στην οθόνη...
  • Τα ID3v2 tags μπορεί να περιέχουν πολλές πληροφορίες που δεν χρειάζεστε, όπως δειγματοληψία, copyright και άδεια χρήσης, αλλά και στίχους. Εάν έχετε ένα φορητό player με περιορισμένη μνήμη, το να αφαιρέσετε όλη αυτή την άχρηστη πληροφορία μπορεί να ανεβάσει σημαντικά την απόδοσή του.

Αναδημοσίευση από άρθρο του Nick Veitch στο τεύχος 18.

Δώσε αστέρια!
Σχόλια