#1 Le 08/04/2008, à 10:23
- mirlipili
Problèmes dans script Python pyGogear
Bonjour a tous
Je ne suis pas sur d'être dans la bonne section mais bon
Mon petit frère a un lecteur mp3 Philips Hdd Gogear 065/00 , et je lui ai dis qu'il pourrait l'utiliser sous ubuntu...
Le Philips Gogear utilise une base de données sqlite pour gérer les chansons qui sont dessus (artiste/album/genre...).
J'essaye d'utiliser le script pyGogear mais celui-ci me renvois des erreurs....
Les erreurs
(+) Opening mp3: Bangbros - Hansebanger Warmduscher Hardstyle Remix.mp3 ... Done
(+) Opening mp3: Bangbros - I Engineer (Jumpstyle).mp3 ... Done
(+) Opening mp3: Bangbros - I Engineer (Without Bangboy Mix).mp3 ... Traceback (most recent call last):
File "./pyGogear.py", line 357, in <module>
myGogear.update() # and update it!
File "./pyGogear.py", line 344, in update
self.add_song(Mp3Dir+this_file)
File "./pyGogear.py", line 294, in add_song
info = self.get_fields(this_file)
File "./pyGogear.py", line 240, in get_fields
Genre = taginfo.getGenre()
File "/var/lib/python-support/python2.5/eyeD3/tag.py", line 648, in getGenre
g.parse(f[0].text);
File "/var/lib/python-support/python2.5/eyeD3/tag.py", line 1512, in parse
(regex.pattern, genreStr));
eyeD3.tag.GenreException: Genre string cannot be parsed with '^[A-Z 0-9'+/\-&]+*$': www.djwitek.prv.pl
pyGogear.py
#!/usr/bin/env python
# File: pyGogear.py
# Author: Piierluigi Cau, 2005.
# Version: 5.9
# Date: Tue Aug 31 13:11:56 CEST 2005
# Usage: See README file
#
# Updates the Philips Gogear hdd0xx mp3 player database file.
# Reads ID3 tags from all the mp3 files inside the Mp3Dir
# and adds them to the SQLite MyDb file.
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import sys
import os
import shutil
import re
import string
_EYED3VERSION = '0.6.6' # adds support for id3v2.2
try:
import sqlite
except ImportError:
sys.stdout.write("You need the pysqlite module. Please see the README file for more info.")
try:
import eyeD3
except ImportError:
sys.stdout.write("You need the eyeD3 module. Please see the README file for more info.")
# # # # # #
#
# Configure the following variables
MyDbFile = "/media/disk/_system/media/audio/MyDb" # Full path to the MyDb file on your GoGear
Mp3Dir = "/media/disk/_system/media/audio/" # Path to the mp3 (audio) folder on your GoGear.
# End of configuration part - do NOT edit below
#
# # # # # #
class GoGear:
'''
This class contains all the methods needed
to update the Gogear mp3 player.
'''
Connection = None # sqlite connection
Cursor = None # sqlite cursor
MyDbPath = None # source sqlite db file
MyDb = "/tmp/MyDb" # local copy of the file
Mp3List = [] # list of mp3s to add
Counter = 0 # number of files added
PlCounter = 0 # playlist counter
def __init__(self, dbFile, mp3Folder):
'''
Returns a GoGear object with initialized values.
'''
self.MyDbPath = dbFile
try:
self.Mp3List = os.listdir(mp3Folder)
except:
self.death("Can't open the mp3 folder. Did you set the Mp3Dir variable?\n", 1)
try:
shutil.copyfile(self.MyDbPath, self.MyDb)
except IOError:
self.death("Can't copy MyDb to %s.\n" % self.MyDb, 1)
try:
self.Connection = sqlite.connect(self.MyDb)
except:
self.death("Could not open a connection to the db.\n", 1)
try:
self.Cursor = self.Connection.cursor()
except:
self.death("Could not bind a cursor to the connection.\n", 1)
self.db_flush()
def death(self, errmsg, deadly):
'''
Prints an error message on stderr, and exits with status code 1.
'''
sys.stdout.write(errmsg)
if deadly:
sys.exit(1)
else:
pass
def db_flush(self):
'''
Empties the four tables in the database, and commits the changes.
'''
flusher ="DELETE FROM songTable;" + \
"DELETE FROM artistTable;" +\
"DELETE FROM albumTable;" + \
"DELETE FROM genreTable;" + \
"DELETE FROM playlistTable;" + \
"DELETE FROM playsongTable;"
try:
self.Cursor.execute(flusher)
self.Connection.commit()
except:
self.death("Error in db_flush.\n", 1)
def read_mp3(self, Mp3):
'''
Returns an eyeD3 Mp3AudioFile() object from the given mp3.
'''
try:
mp3info = eyeD3.Mp3AudioFile(Mp3)
return mp3info
except eyeD3.tag.TagException:
self.death('Error reading tags from "%s"\n' % Mp3, 0)
return None
except:
self.death('Error in read_mp3 with file: "%s"\n' % Mp3, 0)
return None
def db_query(self, sql):
'''
Executes a SQL query, and commits the changes.
'''
try:
self.Cursor.execute(sql)
self.Connection.commit()
except:
sys.stdout.write(sql + "\n")
self.death('Error in db_query with above sql\n' , 1)
def getId(self, id_field, table, field, match):
'''
Generic method to return the id of an entry in a given table.
'''
sql = 'SELECT %s FROM %s WHERE %s = "%s"' % (id_field, table, field, match)
try:
self.db_query(sql)
id_value = self.Cursor.fetchone()
id_value[0]
except:
sql_notFound = 'INSERT INTO %s(%s, %s) VALUES(NULL, "%s")' % (table, id_field, field, match)
self.db_query(sql_notFound)
self.db_query(sql)
id_value = self.Cursor.fetchone()
return id_value[0]
def fix_string(self, string):
'''
Fixes problems with strings, such as NULL bytes, non-utf.
'''
try:
string = string.encode('utf-8')
except UnicodeDecodeError:
pass
string = string.split('\0')
string = string[0]
return string
def set_defaults(self, mp3file):
'''
Returns an initialized dictionary, with Unknown artist, album and genre.
The filename is set as title.
'''
default_tags = {
'title': mp3file,
'artist': "Unkown Artist",
'album': "Unknown Album",
'tracknr': "NULL",
'genre': "(12)Other",
'year': "NULL"
}
return default_tags
def get_fields(self, mp3File):
'''
Returns a dictionary containing all the key:value pairs needed
to insert each track onto the database
'''
mp3info = self.read_mp3(mp3File)
if mp3info == None:
return None
taginfo = mp3info.getTag()
info = {
'title': None,
'artist': None,
'album': None,
'tracknr': None,
'genre': None,
'year': None,
'bitrate': None,
'length': None,
'freq': None,
'size': None,
'artistID': None,
'albumID': None,
'genreID': None
}
default_title = os.path.basename(mp3File)
default_title = os.path.splitext(default_title)[0]
if taginfo == None:
info = self.set_defaults(self.fix_string(default_title))
else:
# Title
info['title'] = taginfo.getTitle()
if info['title'] == '':
info['title'] = self.fix_string(default_title)
else:
info['title'] = self.fix_string(info['title'])
# Artist
info['artist'] = taginfo.getArtist()
if info['artist'] == '':
info['artist'] = "Unknown Artist"
info['artist'] = self.fix_string(info['artist'])
# Album
info['album'] = taginfo.getAlbum()
if info['album'] == '':
info['album'] = "Unknown Album"
info['album'] = self.fix_string(info['album'])
# Track Number
TrackNr = taginfo.getTrackNum()
TrackNr = TrackNr[0]
if TrackNr == None:
TrackNr = 0
info['tracknr'] = TrackNr
# Genre
# TODO: if Genre contains (xx), remove it.
# Brought to you by eyeD3 (can't get why)
Genre = taginfo.getGenre()
info['genre'] = str(Genre)
if info['genre'] == "None":
info['genre'] = "(12)Other"
info['genre'] = self.fix_string(info['genre'])
# Year
info['year'] = taginfo.getYear()
if info['year'] == None:
info['year'] = 0
# Bitrate
Bitrate = mp3info.getBitRate()
info['bitrate'] = Bitrate[1] # bitrate[0] = 1 if VBR, 0 if CBR
# Track Length
info['length'] = mp3info.getPlayTime()
# Sample Freq
info['freq'] = mp3info.getSampleFreq()
# Size
info['size'] = os.path.getsize(mp3File)
# Fetch the proper IDs for the artist, album, genre of the current song
info['artistID'] = self.getId('iArtistId', 'artistTable', 'cArtistName', info['artist'])
info['albumID'] = self.getId('iAlbumId', 'albumTable', 'cAlbumTitle', info['album'])
info['genreID'] = self.getId('iGenreId', 'genreTable', 'cGenreName', info['genre'])
return info
def finalize(self):
'''
Close the db connection (committing changes), copy back the MyDb file to the GoGear,
and print a success message
'''
try:
self.Connection.commit()
except:
self.death("Error while committing final changes.\n", 1)
try:
self.Cursor.close()
except:
self.death("Error while closing the cursor.\n", 1)
try:
shutil.copyfile(self.MyDb, self.MyDbPath)
except IOError:
self.death("Can't copy the MyDb back to the GoGear.\n", 1)
self.death('.'*60, 0)
self.death("\nOperation completed.\n", 0)
self.death(str(self.Counter) + " songs", 0)
if self.PlCounter > 0:
self.death(" and " + str(self.PlCounter) + " playlists", 0)
self.death(" were added to the Gogear.\n", 0)
sys.exit(0)
def add_song(self, this_file):
'''
Takes an mp3 file (full path), fetches the info from each file, and adds it to the database.
'''
self.death("(+) Opening mp3: %s ... " % os.path.basename(this_file), 0)
info = self.get_fields(this_file)
if info != None:
sql = "INSERT INTO songTable(cSongTitle, iArtistId, iAlbumId, iTrackNr, iTrackLength, iNrPlayed, cFileName, iDirId, iYear, iGenreId, iBitRate, iSampleRate, iFileSize, iMediaType) VALUES(\"%s\", %s, %s, %s, %s, 0, \"%s\", 4, %s, %s, %s, %s, %s, 1)" % (info['title'], info['artistID'], info['albumID'], info['tracknr'], info['length'], os.path.basename(this_file), info['year'], info['genreID'], info['bitrate'], info['freq'], info['size'])
self.db_query(sql)
self.Counter+=1
self.death("Done\n", 0)
def playlist_fetch(self, filename):
'''
Returns a list with the playlist tracks' filenames.
'''
playlist = []
try:
f = open(filename)
#print "(+) Opening playlist: %s ..." % os.path.basename(filename)
self.death("(+) Opening playlist: %s ... " % os.path.basename(filename), 0)
except IOError:
self.death('Error while opening "%s"\n' % filename, 1)
prog = re.compile('^#')
for line in f:
result = prog.match(line)
if result == None:
playlist.append(os.path.basename(line))
self.death('Done\n', 0)
return playlist
def add_playlist(self, playlist):
'''
Takes a playlist file and adds it.
'''
song_order = 1
#ext = os.path.splitext(playlist)
pl_id = self.getId('iPlaylistId', 'playlistTable', 'cPlaylistName', os.path.splitext(playlist)[0])
playlistTracks = self.playlist_fetch(Mp3Dir+playlist)
for song in playlistTracks:
song_id = self.getId('iSongId', 'songTable', 'cFileName', song[:-1])
sql_pl = "INSERT INTO playsongTable(iPlaylistId, iSongId, iOrderNr) VALUES(%s, %s, %s)" % (pl_id, song_id, song_order)
self.db_query(sql_pl)
song_order+=1
self.PlCounter+=1
def update(self):
'''
The general method called to update the Gogear.
This will do all the operations needed to insert each track into the database.
'''
playlist_files = []
for this_file in self.Mp3List:
ext = os.path.splitext(this_file)[1]
if ext == ".mp3":
self.add_song(Mp3Dir+this_file)
elif ext == ".m3u":
playlist_files.append(this_file)
else:
self.death('(-) Neither mp3, nor m3u; is this a directory?: "%s"\n' % this_file, 0)
for playlist in playlist_files:
self.add_playlist(playlist)
self.finalize()
# # # # # #
#
# Main part
myGogear = GoGear(MyDbFile, Mp3Dir) # create a new GoGear object
myGogear.update()
J'ai trouvé le script a cet endroit....
http://nixbit.com/cat/multimedia/audio/pygogear/
Merci beaucoup
Hors ligne
#2 Le 08/04/2008, à 18:07
- bipede
Re : Problèmes dans script Python pyGogear
Le problème vient de la fonction taginfo.GetGenre() qui est incluse dans le module eyeD3.
Il semblerait que le tag qu'il cherche à parser dans ton fichier mp3 contienne des infos imprévues.
J'ai introduit un traitement d'erreur dans le script qui devrait traiter ce problème. Mais je ne garantis pas que tu n'auras pas d'autre erreur, car ce soft me semble bien mal codé.
Tu peux récupérer ma version sous ce lien
Tiens moi au courant...
Desktop: MSI - Intel® Core™ i5-3330 CPU @ 3.00GHz × 4 - RAM 8 go- Kubuntu 21.04 - Système sur SSD 64 Go - /home sur HDD 500 Go.
Laptop: DELL Inspiron-15 3567 - Intel® Core™ i5-7200 CPU @ 2.50GHz × 4 - RAM 8 go - HDD 1 To - Ubuntu 20.10 avec /home séparé.
Mon site: Les contributions du bipède
Hors ligne
#3 Le 08/04/2008, à 18:37
- mirlipili
Re : Problèmes dans script Python pyGogear
Merci
J'ai réessayé,et en fait il s'arrête à certaine chansons (4 sur 170),après avoir retiré celle ci, ca marche sans problème
voila le message d'erreur que j'ai pour ces chansons....
(+) Opening mp3: Mims_ft.Prophet_-_Like_This_(Official_Remix)-2007.mp3 ... Traceback (most recent call last):
File "./pyGogear.py", line 359, in <module>
myGogear.update() # and update it!
File "./pyGogear.py", line 346, in update
self.add_song(Mp3Dir+this_file)
File "./pyGogear.py", line 296, in add_song
info = self.get_fields(this_file)
File "./pyGogear.py", line 242, in get_fields
Genre = taginfo.getGenre()
File "/var/lib/python-support/python2.5/eyeD3/tag.py", line 648, in getGenre
g.parse(f[0].text);
File "/var/lib/python-support/python2.5/eyeD3/tag.py", line 1512, in parse
(regex.pattern, genreStr));
eyeD3.tag.GenreException: Genre string cannot be parsed with '^[A-Z 0-9'+/\-&]+*$': [ By R.o.N Shahar ]
Hors ligne
#4 Le 08/04/2008, à 18:43
- bipede
Re : Problèmes dans script Python pyGogear
Merci
J'ai réessayé,et en fait il s'arrête à certaine chansons (4 sur 170),après avoir retiré celle ci, ca marche sans problème
voila le message d'erreur que j'ai pour ces chansons....
(+) Opening mp3: Mims_ft.Prophet_-_Like_This_(Official_Remix)-2007.mp3 ... Traceback (most recent call last): File "./pyGogear.py", line 359, in <module> myGogear.update() # and update it! File "./pyGogear.py", line 346, in update self.add_song(Mp3Dir+this_file) File "./pyGogear.py", line 296, in add_song info = self.get_fields(this_file) File "./pyGogear.py", line 242, in get_fields Genre = taginfo.getGenre() File "/var/lib/python-support/python2.5/eyeD3/tag.py", line 648, in getGenre g.parse(f[0].text); File "/var/lib/python-support/python2.5/eyeD3/tag.py", line 1512, in parse (regex.pattern, genreStr)); eyeD3.tag.GenreException: Genre string cannot be parsed with '^[A-Z 0-9'+/\-&]+*$': [ By R.o.N Shahar ]
Si tu essayes mon script modifié,tu pourras peut-être lire tes quatre morceaux rejettés...
Desktop: MSI - Intel® Core™ i5-3330 CPU @ 3.00GHz × 4 - RAM 8 go- Kubuntu 21.04 - Système sur SSD 64 Go - /home sur HDD 500 Go.
Laptop: DELL Inspiron-15 3567 - Intel® Core™ i5-7200 CPU @ 2.50GHz × 4 - RAM 8 go - HDD 1 To - Ubuntu 20.10 avec /home séparé.
Mon site: Les contributions du bipède
Hors ligne
#5 Le 08/04/2008, à 18:44
- mirlipili
Re : Problèmes dans script Python pyGogear
En fait, en modifiant le genre (avec ex-falso) ca ne pose plus de problèmes....
pour deux chansons il y avait un " [ "
pour deux autres juste une adresse internet,donc juste des points....
et une a passé le script la première fois,mais l'a fait planté la deuxième fois....bizarre
Pour la "propreté" du code,je comprends en gros ce qu'il fait,mais je ne suis pas encore assez loin pour pouvoir corrigé ca moi-même
Hors ligne
#6 Le 08/04/2008, à 18:45
- mirlipili
Re : Problèmes dans script Python pyGogear
Les erreurs sont celles venant de ton script modifié...
Hors ligne
#7 Le 08/04/2008, à 19:42
- bipede
Re : Problèmes dans script Python pyGogear
Les erreurs sont celles venant de ton script modifié...
Bon, on dirait que mon traitement d'exceptions ne fonctionne pas...
La biblothèque eyeD3 plante sans générer d'exception...
Je vais chercher....
Desktop: MSI - Intel® Core™ i5-3330 CPU @ 3.00GHz × 4 - RAM 8 go- Kubuntu 21.04 - Système sur SSD 64 Go - /home sur HDD 500 Go.
Laptop: DELL Inspiron-15 3567 - Intel® Core™ i5-7200 CPU @ 2.50GHz × 4 - RAM 8 go - HDD 1 To - Ubuntu 20.10 avec /home séparé.
Mon site: Les contributions du bipède
Hors ligne