3 ############################################################################
4 # Python wrapper script for running the Amarok LiveCD remastering scripts
5 # from within Amarok. Based on the Python-Qt template script for Amarok
6 # (c) 2005 Mark Kretschmann <markey@web.de>
8 # (c) 2005 Leo Franchi <lfranchi@gmail.com>
10 # Depends on: Python 2.2, PyQt
11 ############################################################################
13 # This program is free software; you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation; either version 2 of the License, or
16 # (at your option) any later version.
18 ############################################################################
25 from time
import sleep
30 os
.popen( "kdialog --sorry 'PyQt (Qt bindings for Python) is required for this script.'" )
34 # Replace with real name
35 debug_prefix
= "LiveCD Remastering"
38 class ConfigDialog ( QDialog
):
39 """ Configuration widget """
42 QDialog
.__init
__( self
)
43 self
.setWFlags( Qt
.WDestructiveClose
)
44 self
.setCaption("Amarok Live! Configuration")
46 self
.lay
= QGridLayout( self
, 3, 2)
48 self
.lay
.addColSpacing( 0, 300 )
50 self
.isopath
= QLineEdit( self
)
51 self
.isopath
.setText( "Path to Amarok Live! iso" )
52 self
.tmppath
= QLineEdit( self
)
53 self
.tmppath
.setText( "Temporary directory used, 2.5gb free needed" )
55 self
.lay
.addWidget( self
.isopath
, 0, 0 )
56 self
.lay
.addWidget( self
.tmppath
, 1, 0 )
58 self
.isobutton
= QPushButton( self
)
59 self
.isobutton
.setText("Browse..." )
60 self
.tmpbutton
= QPushButton( self
)
61 self
.tmpbutton
.setText("Browse..." )
63 self
.cancel
= QPushButton( self
)
64 self
.cancel
.setText( "Cancel" )
65 self
.ok
= QPushButton( self
)
66 self
.ok
.setText( "Ok" )
68 self
.lay
.addWidget( self
.isobutton
, 0, 1 )
69 self
.lay
.addWidget( self
.tmpbutton
, 1, 1 )
70 self
.lay
.addWidget( self
.cancel
, 2, 1 )
71 self
.lay
.addWidget( self
.ok
, 2, 0)
73 self
.connect( self
.isobutton
, SIGNAL( "clicked()" ), self
.browseISO
)
74 self
.connect( self
.tmpbutton
, SIGNAL( "clicked()" ), self
.browsePath
)
76 self
.connect( self
.ok
, SIGNAL( "clicked()" ), self
.save
)
77 self
.connect( self
.ok
, SIGNAL( "clicked()" ), self
.unpack
)
78 # self.connect( self.ok, SIGNAL( "clicked()" ), self.destroy )
79 self
.connect( self
.cancel
, SIGNAL( "clicked()" ), self
, SLOT("reject()") )
85 config
= ConfigParser
.ConfigParser()
86 config
.read( "remasterrc" )
87 path
= config
.get( "General", "path" )
88 iso
= config
.get( "General", "iso")
90 if not path
== "": self
.tmppath
.setText(path
)
91 if not iso
== "": self
.isopath
.setText(iso
)
98 """ Saves configuration to file """
99 self
.file = file( "remasterrc", 'w' )
100 self
.config
= ConfigParser
.ConfigParser()
101 self
.config
.add_section( "General" )
102 self
.config
.set( "General", "path", self
.tmppath
.text() )
103 self
.config
.set( "General", "iso", self
.isopath
.text() )
104 self
.config
.write( self
.file )
111 self
.file = file( "remasterrc", 'w' )
112 self
.config
= ConfigParser
.ConfigParser()
113 self
.config
.add_section( "General" )
114 self
.config
.set( "General", "path", "" )
115 self
.config
.set( "General", "iso", "" )
116 self
.config
.write( self
.file )
119 def browseISO( self
):
121 path
= QFileDialog
.getOpenFileName( "/home",
124 "iso choose dialogr",
125 "Choose ISO to remaster")
126 self
.isopath
.setText( path
)
128 def browsePath( self
):
130 tmp
= QFileDialog
.getExistingDirectory( "/home",
133 "Choose working directory",
135 self
.tmppath
.setText( tmp
)
140 # now the fun part, we run part 1
141 fd
= os
.popen("kde-config --prefix", "r")
142 kdedir
= fd
.readline()
143 kdedir
= kdedir
.strip()
144 scriptdir
= kdedir
+ "/share/apps/amarok/scripts/amarok_live"
147 path
, iso
= self
.readConfig()
148 os
.system("kdesu -t sh %s/amarok.live.remaster.part1.sh %s %s" % (scriptdir
, path
, iso
))
150 print "got path: %s" % path
155 def readConfig( self
) :
159 config
= ConfigParser
.ConfigParser()
160 config
.read("remasterrc")
161 path
= config
.get("General", "path")
162 iso
= config
.get("General", "iso")
169 class Notification( QCustomEvent
):
170 __super_init
= QCustomEvent
.__init
__
171 def __init__( self
, str ):
174 self
.__super
_init
(QCustomEvent
.User
+ 1)
177 class Remasterer( QApplication
):
178 """ The main application, also sets up the Qt event loop """
180 def __init__( self
, args
):
181 QApplication
.__init
__( self
, args
)
184 # Start separate thread for reading data from stdin
185 self
.stdinReader
= threading
.Thread( target
= self
.readStdin
)
186 self
.stdinReader
.start()
191 # ugly hack, thanks mp8 anyway
192 os
.system("dcop amarok script removeCustomMenuItem \"Amarok live\" \"Add playlist to livecd\"")
193 os
.system("dcop amarok script removeCustomMenuItem \"Amarok live\" \"Add selected to livecd\"")
194 os
.system("dcop amarok script removeCustomMenuItem \"Amarok live\" \"Create Remastered CD\"")
195 os
.system("dcop amarok script removeCustomMenuItem \"Amarok live\" \"Clear Music on livecd\"")
197 os
.system("dcop amarok script addCustomMenuItem \"Amarok live\" \"Add playlist to livecd\"")
198 os
.system("dcop amarok script addCustomMenuItem \"Amarok live\" \"Add selected to livecd\"")
199 os
.system("dcop amarok script addCustomMenuItem \"Amarok live\" \"Create Remastered CD\"")
200 os
.system("dcop amarok script addCustomMenuItem \"Amarok live\" \"Clear Music on livecd\"")
203 def readSettings( self
):
204 """ Reads settings from configuration file """
207 path
= config
.get( "General", "path" )
210 debug( "No config file found, using defaults." )
213 ############################################################################
214 # Stdin-Reader Thread
215 ############################################################################
217 def readStdin( self
):
218 """ Reads incoming notifications from stdin """
221 # Read data from stdin. Will block until data arrives.
222 line
= sys
.stdin
.readline()
225 qApp
.postEvent( self
, Notification(line
) )
230 ############################################################################
231 # Notification Handling
232 ############################################################################
234 def customEvent( self
, notification
):
235 """ Handles notifications """
237 string
= QString(notification
.string
)
238 debug( "Received notification: " + str( string
) )
240 if string
.contains( "configure" ):
242 if string
.contains( "stop"):
245 elif string
.contains( "customMenuClicked" ):
246 if "selected" in string
:
247 self
.copyTrack( string
)
248 elif "playlist" in string
:
250 elif "Create" in string
:
252 elif "Clear" in string
:
256 # Notification callbacks. Implement these functions to react to specific notification
257 # events from Amarok:
259 def configure( self
):
260 debug( "configuration" )
262 self
.dia
= ConfigDialog()
264 #self.connect( self.dia, SIGNAL( "destroyed()" ), self.readSettings )
268 self
.dia
= ConfigDialog()
269 path
, iso
= self
.dia
.readConfig()
271 os
.system("rm -rf %s/amarok.live/music/* %s/amarok.live/playlist/* %s/amarok.live/home/amarok/.kde/share/apps/amarok/current.xml" % (path
, path
, path
))
273 def onSignal( self
, signum
, stackframe
):
278 fd
= open("/tmp/amarok.stop", "w")
279 fd
.write( "stopping")
282 os
.system("dcop amarok script removeCustomMenuItem \"Amarok live\" \"Add playlist to livecd\"")
283 os
.system("dcop amarok script removeCustomMenuItem \"Amarok live\" \"Add selected to livecd\"")
284 os
.system("dcop amarok script removeCustomMenuItem \"Amarok live\" \"Create Remastered CD\"")
285 os
.system("dcop amarok script removeCustomMenuItem \"Amarok live\" \"Clear Music on livecd\"")
288 def copyPlaylist( self
):
290 self
.dia
= ConfigDialog()
291 path
, iso
= self
.dia
.readConfig()
293 os
.system("dcop amarok playlist popupMessage 'Please run configure first.'")
296 tmpfileloc
= os
.tmpnam()
297 os
.system("dcop amarok playlist saveM3u '%s' false" % tmpfileloc
)
298 tmpfile
= open(tmpfileloc
)
304 for line
in tmpfile
.readlines():
310 name
= line
.split("/")[-1]
313 url
= "file://" + urllib
.quote(line
)
316 livecdpath
= "/music/" + name
319 m3u
+= livecdpath
+ "\n"
323 files
= files
.strip()
325 os
.system("kfmclient copy %s file://%s/amarok.live/music/" % (files
, path
))
328 suffix
= random
.randint(0,10000)
329 # os.system("mkdir %s/amarok.live/home/amarok/.kde/share/apps/amarok/playlists/" % path)
330 m3uOut
= open("/tmp/amarok.live.%s.m3u" % suffix
, 'w')
337 os
.system("mv /tmp/amarok.live.%s.m3u %s/amarok.live/playlist/" % (suffix
,path
))
338 os
.system("rm /tmp/amarok.live.%s.m3u" % suffix
)
341 os
.remove(tmpfileloc
)
343 def copyTrack( self
, menuEvent
):
345 event
= str( menuEvent
)
347 self
.dia
= ConfigDialog()
349 path
,iso
= self
.dia
.readConfig()
351 os
.system("kdialog --sorry 'You have not specified where the Amarok live iso is. Please click configure and do so first.'")
353 # get the list of files. yes, its ugly. it works though.
354 #files = event.split(":")[-1][2:-1].split()[2:]
355 #trying out a new one
356 #files = event.split(":")[-1][3:-2].replace("\"Amarok live!\" \"add to livecd\" ", "").split("\" \"")
359 files
= event
.replace("customMenuClicked: Amarok live Add selected to livecd", "").split()
363 allfiles
+= file + " "
364 allfiles
= allfiles
.strip()
365 os
.system("kfmclient copy %s file://%s/amarok.live/music/" % (allfiles
, path
))
367 def createCD( self
):
369 self
.dia
= ConfigDialog()
370 path
,iso
= self
.dia
.readConfig()
372 os
.system("kdialog --sorry 'You have not configured Amarok live! Please run configure.")
374 fd
= os
.popen("kde-config --prefix", "r")
375 kdedir
= fd
.readline()
376 kdedir
= kdedir
.strip()
377 scriptdir
= kdedir
+ "/share/apps/amarok/scripts/amarok_live"
380 os
.system("kdesu sh %s/amarok.live.remaster.part2.sh %s" % (scriptdir
, path
))
382 fd
= open("/tmp/amarok.script", 'r')
385 if y
== "end": # user said no more, clear path
390 ############################################################################
392 def onSignal( signum
, stackframe
):
393 fd
= open("/tmp/amarok.stop", "w")
394 fd
.write( "stopping")
399 os
.system("dcop amarok script removeCustomMenuItem \"Amarok live\" \"Add playlist to livecd\"")
400 os
.system("dcop amarok script removeCustomMenuItem \"Amarok live\" \"Add selected to livecd\"")
401 os
.system("dcop amarok script removeCustomMenuItem \"Amarok live\" \"Create Remastered CD\"")
402 os
.system("dcop amarok script removeCustomMenuItem \"Amarok live\" \"Clear Music on livecd\"")
405 def debug( message
):
406 """ Prints debug message to stdout """
408 print debug_prefix
+ " " + message
411 app
= Remasterer( sys
.argv
)
413 # not sure if it works or not... playing it safe
418 if __name__
== "__main__":
420 mainapp
= threading
.Thread(target
=main
)
422 signal
.signal(15, onSignal
)
423 print signal
.getsignal(15)