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

Reply via email to