new Desktop runner

This commit is contained in:
Ruud
2012-02-19 17:13:37 +01:00
parent a4a4a6a185
commit 1def62b1b1
3 changed files with 313 additions and 165 deletions
+124 -164
View File
@@ -1,167 +1,127 @@
from threading import Thread #!/usr/bin/env python
from wx.lib.softwareupdate import SoftwareUpdate from logging import handlers
from os.path import dirname
import logging
import os import os
import signal
import subprocess
import sys import sys
import webbrowser import traceback
import wx  
 
# Root path
# Include proper dirs base_path = dirname(os.path.abspath(__file__))
if hasattr(sys, 'frozen'):  
import libs # Insert local directories into path
base_path = os.path.dirname(os.path.dirname(os.path.abspath(libs.__file__))) sys.path.insert(0, os.path.join(base_path, 'libs'))
print base_path  
else: from couchpotato.environment import Env
base_path = os.path.dirname(os.path.abspath(__file__)) from couchpotato.core.helpers.variable import getDataDir
 
lib_dir = os.path.join(base_path, 'libs') class Loader(object):
 
sys.path.insert(0, base_path)     do_restart = False
sys.path.insert(0, lib_dir)  
    def __init__(self):
# Get options via arg  
from couchpotato.runner import getOptions         # Get options via arg
from couchpotato.runner import runCouchPotato         from couchpotato.runner import getOptions
        self.options = getOptions(base_path, sys.argv[1:])
 
class TaskBarIcon(wx.TaskBarIcon):         # Load settings
        settings = Env.get('settings')
TBMENU_OPEN = wx.NewId()         settings.setFile(self.options.config_file)
TBMENU_SETTINGS = wx.NewId()  
TBMENU_ABOUT = wx.ID_ABOUT         # Create data dir if needed
TBMENU_EXIT = wx.ID_EXIT         self.data_dir = os.path.expanduser(Env.setting('data_dir'))
        if self.data_dir == '':
def __init__(self, frame):             self.data_dir = getDataDir()
wx.TaskBarIcon.__init__(self)  
self.frame = frame         if not os.path.isdir(self.data_dir):
            os.makedirs(self.data_dir)
icon = wx.Icon('icon.ico', wx.BITMAP_TYPE_ANY)  
self.SetIcon(icon)         # Create logging dir
        self.log_dir = os.path.join(self.data_dir, 'logs');
self.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.onTaskBarActivate)         if not os.path.isdir(self.log_dir):
            os.mkdir(self.log_dir)
self.Bind(wx.EVT_MENU, self.onOpen, id = self.TBMENU_OPEN)  
self.Bind(wx.EVT_MENU, self.onSettings, id = self.TBMENU_SETTINGS)         # Logging
self.Bind(wx.EVT_MENU, self.onAbout, id = self.TBMENU_ABOUT)         from couchpotato.core.logger import CPLog
self.Bind(wx.EVT_MENU, self.onTaskBarClose, id = self.TBMENU_EXIT)         self.log = CPLog(__name__)
 
        formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', '%H:%M:%S')
def CreatePopupMenu(self):         hdlr = handlers.RotatingFileHandler(os.path.join(self.log_dir, 'error.log'), 'a', 500000, 10)
menu = wx.Menu()         hdlr.setLevel(logging.CRITICAL)
menu.Append(self.TBMENU_OPEN, "Open")         hdlr.setFormatter(formatter)
menu.Append(self.TBMENU_SETTINGS, "Settings")         self.log.logger.addHandler(hdlr)
menu.Append(self.TBMENU_ABOUT, "About")  
menu.Append(self.TBMENU_EXIT, "Close")     def addSignals(self):
return menu  
        signal.signal(signal.SIGINT, self.onExit)
def onOpen(self, event):         signal.signal(signal.SIGTERM, lambda signum, stack_frame: sys.exit(1))
url = self.frame.parent.getSetting('base_url')  
webbrowser.open(url)         from couchpotato.core.event import addEvent
        addEvent('app.after_shutdown', self.afterShutdown)
def onSettings(self, event):  
url = self.frame.parent.getSetting('base_url') + '/settings/'     def afterShutdown(self, restart):
webbrowser.open(url)         self.do_restart = restart
 
def onAbout(self, event):     def onExit(self, signal, frame):
print 'onAbout'         from couchpotato.core.event import fireEvent
        fireEvent('app.crappy_shutdown', single = True)
def onTaskBarActivate(self, evt):  
if not self.frame.IsShown():     def run(self):
self.frame.Show(True)  
self.frame.Raise()         self.addSignals()
 
def onTaskBarClose(self, evt):         from couchpotato.runner import runCouchPotato
wx.CallAfter(self.frame.Close)         runCouchPotato(self.options, base_path, sys.argv[1:], data_dir = self.data_dir, log_dir = self.log_dir, Env = Env)
 
def makeIcon(self, img):         if self.do_restart:
if "wxMSW" in wx.PlatformInfo:             self.restart()
img = img.Scale(16, 16)  
elif "wxGTK" in wx.PlatformInfo:     def restart(self):
img = img.Scale(22, 22)         try:
            # remove old pidfile first
icon = wx.IconFromBitmap(img.CopyFromBitmap())             try:
return icon                 if self.runAsDaemon():
                    self.daemon.delpid()
            except:
class MainFrame(wx.Frame):                 self.log.critical(traceback.format_exc())
 
def __init__(self, parent):             args = [sys.executable] + [os.path.join(base_path, __file__)] + sys.argv[1:]
wx.Frame.__init__(self, None)             subprocess.Popen(args)
        except:
self.parent = parent             self.log.critical(traceback.format_exc())
self.tbicon = TaskBarIcon(self)  
    def daemonize(self):
 
class WorkerThread(Thread):         if self.runAsDaemon():
            try:
def __init__(self, desktop):                 from daemon import Daemon
Thread.__init__(self)                 self.daemon = Daemon(self.options.pid_file)
self._desktop = desktop                 self.daemon.daemonize()
            except SystemExit:
self.start()                 raise
            except:
def run(self):                 self.log.critical(traceback.format_exc())
 
args = ['--nogit', '--console_log']#, '--quiet']     def runAsDaemon(self):
options = getOptions(base_path, args)         return self.options.daemon and  self.options.pid_file
 
try:  
runCouchPotato(options, base_path, args, desktop = self._desktop)
except KeyboardInterrupt, e:
raise
except Exception, e:
raise
finally:
pass
class CouchPotatoApp(wx.App, SoftwareUpdate):
settings = {}
events = {}
restart = False
def OnInit(self):
# Updater
base_url = 'http://couchpotatoapp.com/updates/'
self.InitUpdates(base_url, base_url + 'changelog.txt',
icon = wx.Icon('icon.ico'))
self.frame = MainFrame(self)
self.frame.Bind(wx.EVT_CLOSE, self.onClose)
# CouchPotato thread
self.worker = WorkerThread(self)
return True
def setSettings(self, settings = {}):
self.settings = settings
def getSetting(self, name):
return self.settings.get(name)
def addEvents(self, events = {}):
for name in events.iterkeys():
self.events[name] = events[name]
def onClose(self, event):
onClose = self.events.get('onClose')
if self.events.get('onClose'):
onClose(event)
else:
self.afterShutdown()
def afterShutdown(self, restart = False):
self.frame.Destroy()
self.restart = restart
if __name__ == '__main__': if __name__ == '__main__':
app = CouchPotatoApp(redirect = False)     try:
app.MainLoop()         l = Loader()
        l.daemonize()
#path = os.path.join(sys.path[0].decode(sys.getfilesystemencoding()), sys.argv[0])         l.run()
#if app.restart:     except KeyboardInterrupt:
# wx.Process.Open(sys.executable + ' ' + path)         pass
    except SystemExit:
        raise
    except Exception as (nr, msg):
        if nr != 4:
            try:
                l.log.critical(traceback.format_exc())
            except:
                print traceback.format_exc()
+188
View File
@@ -0,0 +1,188 @@
from threading import Thread
from wx.lib.softwareupdate import SoftwareUpdate
import os
import sys
import webbrowser
import wx
# Include proper dirs
if hasattr(sys, 'frozen'):
import libs
base_path = os.path.dirname(os.path.dirname(os.path.abspath(libs.__file__)))
print base_path
else:
base_path = os.path.dirname(os.path.abspath(__file__))
lib_dir = os.path.join(base_path, 'libs')
sys.path.insert(0, base_path)
sys.path.insert(0, lib_dir)
from couchpotato.environment import Env
class TaskBarIcon(wx.TaskBarIcon):
TBMENU_OPEN = wx.NewId()
TBMENU_SETTINGS = wx.NewId()
TBMENU_ABOUT = wx.ID_ABOUT
TBMENU_EXIT = wx.ID_EXIT
def __init__(self, frame):
wx.TaskBarIcon.__init__(self)
self.frame = frame
icon = wx.Icon('icon.ico', wx.BITMAP_TYPE_ANY)
self.SetIcon(icon)
self.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.onTaskBarActivate)
self.Bind(wx.EVT_MENU, self.onOpen, id = self.TBMENU_OPEN)
self.Bind(wx.EVT_MENU, self.onSettings, id = self.TBMENU_SETTINGS)
self.Bind(wx.EVT_MENU, self.onAbout, id = self.TBMENU_ABOUT)
self.Bind(wx.EVT_MENU, self.onTaskBarClose, id = self.TBMENU_EXIT)
def CreatePopupMenu(self):
menu = wx.Menu()
menu.Append(self.TBMENU_OPEN, "Open")
menu.Append(self.TBMENU_SETTINGS, "Settings")
menu.Append(self.TBMENU_ABOUT, "About")
menu.Append(self.TBMENU_EXIT, "Close")
return menu
def onOpen(self, event):
url = self.frame.parent.getSetting('base_url')
webbrowser.open(url)
def onSettings(self, event):
url = self.frame.parent.getSetting('base_url') + '/settings/'
webbrowser.open(url)
def onAbout(self, event):
print 'onAbout'
def onTaskBarActivate(self, evt):
if not self.frame.IsShown():
self.frame.Show(True)
self.frame.Raise()
def onTaskBarClose(self, evt):
wx.CallAfter(self.frame.Close)
def makeIcon(self, img):
if "wxMSW" in wx.PlatformInfo:
img = img.Scale(16, 16)
elif "wxGTK" in wx.PlatformInfo:
img = img.Scale(22, 22)
icon = wx.IconFromBitmap(img.CopyFromBitmap())
return icon
class MainFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, None)
self.parent = parent
self.tbicon = TaskBarIcon(self)
class WorkerThread(Thread):
def __init__(self, desktop):
Thread.__init__(self)
self.daemon = True
self._desktop = desktop
self.start()
def run(self):
# Get options via arg
from couchpotato.runner import getOptions
args = ['--nogit', '--console_log']
self.options = getOptions(base_path, args)
# Load settings
settings = Env.get('settings')
settings.setFile(self.options.config_file)
# Create data dir if needed
self.data_dir = os.path.expanduser(Env.setting('data_dir'))
if self.data_dir == '':
from couchpotato.core.helpers.variable import getDataDir
self.data_dir = getDataDir()
if not os.path.isdir(self.data_dir):
os.makedirs(self.data_dir)
# Create logging dir
self.log_dir = os.path.join(self.data_dir, 'logs');
if not os.path.isdir(self.log_dir):
os.mkdir(self.log_dir)
try:
from couchpotato.runner import runCouchPotato
runCouchPotato(self.options, base_path, args, data_dir = self.data_dir, log_dir = self.log_dir, Env = Env, desktop = self._desktop)
except:
pass
self._desktop.frame.Close()
class CouchPotatoApp(wx.App, SoftwareUpdate):
settings = {}
events = {}
restart = False
def OnInit(self):
# Updater
base_url = 'http://localhost/updates/'
self.InitUpdates(base_url, base_url + 'changelog.txt',
icon = wx.Icon('icon.ico'))
self.frame = MainFrame(self)
self.frame.Bind(wx.EVT_CLOSE, self.onClose)
# CouchPotato thread
self.worker = WorkerThread(self)
return True
def setSettings(self, settings = {}):
self.settings = settings
def getSetting(self, name):
return self.settings.get(name)
def addEvents(self, events = {}):
for name in events.iterkeys():
self.events[name] = events[name]
def onClose(self, event):
onClose = self.events.get('onClose')
if self.events.get('onClose'):
onClose(event)
else:
self.afterShutdown()
def afterShutdown(self, restart = False):
self.frame.Destroy()
self.restart = restart
self.ExitMainLoop()
if __name__ == '__main__':
app = CouchPotatoApp(redirect = False)
app.MainLoop()
path = os.path.join(sys.path[0].decode(sys.getfilesystemencoding()), sys.argv[0])
if app.restart:
pass
#wx.Process.Open(path)
+1 -1
View File
@@ -65,7 +65,7 @@ elif sys.platform == "darwin":
# Common # Common
NAME = "CouchPotato" NAME = "CouchPotato"
APP = [bdist_esky.Executable("CouchPotato.py", gui_only = True, icon = exeICON,)] APP = [bdist_esky.Executable("Desktop.py", name = NAME, gui_only = True, icon = exeICON,)]
DATA_FILES = ['icon.ico'] DATA_FILES = ['icon.ico']
ESKY_OPTIONS = dict( ESKY_OPTIONS = dict(
freezer_module = FREEZER, freezer_module = FREEZER,