Seite 1 von 1
Kleines Programm für Openbox\MPD
Verfasst: Mittwoch 23. April 2008, 00:56
von Tayce
Ich hab mir mal ein kleines Script geschrieben dass ich vom Openbox-Menü aus starten kann um MPD zu stoppen, das nächste Lied zu spielen usw...
Genutzt wird python-mpd.
Hier mal der Code:
Code: Alles auswählen
#!/usr/bin/env python
import sys
import mpd
class Player(object):
def __init__(self):
self.client=mpd.MPDClient()
self.client.connect("localhost", 6600)
def next(self):
self.client.next()
def previous(self):
self.client.previous()
def play(self):
self.client.play()
def pause(self):
self.client.pause()
def stop(self):
self.client.stop()
def close(self):
self.client.close()
def getcommand(self):
try:
self.command = sys.argv[1]
except:
print "Error"
def doit(self):
if self.command == "-next":
self.next()
if self.command == "-previous":
self.previous()
if self.command == "-play":
self.play()
if self.command == "-pause":
self.pause()
if self.command == "-stop":
self.stop()
else:
print "Error\n Use one of these commands to use this programm:\n\
'-play' start playing\n\
'-pause' pause playing\n\
'-stop' stop playing\n\
'-next' play the next song\n\
'-previous' play the previous song"
a=Player()
a.getcommand()
a.doit()
a.close()
Ich weiß der Code ist nicht perfekt aber es funktioniert =)
Verfasst: Mittwoch 23. April 2008, 06:56
von Hyperion
Hallo,
mal ein paar Tipps von mir, wie man das Tool verbessern könnte:
Schau Dir mal das optparse-Modul an:
file:///usr/share/doc/python2.5/html/lib/module-optparse.html
Damit kann man ganz einfach Kommandozeilenparameter parsen und nebenbei bekommt man eine "-help"-Ausgabe gratis dazu
Außerdem wären ein paar mehr Kommentare und Leerzeilen zwischen den Methoden ganz nett.
Das Programm würde ich außerdem per
"aufmotzen"
Außerdem würde ich die die doit()-Methode umschreiben und mir die Methoden in einem dict aus dem Parameternamen und den Methoden speichern. Somit verkürzt sich das if-"Monster".
Ansonsten nette Idee

Verfasst: Mittwoch 23. April 2008, 09:43
von Tayce
Hyperion hat geschrieben:Außerdem würde ich die die doit()-Methode umschreiben und mir die Methoden in einem dict aus dem Parameternamen und den Methoden speichern. Somit verkürzt sich das if-"Monster".
Ansonsten nette Idee

Hey, ja die Idee mit dem Dict hatte ich grade auch. Naja war gestern tief in der Nacht^^.
Verfasst: Mittwoch 23. April 2008, 09:51
von BlackJack
Also ich finde da ist *extrem* viel Redundanz in dem Skript. Das ist viel zu lang und umständlich.
Verfasst: Mittwoch 23. April 2008, 10:04
von Tayce
Okay, ich hab des gerade mit dem dict versucht aber naja...
Wie schaff ich es das dict mit einer funktion zu verbinden ohne das diese gestartet wird?
ich hatte es in etwa so:
Code: Alles auswählen
dic={"-next":self.client.next(),"-previous":self.client.previous, usw}
dic[self.command]
So würde ich mir auch diese ganzen next() previous() def's sparen aber bei dieser art von dictionary wird anscheinen gleich die funktion gestartet ohne das ich einen aufruf gestartet hab o0
Verfasst: Mittwoch 23. April 2008, 10:10
von Rebecca
Ungetested:
Code: Alles auswählen
dic={"-next":self.client.next,"-previous":self.client.previous, usw}
dic[self.command]()
Du darfst halt die Funktion nicht aufrufen, wenn du sie ins Dict packst (dann bindest du den Rueckgabewert an den Value), sondern erst, wenn du sie wieder rausgeholt hast.
Edit:
Ungetested 
Immer dieser Wechsel zwischen Deutsch und Englisch, das macht mein Hirn nicht mit...

Verfasst: Mittwoch 23. April 2008, 10:12
von keppla
Tayce hat geschrieben:Okay, ich hab des gerade mit dem dict versucht aber naja...
Wie schaff ich es das dict mit einer funktion zu verbinden ohne das diese gestartet wird?
aus versehen hast du das schon geschafft: lass die klammern weg.
Code: Alles auswählen
def x():
return 1
d = {
'ergebnis' : x(), # das resultat des funktionsaufrufes
'funktion' : x, # das funktionsobjekt selbst
}
print d['funktion']() # so kann man sie dann aufrufen
Verfasst: Mittwoch 23. April 2008, 10:29
von BlackJack
Eine einfache Lösung ohne Klasse (ungetestet):
Code: Alles auswählen
import sys
import mpd
def main():
commands = (('play', 'start playing'),
('pause', 'pause playing'),
('stop', 'stop playing'),
('next', 'play the next song'),
('previous', 'play the previous song'))
try:
command = sys.argv[1]
except IndexError:
command = None
if command in (c[0] for c in commands):
client = mpd.MPDClient()
client.connect('localhost', 6600)
getattr(client, command)()
client.close()
else:
print 'Use one of these commands:'
for command, description in commands:
print '%-10s%s' % (command, description)
Verfasst: Mittwoch 23. April 2008, 10:33
von Tayce
Danke Keppla, das wars...
hier mal der Code V 2
Code: Alles auswählen
#!/usr/bin/env python
import sys
import mpd
class Player(object):
def __init__(self):
self.client=mpd.MPDClient()
self.client.connect("localhost", 6600)
def getcommand(self):
try:
self.command = sys.argv[1]
except:
return "Error"
def doit(self):
dic={"-next":self.client.next,
"-previous":self.client.previous,
"-stop":self.client.stop,
"-play":self.client.play,
"-pause":self.client.pause}
try:
dic[self.command]()
except:
print "Error\n Use one of these commands to use this programm:\n\
'-play' start playing\n\
'-pause' pause playing\n\
'-stop' stop playing\n\
'-next' play the next song\n\
'-previous' play the previous song"
def main():
a=Player()
a.getcommand()
a.doit()
a.close()
if __name__ =="__main__":
main()
Verfasst: Mittwoch 23. April 2008, 11:38
von Y0Gi
Ich bin nicht so tief in der POSIX-, GNU- und Sonstwas-Materie, aber Optionen/Schalter in der Form "-foo" erscheinen mir als, naja, ungern geduldet. Vielmehr scheint da die Variante "-f" (kurz) mit "--foo" (lang) gängig zu sein. So kenne und nutze ich das auch vom und mit dem `OptionParser`.
Nachtrag:
Wenn du Kommandos hast, warum verkleidest du die dann als Optionen? Es sind ja essentielle Argumente, also hat der Bindestrich davor eigentlich nichts verloren, sondern ist sogar irreführend.
`.getcommand()` erscheint mir überflüssig. Ich rate dringend, den Kommandonamen von `.doit()` als Parameter entgegen nehmen zu lassen und dorthin `sys.argv[1]` zu übergeben. Dann lohnt sich die Klasse auch schon bald nicht mehr.
Weiterhin schreit dein Code geradezu danach, dass du direkt vom Argument (z.B. "play") mittels `getattr()` nach einer entsprechend benannten Methode des `client`-Objekts suchst.
Spontaner, ungetesteter Versuch:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from os.path import basename
from sys import argv, exit
from mpd import MPDClient
VALID_CMDS = ['start', 'pause', 'stop', 'previous', 'next']
def main():
try:
cmd = argv[1]
except IndexError:
# Sollte man hier besser auf STDERR schreiben?
print 'usage: %s <%s>' % (basename(argv[0]), '|'.join(VALID_CMDS))
exit(2) # 2 wird oft für Aufruffehler verwendet.
client = MPDClient()
client.connect('localhost', 6600)
getattr(client, cmd)()
if __name__ =="__main__":
main()
P.S.: OK, ich sehe gerade, im Grunde ist es das, was BlackJack schon demonstriert hat.
Der OptionParser ist manchmal überdimensioniert (Vllt. kommt man da mit dem etwas umständlicheren `getopt` weiter? Oder soll das in absehbarer Zeit aus der Stdlib fliegen?), kann zumindest aber "Usage"-Hilfetexte mit den verfügbaren Optionen erzeugen.
Verfasst: Mittwoch 23. April 2008, 12:28
von Leonidas
Y0Gi hat geschrieben:Ich bin nicht so tief in der POSIX-, GNU- und Sonstwas-Materie, aber Optionen/Schalter in der Form "-foo" erscheinen mir als, naja, ungern geduldet. Vielmehr scheint da die Variante "-f" (kurz) mit "--foo" (lang) gängig zu sein. So kenne und nutze ich das auch vom und mit dem `OptionParser`.
Ja, ich wollte auch anmeckern, dass das auf GNU-Systemen eher unkonsistent ist. Einige GNU-Programme unterstützen es zwar, aber nur aus historischen Gründen, etwa GNU tar.
Verfasst: Mittwoch 23. April 2008, 17:39
von Y0Gi
Speziell `tar` ist bzgl. CLI-Syntax 'ne ziemliche Katastrophe, finde ich.
Verfasst: Mittwoch 23. April 2008, 22:06
von audax
Code: Alles auswählen
#!/usr/bin/env python
import sys
from mpd import MPDClient
client = MPDClient()
client.connect('localhost', 6600)
try:
getattr(client, sys.argv[1])()
except (AttributeError, IndexError):
print >>sys.stderr client.__doc__
Ich bin pragmatiker
