Author: duncan
Date: Thu Nov 30 10:22:29 2006
New Revision: 8679
Added:
branches/rel-1/freevo/src/plugins/cd_burn.py
Modified:
branches/rel-1/freevo/ChangeLog
branches/rel-1/freevo/freevo_config.py
branches/rel-1/freevo/local_conf.py.example
branches/rel-1/freevo/src/plugins/idlebar/__init__.py
branches/rel-1/freevo/src/plugins/idlebar/diskfree.py
Log:
[ 1605919 ] cd_burn plugin in the main package
[ 1605951 ] Allow the idlebar clock's format string in local_conf.py
[ 1605953 ] Allow the idlebar diskfree levels to be set in local_conf.py
These plug-ins have been added or updated
Modified: branches/rel-1/freevo/ChangeLog
==============================================================================
--- branches/rel-1/freevo/ChangeLog (original)
+++ branches/rel-1/freevo/ChangeLog Thu Nov 30 10:22:29 2006
@@ -21,6 +21,7 @@
* Replaced mmpython with kaa.base and kaa.metadata (F#1580712)
* New apple trailers plugin (disabled by default) (F#1580418)
+ * New CD/DVD burn plug-in added (F#1605919)
* New encoding server, allows re-encoding TV programs and ripping DVDs
(F#1580642,F#1578402)
* New home automation plug-in, allows controlling device in the home!
(F#1605293)
* New Linux event device support (F#1579124)
@@ -28,6 +29,8 @@
* New XM online plugin (F#1580412)
* New webserver library, allows playing/viewing on local and host machines
(F#1592806)
* Updated autocrop to take more samples from different parts of the video
(F#1591170)
+ * Updated idlebar clock plug-in to allow CLOCK_FORMAT to be used (F#1605951)
+ * Updated idlebar diskfree plug-in to allow the bar colours levels to be set
(F#1605953)
* Updated DEBUGGING, IP, PORT, UID and GUI based on helper name (F#1580628)
* Updated helper convert_config (F#1578183)
* Updated imdb movie parsing to use BeautifulSoup (F#1590928)
Modified: branches/rel-1/freevo/freevo_config.py
==============================================================================
--- branches/rel-1/freevo/freevo_config.py (original)
+++ branches/rel-1/freevo/freevo_config.py Thu Nov 30 10:22:29 2006
@@ -752,7 +752,10 @@
plugin.activate('idlebar.tv', level=20)
plugin.activate('idlebar.cdstatus', level=25)
plugin.activate('idlebar.diskfree', level=30)
-plugin.activate('idlebar.clock', level=50, args='%a %d %H:%M')
+DISKFREE_VERY_LOW = 8 # In Gigabytes
+DISKFREE_LOW = 20
+plugin.activate('idlebar.clock', level=50)
+CLOCK_FORMAT = '%a %d %H:%M'
# ======================================================================
# Headlines
Modified: branches/rel-1/freevo/local_conf.py.example
==============================================================================
--- branches/rel-1/freevo/local_conf.py.example (original)
+++ branches/rel-1/freevo/local_conf.py.example Thu Nov 30 10:22:29 2006
@@ -375,13 +375,13 @@
# plugin.activate('joy')
-# ======================================================================
+# ----------------------------------------------------------------------
# Headlines
#
# You are free to use any rss feeds in the HEADLINES_LOCATIONS below
# These are just working examples for the Freevo feeds.
# To turn off Headlines add plugin.remove('headlines')
-# ======================================================================
+# ----------------------------------------------------------------------
#plugin.activate('headlines', level=45)
#HEADLINES_LOCATIONS = [
# ('Freevo news releases',
'http://sourceforge.net/export/rss2_projnews.php?group_id=46652'),
@@ -391,6 +391,18 @@
#]
+# ----------------------------------------------------------------------
+# CD Burning
+# ----------------------------------------------------------------------
+# plugin.activate('cd_burn')
+# CDBURN_AUDIO_DAO = 1
+# CDBURN_MKISOFS_PATH = '/usr/bin/mkisofs'
+# CDBURN_CDRECORD_PATH = '/usr/bin/cdrecord'
+# CDBURN_TEMP_DIR='/tmp/'
+# CDBURN_DEV = '/dev/hdc'
+# CDBURN_SPEED = 32
+
+
# ======================================================================
# Freevo directory settings:
# ======================================================================
@@ -1366,7 +1378,12 @@
# plugin.activate('idlebar.tv', level = 20)
# plugin.activate('idlebar.cdstatus', level = 25)
# plugin.activate('idlebar.diskfree', level = 30)
-# plugin.activate('idlebar.clock', level = 50, args='%a %d %H:%M')
+# plugin.activate('idlebar.clock', level = 50)
+# CLOCK_FORMAT = '%a %d %H:%M'
+#
+# settings for the idlebar.diskfree plug-in, in Gigabytes
+# DISKFREE_VERY_LOW = 8 # less than this shows a red bar
+# DISKFREE_LOW = 20 # less than this shows an orange bar
#
# display proc-stats, CPU and RAM usage
# plugin.activate('idlebar.system.procstats',level=20)
Added: branches/rel-1/freevo/src/plugins/cd_burn.py
==============================================================================
--- (empty file)
+++ branches/rel-1/freevo/src/plugins/cd_burn.py Thu Nov 30 10:22:29 2006
@@ -0,0 +1,903 @@
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------
+# cd_burn.py - Plugin for copying files to a cd
+# -----------------------------------------------------------------------
+# $Id: ossmixer.py 8441 2006-10-21 11:15:52Z duncan $
+#
+# Notes:
+#
+# And to activate:
+# plugin.activate('cd_burn')
+#
+# CDBURN_AUDIO_DAO = 1
+# CDBURN_MKISOFS_PATH = '/usr/bin/mkisofs'
+# CDBURN_CDRECORD_PATH = '/usr/bin/cdrecord'
+# CDBURN_TEMP_DIR='/tmp/'
+# CDBURN_DEV = '/dev/hdc'
+# CDBURN_SPEED = 32
+#
+# - You can now burn DVD Video from your rips
+# - BurnCD is now a sub menu
+# - Directory burning
+#
+# Todo:
+#
+# -----------------------------------------------------------------------
+# Freevo - A Home Theater PC framework
+# Copyright (C) 2002 Krister Lagerstrom, et al.
+# Please see the file freevo/Docs/CREDITS for a complete list of authors.
+#
+# 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 MER-
+# CHANTABILITY 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 threading
+import re
+import shutil
+
+import util.fileops
+import plugin
+import rc
+
+import os
+import pickle
+
+import string
+import menu
+import plugin
+import time
+import item
+import re
+import glob
+import config
+import popen2
+import signal
+
+import select
+import fcntl
+
+from gui.PopupBox import PopupBox
+from gui.Button import Button
+from gui.ProgressBox import ProgressBox
+from gui.ConfirmBox import ConfirmBox
+from gui.AlertBox import AlertBox
+#from gui.YesNoBox import YesNoBox
+from popen2 import Popen3,Popen4
+#from os import *
+from stat import *
+#from os.path import *
+from event import *
+
+class MyProgressBox(ProgressBox):
+ def __init__(self, text, x=None, y=None, width=0, height=0,
+ icon=None, vertical_expansion=1, text_prop=None,
+ full=0, parent='osd', handler=None,initial_progress=0):
+
+ ProgressBox.__init__(self, text, x, y, width, height,
+ icon, vertical_expansion, text_prop,
+ full, parent);
+
+ b1 = Button(_('OK'))
+ b1.toggle_selected()
+
+ self.add_child(b1)
+
+ self.progressbar.position = initial_progress
+
+ def set_progress(self, progress):
+ _debug_('set_progress');
+ while self.progressbar.position < progress:
+ self.tick()
+ def eventhandler(self, event):
+ _debug_('eventhandler');
+ if event in (INPUT_ENTER, INPUT_EXIT):
+ self.destroy()
+ if self.handler:
+ self.handler()
+ else:
+ return self.parent.eventhandler(event)
+
+class Logger:
+ def __init__(self):
+ _debug_('__init__');
+ self.filename = '%s/%s-%s.log' % (config.LOGDIR, 'burn_cd-helpers',
os.getuid())
+ self.file = file(self.filename,"a")
+
+ def log (self,line=None):
+ self.file.write(line + "\n")
+ self.file.flush()
+
+class BurnCDItem:
+ def
__init__(self,item,filename=None,plugin=None,menu=None,burn_mode="data_cd"):
+ _debug_('__init__');
+ self.item = item
+ self.menuw = menu
+ self.plugin = plugin
+ self.files = []
+ self.volume_name = None
+ self.burn_mode = burn_mode
+
+ def menu_back (self):
+ _debug_('menu_back ');
+ # go back in menustack
+ #for i in range(2):
+ for i in range(1):
+ self.menuw.back_one_menu(arg='reload')
+ self.menuw.refresh
+
+
+
+ #starts de decision process of burning the CD
+ def burn (self, arg=None, menuw=None):
+ _debug_('burn ');
+ if self.burn_mode == "data_cd":
+ self.burn_data_cd()
+ elif self.burn_mode == "dvd_video":
+ self.burn_dvd_video()
+ elif self.burn_mode == "audio_cd":
+ self.burn_audio_cd()
+ else:
+ AlertBox(text=_('Not Yet implemented :)')).show()
+ return
+
+ #checks if the file "program" with the program name exists and is
executable
+ #if not displays a alert box and returns 0
+ def check_program (self, program=None, program_name=None) :
+ _debug_('check_program ');
+ if not ( os.path.exists(program) and os.path.isfile(program) and
os.access(program, os.X_OK) ) :
+ print "CDBURN : Progam Error"
+ AlertBox(text=_('Cannot find %s (%s). Please configure the right
path in your config file and make sure it has the right permissions.' %
(program_name,program)), handler=self.menu_back).show()
+ return 0
+ else:
+ return 1
+
+ def burn_audio_cd(self):
+ _debug_('burn_audio_cd');
+ """
+ Checks for burnlist cleanup, mplayer availability
+ """
+ if not self.check_program(program=config.MPLAYER_CMD,
program_name="mplayer"):
+ return
+
+ if not self.clean_up_burndir():
+ return
+
+ ConfirmBox(text=_('Start burning %s audio files?' % len(self.files)),
+ handler=self.start_burning, default_choice=0).show()
+
+ def burn_dvd_video(self):
+ _debug_('burn_dvd_video');
+ """
+ copy this DIR to DVD as DVD VIDEO, NB: MUST BE DVD VIDEO
ALREADY!!!!!!! (ie ripped with dvdcopy.py)
+ """
+
+ name = self.files[0].split("/")
+ self.name = name[len(name) -1]
+ print 'CDBURN : self.name = %s' % self.name
+ dir = self.files[0]
+ self.dir = dir + "/"
+ print 'CDBURN : self.dir = %s ' % self.dir
+ for f in os.listdir(self.dir):
+ pathname = os.path.join(self.dir, f)
+ print 'CDBURN : %s ' % pathname[-3:]
+ if pathname[-3:].lower() == '_ts':
+ print 'CDBURN : would not delete %s' %pathname
+ self.file_to_delete = None
+ else:
+ print 'CDBURN : would delete %s' % pathname
+ #self.file_to_delete.append(pathname)
+ self.file_to_delete = pathname
+
+ if self.file_to_delete:
+ ConfirmBox(text=_('Delete %s?' % self.file_to_delete ),
+ handler=self.delete_now, default_choice=0).show()
+ else:
+ ConfirmBox(text=_('Insert media then click OK'),
+ handler=self.start_burning, default_choice=0
+ ).show()
+ return
+
+ def delete_now (self, arg=None, menuw=None):
+ _debug_('delete_now ');
+ """
+ Called by burn_dvd_video to remove anything it sees fit.. I think
+ freevo should have a file op for this but it doesn't (that i can find).
+ """
+ for a in self.files_to_delete:
+ try:
+ mode = os.stat(a)[ST_MODE]
+ if S_ISDIR(mode):
+ try:
+ shutil.rmtree(a)
+ except:
+ rc.post_event(Event(OSD_MESSAGE, arg=_('Error, unable
to delete dir %s' % a)))
+ print "CDBURN : unable to delete tree %s" %a
+ elif S_ISREG(mode):
+ try:
+ os.unlink(a)
+ except:
+ rc.post_event(Event(OSD_MESSAGE, arg=_('Error, unable
to delete file %s' % a)))
+ print "CDBURN : unable to delete %s" %a
+ except:
+ pass
+ self.burn()
+
+
+ #asks confirmation for the burning of a data CD
+ #if confirmation given it calls start_burning
+ def burn_data_cd (self) :
+ _debug_('burn_data_cd ');
+ #lets check if we have all we need
+ if not self.check_program(program=config.CDBURN_CDRECORD_PATH,
program_name="cdrecord"):
+ print "CDBURN : Unable to find %s" %config.CDBURN_CDRECORD_PATH
+ return
+ if not self.check_program(program=config.CDBURN_MKISOFS_PATH,
program_name="mkisofs"):
+ print "CDBURN : Unable to find %s" %config.CDBURN_MKISOFS_PATH
+ return
+
+ if not self.clean_up_burndir():
+ return
+
+ #if list of files not to big just display it
+ if len( self.files) <= 4:
+ ConfirmBox(text=_('Start burning %s ?' % self.files),
+ handler=self.start_burning, default_choice=0).show()
+ #else display the size of the burning
+ else:
+ t_sum = 0
+ t_files = len(self.files)
+ for a in self.files:
+ c = os.stat(a)[ST_SIZE]
+ t_sum = t_sum + (int(c)/1024/1024)
+
+ ConfirmBox(text=_('Start burning %s entries? ( %d Mb )' %
(t_files, t_sum)),
+ handler=self.start_burning, default_choice=0).show()
+
+
+ def clean_up_burndir (self):
+ _debug_('clean_up_burndir ');
+ """
+ Tries to cleanup /tmp/burndir, if it not exists it try's to create it
+ the final result of this function must a be a existing and empty
+ /tmp/burnlist
+ """
+ try:
+ _debug_('in Try 2');
+ if not os.stat("/tmp/burnlist"):
+ _debug_('in if 2');
+ os.makedirs("/tmp/burnlist", 0777)
+ else:
+ _debug_('in else 2');
+ if os.listdir("/tmp/burnlist"):
+ os.system('rm -rf /tmp/burnlist/*')
+ except:
+ _debug_('in except 2');
+ os.makedirs("/tmp/burnlist", 0777)
+ os.system('rm -rf /tmp/burnlist/*')
+
+ try:
+ _debug_('in Try 1');
+ if os.stat("/tmp/burnlist"):
+ _debug_('in if 1');
+ for a in os.listdir("/tmp/burnlist"):
+ os.unlink("/tmp/burnlist/" + a)
+ except:
+ _debug_('in except 1');
+ AlertBox(text='"Aborted, could not empty /tmp/burnlist"')
+ _debug_('clean_up_burndir end1');
+ return 0
+
+ _debug_('clean_up_burndir end');
+ return 1
+
+ # Starts the burning thread
+ def start_burning (self, arg=None, menuw=None):
+ _debug_('start_burning ');
+ self.thread_burn = main_burn_thread(token=self)
+ self.thread_burn.start()
+ self.plugin.thread_burn = self.thread_burn
+ self.menu_back()
+
+ #
+ # Routines to find files for burning
+ #
+
+ #Finds the file of a single file item
+ def findFileFromItem (self) :
+ _debug_('findFileFromItem ');
+ print "CDBURN : findFileFromItem() ran"
+ if self.item.filename:
+ print 'CDBURN : findFileFromItem() found item %s'
%self.item.filename
+ self.volume_name = self.item.name
+ self.files.append(self.item.filename)
+
+ #Finds all the files in a dir item
+ def findFromDir (self) :
+ _debug_('findFromDir ');
+ for f in os.listdir(self.item.dir) :
+ self.files.append(self.item.dir+'/'+f)
+
+ #Finds files from item and related.
+ #related files have the same filename that
+ #the item filename but diferent extensions
+ def findRelated (self,mode=0):
+ _debug_('findRelated ');
+ self.files.append(self.item.filename)
+ file = self.item.filename
+ self.volume_name = self.item.name
+
+ rexp = re.compile('(.*)/(.*)\.(.*)')
+ result = rexp.search(file)
+ name = result.group(2)
+ dir = result.group(1)
+ print 'CDBURN : File: %s, Name: %s, Dir: %s' % (file,name,dir)
+ files = glob.glob( dir + '/' + name + '.*' )
+ for k in files:
+ if k == file:
+ continue
+ result = rexp.search(k)
+ ext = result.group(3)
+
+ if mode==0 and (ext == 'fxd' or ext == 'jpg'):
+ continue
+
+ print 'CDBURN : related file: ' + k
+ print 'CDBURN : extension ' + ext
+ self.files.append(k)
+
+ def findFromDirMatches(self,suffix=None):
+ _debug_('findFromDirMatches');
+ #finds all files in a dir matching suffix
+ if not suffix:
+ return
+ matches = util.match_files(dirname=self.item.dir, suffix_list=suffix)
+ self.files = matches
+
+#
+# Thread that really burns the CD
+#
+class main_burn_thread(threading.Thread):
+ def __init__(self, token=None):
+ _debug_('__init__');
+ threading.Thread.__init__(self)
+ self.token = token
+ self.childs = []
+
+ #process progress and status
+ self.running = 0
+ self.progress = 0
+ self.status = ""
+ self.stopping = False
+
+ self.logger = Logger()
+
+ #widget to display the status
+ self.widget = False
+
+ def stop(self):
+ _debug_('stop');
+ self.stopping = True
+ starttime = time.time()
+
+ while self.stopping and (time.time()- starttime < 15):
+ print 'Waiting for the thread to terminate...'
+ time.sleep(1)
+
+
+ def cleanup(self):
+ _debug_('cleanup');
+ for child in self.childs:
+ if child.poll() == 0:
+ continue
+ try:
+ _debug_('killing process group %d with signal 15' %
(child.pid))
+ os.kill(-child.pid, signal.SIGTERM)
+ except OSError:
+ _debug_('killing process group %d FAILED' % (child.pid))
+ pass
+
+ for i in range(20):
+ #_debug_('Waiting for process group %d to terminate...' %
(child.pid))
+ try:
+ p,s = os.waitpid((-child.pid), os.WNOHANG)
+ except OSError:
+ _debug_('Process group %d exited' % (child.pid))
+ break
+ if p == child.pid:
+ _debug_('Process group %d terminated with signal 15' %
child.pid)
+ break
+ time.sleep(0.1)
+ else:
+ try:
+ _debug_('killing process group %d with signal 9' %
(child.pid))
+ os.kill(-child.pid, signal.SIGKILL)
+ except OSError:
+ _debug_('killing process group %d FAILED' % (child.pid))
+ pass
+ for i in range(20):
+ #_debug_('Waiting for process group %d to terminate...' %
(child.pid))
+ try:
+ p,s = os.waitpid(-child.pid, os.WNOHANG)
+ except OSError:
+ _debug_('Process group %d exited' % (child.pid))
+ break
+ if p == child.pid:
+ _debug_('Process group %d terminated with signal 9' %
child.pid)
+ break
+ time.sleep(0.1)
+
+ self.update_status(status='error', description='Aborted by user')
+
+ #mick, all childs are spwaned using this method
+ def run_child(self,cmd=None,cwd=None,wait=0,task_weight=False):
+ _debug_('run_child');
+ """
+ Spwans a child using command cmd.
+ If cwd is filled the os will change to that dir before the spwan
+ If wait is 1 (or True), this function will wait for child "death"
before returning
+ This function returns the child object, if it does not return any
value, the process
+ was aborted.
+ If task_weight is passed, when the child exits the progress is
incremented by the
+ task_wight
+ """
+ if cwd:
+ _debug_("CDBURN : Changing working dir to %s" % cwd)
+ os.chdir(cwd)
+
+ cmd = cmd + " 2>&1"
+
+ child_app = util.popen3.Popen4(cmd)
+
+ self.logger.log(cmd)
+ self.childs.append(child_app)
+
+ if wait:
+ print 'CDBURN : Waiting for %s' % child_app.pid
+
+ self.makeNonBlocking(child_app.fromchild.fileno())
+
+ while child_app.poll() < 0:
+ #print "CDBURN : Polled %s (pid : %s), status is %s" %
(cmd,child_app.pid,child_app.poll())
+ if self.stopping:
+ self.cleanup()
+ self.stopping = False
+ return
+
+ try:
+ """
+ This allow us to parse the output of the commands,
+ its a approach to the status bar
+ """
+ while 1:
+ line = child_app.fromchild.readline()
+ if line:
+ pass
+ self.logger.log(line[0:-1])
+ #TODO, call the parser to get the progress
+ else:
+ break
+ except IOError:
+ #the fd was not ready to read
+ pass
+
+ #print 'CDBURN : string = %s' % last_string
+
+ time.sleep(1)
+
+ print 'CDBURN : %s exited with code %s' % (cmd,child_app.poll())
+ if task_weight:
+ self.progress = self.progress + task_weight
+ self.update_progress(self.progress)
+ if self.stopping:
+ self.cleanup()
+ self.stopping = False
+ return
+ return child_app
+
+ def makeNonBlocking(self,fd):
+ _debug_('makeNonBlocking');
+ fl = fcntl.fcntl(fd, fcntl.F_GETFL)
+ try:
+ fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NDELAY)
+ except AttributeError:
+ fcntl.fcntl(fd, fcntl.F_SETFL, fl | fcntl.FNDELAY)
+
+ def show_status(self,arg=None, menuw=None):
+ _debug_('show_status');
+ """
+ The thread has is own status widget
+ """
+ self.widget = MyProgressBox(text=_('Burning status: %s' % self.status
),
+ handler=self.hide_status,full=100,
+ initial_progress=self.progress )
+ self.widget.show()
+
+ def hide_status(self,arg=None, menuw=None):
+ _debug_('hide_status');
+ w = self.widget;
+ self.widget = False;
+ if w:
+ w.destroy
+
+ def update_progress(self,progress=0):
+ _debug_('update_progress');
+ self.progress=progress
+ if self.widget:
+ self.widget.set_progress(progress)
+ self.widget.draw(update=True)
+
+ def update_status(self, status='running', description=None):
+ _debug_('update_status');
+ """
+ Is used to change the status of the process.
+ The status can be: running, error, done
+ The description should be a string describing the status of the process.
+ """
+ if status == 'error':
+ self.status = "Error : " + description
+ self.running = 0
+ self.elapsed = (time.time() - self.starttime)
+ self.progress=100
+ elif status == 'running':
+ if self.running == 0:
+ #first time running is called
+ self.running = 1
+ self.starttime = time.time()
+ self.status = description
+ elif status == 'done':
+ self.running = 0
+ self.elapsed = (time.time() - self.starttime)
+ self.status = description or "Burn sucessfull (in %s sec)" %
self.elapsed
+ print "CD_BURN : " + self.status
+ self.progress=100
+
+ if self.widget:
+ print "Updating"
+ self.widget.set_progress(self.progress)
+ self.widget.label.set_text(self.status)
+ self.widget.draw(update=True)
+
+ def run(self, arg=None, menuw=None, token=None):
+ _debug_('run');
+ """
+ Starts the burning process and helpers
+ """
+
+ print 'CDBURN : running burning thread with token.burn_mode = %s' %
self.token.burn_mode
+
+ if self.token.burn_mode == "data_cd":
+ self.update_status(status="running", description="Creating disc
image")
+
+ """
+ Links the files to Burn in /tmp/burnlist
+ """
+ for a in self.token.files:
+ path = re.split("\\/", a)
+ os.symlink(a, "/tmp/burnlist/" + path[-1])
+
+ print "CDBURN : start burning"
+
+ """
+ copy files into a CD
+ """
+ if not self.token.volume_name:
+ self.token.volume_name = self.token.item.type
+
+ image_file = config.CDBURN_TEMP_DIR + "/image.img"
+ burn_list = config.CDBURN_TEMP_DIR + "/burnlist/"
+
+ mkisofs_cmd = '%s -f -U -V "%s" -o %s %s' %
(config.CDBURN_MKISOFS_PATH,self.token.volume_name,image_file,burn_list)
+ child = self.run_child(cmd=mkisofs_cmd,wait=1,task_weight=50)
+ if not child:
+ return
+
+ if child.poll() != 0:
+ self.update_status(status="error",description="Could
not create the image file")
+ return
+
+ print 'CDBURN : Mkisofs done'
+ self.status = "Burning files to CD"
+
+ cdrecord_cmd = '%s -eject -v -driveropts=burnfree speed=%s
dev=%s %s' %
(config.CDBURN_CDRECORD_PATH,config.CDBURN_SPEED,config.CDBURN_DEV,image_file)
+
+ rec_child =
self.run_child(cmd=cdrecord_cmd,wait=1,task_weight=50)
+
+ if not rec_child:
+ return
+
+ if rec_child.poll() != 0:
+ self.update_status(status='error', description='Could
not burn image file to CD');
+ return
+
+ os.unlink(image_file)
+
+ elif self.token.burn_mode == "dvd_video":
+ growisofs_cmd = 'growisofs -use-the-force-luke -dvd-compat -Z
/dev/dvd -V %s -dvd-video %s' % (self.token.name,self.token.dir)
+ self.update_status(status='running', description='Burning DVD
Video');
+ burn_child =
self.run_child(cmd=growisofs_cmd,wait=1,task_weight=100)
+ if (not burn_child):
+ return
+
+ if burn_child.poll() != 0:
+ self.update_status(status="error",description="Could
not burn DVD")
+ return
+
+ #rc.register(self.burn_status, False, 2000)
+
+
+ elif self.token.burn_mode == "audio_cd":
+ #All tracks are about 70% of the total process percentage
+ track_percent = 70/len(self.token.files);
+ for a in self.token.files:
+ status_line = "Converting %s" % os.path.basename(a)
+
self.update_status(status='running',description=status_line)
+
+ print "CDBURN : Converting %s" % os.path.basename(a)
+ convert_cmd = 'mplayer -ao pcm:waveheader -vc null -vo
null "%s"' % a
+
+ conv_child =
self.run_child(cmd=convert_cmd,cwd='/tmp/burnlist',wait=1,task_weight=track_percent)
+ if not conv_child:
+ return
+
+ if conv_child.poll() != 0:
+
self.update_status(status="error",description=_("Error : Could not convert %s"
% os.path.basename(a)))
+ return
+
+ print "CDBURN : Conversion done"
+ rename_wav = '%s.wav' % (config.os.path.basename(a))
+ os.rename('/tmp/burnlist/audiodump.wav',
_('/tmp/burnlist/%s' % rename_wav))
+
+ self.update_status(status='running',description="Burning Audio
to CD")
+ audio_mode = config.CDBURN_AUDIO_DAO;
+ if audio_mode == 1:
+ audio_mode = "-dao"
+ else:
+ audio_mode = ""
+ cdrec_cmd = '%s -audio -s -eject -v -driveropts=burnfree
speed=%s dev=%s %s -pad -useinfo /tmp/burnlist/*' % \
+
(config.CDBURN_CDRECORD_PATH,config.CDBURN_SPEED,config.CDBURN_DEV,audio_mode)
+ print 'CDBURN : %s' % cdrec_cmd
+
+ rec_child = self.run_child(cmd=cdrec_cmd,wait=1)
+ if not rec_child:
+ return
+
+ if rec_child.poll() != 0:
+ self.update_status(status="error",description='Could
burn audio tracks to CD')
+ return
+
+ #lets wait for all childs to stop
+ for child in self.childs:
+ while child.poll() < 0:
+ child.fromchild.readlines()
+ _debug_('CDBURN : Waiting for process %d...' % child.pid)
+ time.sleep(1)
+
+ self.update_status(status='done');
+ return
+
+
+class PluginInterface(plugin.ItemPlugin):
+ """
+ Enables writing selected item to compatable device. So far we can burn
+ files to cd, DVD (VIDEO_TS) to video dvd, and files (mp3 and Ogg) to
+ Audio cd.
+
+ Place cd_burn.py in:
+ freevo/plugins/.
+
+ Activate in local_conf.py by:
+ plugin.activate(cd_burn)
+ """
+
+ def __init__(self):
+ _debug_('__init__');
+ plugin.ItemPlugin.__init__(self)
+ self.device = ''
+ self.item = None
+ self.thread_burn = None
+ self.dev_list = []
+
+ def config(self):
+ _debug_('config');
+ self.dev_list = []
+ """
+ time for some auto stuff...
+ """
+ child = popen2.Popen4('cdrecord -scanbus')
+ while child.poll() < 0:
+ # print child.pid
+
+ try:
+ while 1:
+ line = child.fromchild.readline()
+
+ #if line and ('RW' in line):
+ if line and (line.find('RW') != -1):
+ # print line
+ burn_dev = line.split()[0]
+# print burn_dev
+ self.dev_list.append(burn_dev)
+ else:
+ #this is needed to get out of while loop..
+ break
+ except IOError:
+ print "no line"
+ time.sleep(0.1)
+
+ if len(self.dev_list) and self.dev_list[0]:
+ record_dev = self.dev_list[0]
+ else:
+ record_dev = 'ATAPI:0,0,0'
+
+ return [ ('CDBURN_CDRECORD_PATH', '/usr/bin/cdrecord', 'Path to
cdrecord'),
+ ('CDBURN_MKISOFS_PATH', '/usr/bin/mkisofs', 'Path to
mkisofs'),
+ # bruno:
+ # in tao (track at once mode, empty value) cd record will
leave 2 sec gaps between tracks
+ # in dao (disk at once) no gaps at all, but not all drives
support it
+ ('CDBURN_AUDIO_DAO',0,'CDRecord canburn audio cds in DAO
mode'),
+ ('CDBURN_SPEED', '8', 'Speed to burn with cdrecord'),
+ ('CDBURN_TEMP_DIR', '/tmp/', 'Temp file name used by
cdrecord'),
+ ('CDBURN_DEV', record_dev, 'Device for cdrecord to burn with
(not auto detected)') ]
+
+ def stop_burning(self, arg, menuw=None):
+ _debug_('stop_burning');
+ pop = PopupBox(text=_('Interrupting burning process...'))
+ pop.show()
+
+ self.thread_burn.stop()
+ pop.destroy()
+
+ if menuw:
+ menuw.back_one_menu(arg='reload')
+ menuw.refresh
+
+ AlertBox(text=_('Backup interrupted')).show()
+
+ def actions(self, item):
+ _debug_('actions');
+ self.item = item
+ show_burn_menu = 0;
+
+ print _('CDBURN : Item type is %s' % item.type)
+
+ if self.thread_burn and self.thread_burn.running == 1:
+ show_burn_menu = 1;
+
+ if ( item.type == 'audio' or item.type == 'image' or item.type ==
'video' or item.type == 'dir' ):
+ show_burn_menu = 1;
+
+ print _('CDBURN : Should show the menu? %i' % show_burn_menu)
+
+ if show_burn_menu:
+ return [ (self.fill_menu, 'Burn CD') ]
+ else:
+ return []
+
+ def draw_menu(self,menuw=None,items=None):
+ _debug_('draw_menu');
+ #draws the menu with the options on the screen
+ menu_items = []
+ if items:
+
+ for a in items:
+ menu_items.append(menu.MenuItem(a[1],a[0]))
+
+ moviemenu = menu.Menu(_('CD Burn Menu'), menu_items)
+ menuw.pushmenu(moviemenu)
+
+
+ def fill_menu(self,arg=None, menuw=None):
+ _debug_('fill_menu');
+ #chooses the options available for this type of item
+ to_return = []
+ item = self.item
+ print "CDBURN : Item type = %s" % item.type
+ if self.thread_burn and self.thread_burn.running == 1:
+ to_return.append( (self.thread_burn.show_status, 'Show burning
status' ));
+ to_return.append( (self.stop_burning, 'Stop the burn process' ));
+ return self.draw_menu(menuw=menuw,items=to_return)
+
+
+ if item.type == 'dir':
+ #dirs
+ print 'CDBURN : Dir has media : %s ' % item.media
+ try:
+ cur = BurnCDItem(item=item, plugin=self,menu=menuw)
+ cur.findFromDir()
+
+ cur2 = BurnCDItem(item=item,
plugin=self,menu=menuw,burn_mode="audio_cd")
+ cur2.findFromDirMatches(suffix=['mp3','flac','ogg','wav'])
+
+ if cur.files:
+ to_return.append(( cur.burn, 'Copy dir to CD') )
+ if len(cur2.files)>0:
+ to_return.append(( cur2.burn, 'Burn audio files (MP3, Wav and Ogg)
as Audio CD'))
+ except Exception, e:
+ print e
+ pass
+
+ try:
+ #any item except dirs
+ if (not item.subitems) and (not item.type == 'dir') :
+ cur = BurnCDItem(item=item, plugin=self,menu=menuw)
+ cur.findFileFromItem()
+ #cur.addFilesFromItem()
+ if cur.files:
+ to_return.append( ( cur.burn, _('Copy this file to CD')) )
+
+ #any joined item except dirs
+ elif not item.type == 'dir' and item.subitems:
+ for a in item.subitems:
+ cur = BurnCDItem(item=a, plugin=self,menu=menuw)
+ cur.findFileFromItem()
+ if cur.files:
+ to_return.append( ( cur.burn, _('Copy %s to CD' %
a.name )) )
+
+ except:
+ pass
+
+
+ #single video file
+ try:
+ if item.filename and item.type == 'video' and ( not item.subitems):
+ cur = BurnCDItem(item=item, plugin=self,menu=menuw)
+ cur.findRelated()
+ #cur2 = BurnCDItem(ite=item, plugin=self,menu=menuw)
+ #cur2.findRelated(mode=1)
+
+ if len(cur.files) > 1:
+ to_return.append(( cur.burn, _('Copy %s, and related, to CD' %
item.name)) )
+ #to_return.append(( cur2.delete, _('Delete %s, and related' %
item.name)) )
+ except:
+ pass
+
+ #joined video files
+ try:
+ if item.subitems:
+ if item.type == 'video':
+ for a in item.subitems:
+ if a.filename:
+ cur = BurnCDItem(item=a, plugin=self,menu=menuw)
+ cur.findRelated()
+
+ if len(cur.files) > 1:
+ to_return.append(( cur.burn, _('Copy %s, and
related, file to CD' % a.name)) )
+ except:
+ pass
+
+ #DVD movie on file system (ir DIR containing VIDEO_TS and/or AUDIO_TS)
+ #Not sure how freevo works this about but bellow if seems to be fairly
+ #accurate..
+ try:
+ if item.type == 'video' and item.mode == 'dvd' and item.media ==
None:
+ cur = BurnCDItem(item=item, plugin=self, menu=menuw,
burn_mode="dvd_video")
+ cur.findFileFromItem()
+
+ if cur.files and len(cur.files) == 1:
+ print "CDBURN : Adding DVD-VIDEO Item to menu"
+ to_return.append(( cur.burn, 'Burn as DVD-VIDEO disc') )
+ elif len(self.files) > 1:
+ print "CDBURN : To many objects to burn into a DVD Video"
+
+ except:
+ print "CDBURN : Not possible to findFileFromItem for DVD Movie"
+
+ if self.thread_burn and self.thread_burn.running == 0:
+ to_return.append( (self.thread_burn.show_status, 'Show last burn
status/result' ));
+
+ return self.draw_menu(menuw=menuw,items=to_return)
+
+
Modified: branches/rel-1/freevo/src/plugins/idlebar/__init__.py
==============================================================================
--- branches/rel-1/freevo/src/plugins/idlebar/__init__.py (original)
+++ branches/rel-1/freevo/src/plugins/idlebar/__init__.py Thu Nov 30
10:22:29 2006
@@ -153,8 +153,11 @@
"""
def __init__(self, format=''):
IdleBarPlugin.__init__(self)
- if format == '': # No overiding of the default value
- if time.strftime('%P') =='':
+ if config.CLOCK_FORMAT:
+ format = config.CLOCK_FORMAT
+ # No overiding of the default value
+ elif not format:
+ if time.strftime('%P') == '':
format ='%a %H:%M'
else:
format ='%a %I:%M %P'
Modified: branches/rel-1/freevo/src/plugins/idlebar/diskfree.py
==============================================================================
--- branches/rel-1/freevo/src/plugins/idlebar/diskfree.py (original)
+++ branches/rel-1/freevo/src/plugins/idlebar/diskfree.py Thu Nov 30
10:22:29 2006
@@ -97,9 +97,9 @@
self.getDiskFree()
diskimg = self.getimage(self.diskimg, osd)
w,h = diskimg.get_size()
- if self.freespace < 8:
+ if self.freespace < config.DISKFREE_VERY_LOW:
diskbar = self.getimage(self.badimg, osd, True)
- elif self.freespace < 20:
+ elif self.freespace < config.DISKFREE_LOW:
diskbar = self.getimage(self.poorimg, osd, True)
else:
diskbar = self.getimage(self.goodimg, osd, True)
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog