JamendoTorrent Editor

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Hallo,

da es mich immer sehr stört, dass bei allen Alben, die ich von Jamendo herunterlade, lauter *.txt Dateien drinnen sind und das cover immer umbenannt werden müsste, hab ich mal ein Programm geschrieben, dass mir die Cover in cover.jpg umbenennt und die Textdateien löscht:

Code: Alles auswählen

#!/usr/bin/python
#-*- encoding: utf8 -*-
'''
TODO:
-Methode zum Ordner umbennen
 o Nur noch [Artist] - [Album]
-Methode zum Ordnerstruktur aendern
 o Ordner umbennen(s.o.)
 o Order fuer Interpret mit Unterordnern fuer die Alben([Artist]/[Album]
-GUI
'''

__version__='0.0.1a'
__autor__='Tobias Höbel'

import os
import sys
import re

class JTE:
#--------------------------------------------------------------------------
    def __init__(self):
        '''
            sets up the variables, check the given arguments and do the
            operations.
        '''
        self.args=dict()
        self.args['dr']=False
        self.args['cr']=False
        self.args['tdel']=False
        self.homedir=os.path.join(os.environ.get('HOME'))
        self.trash_path=os.path.join(self.homedir,'.Trash')

        self.check_dir(self.trash_path)
        self.check_dir(sys.argv[-1],False,True)
        self.check_arguments()

        os.path.walk(sys.argv[-1],self.file_operations,None)
#--------------------------------------------------------------------------
    def check_arguments(self):
        '''
            checks witch arguments are given
        '''
        #VERSUCH OHNE REGEX AUSZUKOMMEN, UM DIE ARGUMENTE ZU ÜBERPRÜFEN.
        #WIRD NOCH AUSGEBAUT
        #for arg in sys.argv:
        #    if arg.startswith('-'):
        #        if arg[1:]=='cr':
        #            self.args['cr']=True
        #            try:
        #                self.args['cover_name']=arg.split('=')[1]
        #            except KeyError:
        #                self.args['cover_name']='cover'
        #        if arg[1:]=='dr':
        #            self.args['dr']=True
        #            try:
        #                self.args['dr_sa']=arg.split('=')[1]
        #            except KeyError:
        #                self.args['dr_sa']=False
        #        if arg[1:]=='tdel':
        #            self.args['tdel']=True
        #    elif arg.startswith('--'):

        arg=' '.join(sys.argv)
        cr=re.compile(r'(-cr|--coverrename)(=(?P<opt>[\w\d]+))?',
            re.IGNORECASE).search(arg)
        tdel=re.compile(r'(-tdel|--txtdelete)',
            re.IGNORECASE).search(arg)
        dr=re.compile(r'(-dr|--dirrename)(=(?P<opt>sa))?',
            re.IGNORECASE).search(arg)

        if cr:
            self.args['cr']=True
            if cr.group('opt'):
                self.args['cover_name']=cr.group('opt')
        if tdel:
            self.args['tdel']=True
        if dr:
            self.args['dr']=True
            self.args['dr_type']=dr.group('opt')
        if len(sys.argv) < 2:
            self.show_help()
            raise SystemExit,'Es wurden nicht genuegend Argumente uebergeben.'
        if not self.args['cover_name'].endswith('.jpg'):
            self.args['cover_name']+='.jpg'
#--------------------------------------------------------------------------
    def show_help(self):
        '''
            shows the help.
        '''
        print ('Aufruf: '+sys.argv[0]+' [OPTION] Verzeichniss\n'
            'Rekursives aendern der Dateien in den Unterordnern des '
            'uebergebenen Ordners.\n'
            'Moegliche Optionen:\n'
            '  -tdel, --txtdelete\t\tLoeschen der *.txt Dateien in '
            'den Unterordnern.\n'
            '  -cr[=NAME] --coverrename[=NAME]\tUmbenennung der Bilddatei in'
            ' cover.jpg oder bei Angabe von NAME in NAME.jpg.\n'
            '  -dr[--sa], --dirrename[--sa]\t\tUmbenennung der Ordner in '
            '[Arist] - [Album]. Falls "--sa" mit angegeben wird, wird fuer '
            'jeden Interpreten jeweils ein Ordner mit Unterordnern fuer jedes '
            'Album erstellt.\n')
#--------------------------------------------------------------------------
    def check_dir(self,dir,create=True,force_exist=False):
        '''
            checks wether the given path exitsts and if it's a directory.
            if the check is succesful it return true or false.
            if the directory doesn't exist it can be created or exit.
        '''

        if not os.path.exists(dir) and not os.path.isdir(dir):
            if force_exist:
                raise (SystemExit, 'Pfad '+dir+' existiert nicht')
            else:
                if create:
                    os.mkdir(dir)
                self.check_dir(dir)
            return False
        else:
            return True
#--------------------------------------------------------------------------
#    def get_dirs(self):
#        dirs=[]
#        for dir in os.listdir('.'):
#            if os.path.isdir(dir):
#                dirs.append(dir)
#        if not dirs:
#            print 'leer'
#        return dirs
#--------------------------------------------------------------------------
    def file_operations(self,arg,dirname,names):
        '''
            performs the operations which should be done.
        '''
        path=os.path.join(sys.argv[-1],dirname)
        for name in names:
            if name.endswith('.txt') and self.args['tdel']:
                os.remove(os.path.join(path,name))
            if name.endswith('jpg') and self.args['cr']:
                os.rename(os.path.join(path,name),
                    os.path.join(path,self.args['cover_name']))
#--------------------------------------------------------------------------

def main():
    if __name__=='__main__':
        jte=JTE():
main()
Ihr könnt jetzt den Code in der Luft zerreisen^.^
Was ich noch vorhab:
  • Ein GUI
  • Ordnerstrukturänderungen(Artist - Album) oder ein Ordner pro Artist (Artist/Album)
  • Erstellen von Playlisten
Was habt ihr noch für Vorschläge?
Die Auskommentierten Codestellen sind überbleibsel von fehlgeschlagenen Versuchen oder noch nich ausgereifte Versuche (z.B. Die Argumente mit Stringoperationen auszuwerten und nich extra deswegen das Modul re hernehmen zu müssen).
Dann sagt mir mal, was ihr von dem Code haltet und was ich verbessern könnte/sollte.

Lg Tobi
BlackJack

Ganz böser Fehler ist der Doppelpunkt in Zeile 146. Damit kompiliert das Programm nicht einmal.

Es sind zuwenig Leerzeichen drin. Vor und nach binären Operatoren und nach Kommata sollte eines stehen, das erhöht die Lesbarkeit.

Der Klassenname ist IMHO nicht wirklich selbsterklärend.

`os.path.join()` auf *ein* Argument anzuwenden kann man sich sparen, da kommt einfach das Argument wieder zurück. `self.homedir` und `self.trash_path` werden nur in der `__init__()` verwendet, brauchen also nicht an die Instanz gebunden zu werden.

Kommandozeilenargumente mit regulären Ausdrücken auszuwerten, wo es doch das `optparse`-Modul in der Standardbibliothek gibt, ist ziemlich, äh, "perlesque". ;-)

Die Methode `show_help()` könnte eine Funktion sein.

`JTE.check_dir()` gibt `False` zurück wenn das Verzeichnis erzeugt werden musste.

Ich sehe den Sinn der Klasse nicht so richtig. Das hätte man prima mit ein paar Funktionen lösen können. Wir sind hier ja nicht bei Java. :-)

Das Idiom für `main()` ist durcheinandergeraten. Das sieht normalerweise so aus:

Code: Alles auswählen

if __name__ == '__main__':
    main()
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

BlackJack hat geschrieben:Ganz böser Fehler ist der Doppelpunkt in Zeile 146. Damit kompiliert das Programm nicht einmal.
:oops: Der kommt, weil ich in letzter Minute noch bisi was geändert hab, der war da eigentlich nich :wink:
BlackJack hat geschrieben:Es sind zuwenig Leerzeichen drin. Vor und nach binären Operatoren und nach Kommata sollte eines stehen, das erhöht die Lesbarkeit.
Versuche zwar immer wieder genügen reinzumachen, vergess es aber oft.
BlackJack hat geschrieben:Der Klassenname ist IMHO nicht wirklich selbsterklärend.
Hm, mir ist nichts besseres eingefallen :wink:
BlackJack hat geschrieben:`os.path.join()` auf *ein* Argument anzuwenden kann man sich sparen, da kommt einfach das Argument wieder zurück.
Wo habe ich denn nur ein Argument angegen? Dass das sinnlos is, is irgendwie klar. Muss mal schaun, wo ich das falsch gemacht hab.
BlackJack hat geschrieben:`self.homedir` und `self.trash_path` werden nur in der `__init__()` verwendet, brauchen also nicht an die Instanz gebunden zu werden.
Muss ich mal überorüfen, kann aber gut sein, da ich so oft, die Methoden getauscht habe. Das is wohl das überbleibsel von der Option, ob man die Dateien in den Mülleimer verschieben will oder nach /dev/null, die ich rausgenommen hatte.
BlackJack hat geschrieben:Kommandozeilenargumente mit regulären Ausdrücken auszuwerten, wo es doch das `optparse`-Modul in der Standardbibliothek gibt, ist ziemlich, äh, "perlesque". ;-)
Das Modul kannte ich noch gar nicht :wink: Muss ich mir gleich mal anschauen, danke.
BlackJack hat geschrieben:`JTE.check_dir()` gibt `False` zurück wenn das Verzeichnis erzeugt werden musste.
Gleich mal checken sollte aber nicht so sein.
Nein, es gibt nicht False zurück. Da hast du Einrückung übersehen. Wenn das Verzeichniss erstellt werden musste, wird die Methode nocheinmal aufgreufen, um zu checken, ob jetz alles stimmt. Das False steht da falls das Verzeichniss nicht existieren muss und nich erstellt werden soll.
BlackJack hat geschrieben:Ich sehe den Sinn der Klasse nicht so richtig. Das hätte man prima mit ein paar Funktionen lösen können. Wir sind hier ja nicht bei Java. :-)
Naja, aber ich hab mir gedacht, dass es mit einer Klasse leichter zu lösen ist, zumal das Programm ja noch wachsen soll, weswegen später vielleicht eine Klasse von nöten ist. So war mein Gedankengang
BlackJack hat geschrieben:Das Idiom für `main()` ist durcheinandergeraten. Das sieht normalerweise so aus:

Code: Alles auswählen

if __name__ == '__main__':
    main()
Und gleich nochmal :oops: Da hast du natürlich recht :D Böses Faul.

Danke für die vielen Hinweiße und Tipps.

LG Tobi
BlackJack

CrackPod hat geschrieben:
BlackJack hat geschrieben:`os.path.join()` auf *ein* Argument anzuwenden kann man sich sparen, da kommt einfach das Argument wieder zurück.
Wo habe ich denn nur ein Argument angegen? Dass das sinnlos is, is irgendwie klar. Muss mal schaun, wo ich das falsch gemacht hab.
Zeile 31.
BlackJack hat geschrieben:`JTE.check_dir()` gibt `False` zurück wenn das Verzeichnis erzeugt werden musste.
Gleich mal checken sollte aber nicht so sein.
Nein, es gibt nicht False zurück. Da hast du Einrückung übersehen.
Nein habe ich nicht. Das hat mit Einrückung nichts zu tun.
Wenn das Verzeichniss erstellt werden musste, wird die Methode nocheinmal aufgreufen, um zu checken, ob jetz alles stimmt.
Und dieser Aufruf kehrt zurück und dann wird als nächstes ein ``return False`` ausgeführt.
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Also das in Zeile 31 hab ich bereinigt, sowie soziemlich alles andere, worauf du mich hingewiesen hast-Danke :)
Das mit der Ordnerfunktion stimmt.:roll: tut mir leid. Ich hatte nicht bedacht, dass die Funktion nocheinmal zurückkehrt...

Code: Alles auswählen

def check_dir(self,dir,create=True,force_exist=False):

    if not os.path.exists(dir) and not os.path.isdir(dir):
        if force_exist:
            raise (SystemExit, 'Pfad '+dir+' existiert nicht')
        else:
            if create:
                os.mkdir(dir)
            return self.check_dir(dir,create,force_exist)
        return False
    else:
        return True
So müsste es doch funktionieren, wenn ich den Rückgabewert der Funktion returne, oder?

LG Tobi
BlackJack

CrackPod hat geschrieben:So müsste es doch funktionieren, wenn ich den Rückgabewert der Funktion returne, oder?
Fast. Wenn die Datei nicht angelegt werden kann, dann wird rekursiv die Funktion aufgerufen, die die Datei nicht anlegen kann und rekursiv die Funktion aufruft, die die Datei nicht anlegen kann und rekursiv… ;-)
CrackPod
User
Beiträge: 205
Registriert: Freitag 30. Juni 2006, 12:56

Pfff, dann wisch ich der Rekursion eben eins aus, indem ich nen SystemExit raise, wenn ein OSError kommt :P

Code: Alles auswählen

def check_dir(self,dir,create=True,force_exist=False):

    if not os.path.exists(dir) and not os.path.isdir(dir):
        if force_exist:
            raise (SystemExit, 'Pfad '+dir+' existiert nicht')
        else:
            if create:
                try:
                    os.mkdir(dir)
                except OSError,e:
                    raise SystemExit,e
            self.check_dir(dir,create,force_exist)
        return False
    else:
        return True
So richtig?

Lg Tobi
azarai
User
Beiträge: 10
Registriert: Mittwoch 14. Februar 2007, 14:48
Kontaktdaten:

schön, gibt doch mehr jamendo user. Hatte mir letztes Jahr auch ein Script geschrieben was die "torrents" in die Struktur meiner Musiksammlung kopiert. Kann in meinem blog gezogen werden. Ich poste es aber genre auch nochmal hier, sofern das dann nicht direkt als Spam gilt :-)
Antworten