Browse Source

Restore macOS menu options

pull/1399/head
Safihre 5 years ago
parent
commit
1c94db79b0
  1. 85
      SABnzbd.py
  2. BIN
      icons/sabnzbd_osx_clicked.tiff
  3. BIN
      icons/sabnzbd_osx_idle.tiff
  4. BIN
      icons/sabnzbd_osx_pause.tiff
  5. 2
      sabnzbd/__init__.py
  6. 3
      sabnzbd/misc.py
  7. 38
      sabnzbd/osxmenu.py

85
SABnzbd.py

@ -24,7 +24,6 @@ if sys.hexversion < 0x03050000:
import logging
import logging.handlers
import traceback
import os
import getopt
import signal
import socket
@ -889,10 +888,6 @@ def main():
sabnzbd.DIR_LANGUAGE = real_path(sabnzbd.DIR_PROG, DEF_LANGUAGE)
org_dir = os.getcwd()
if getattr(sys, 'frozen', None) == 'macosx_app':
# Correct path if frozen with py2app (OSX)
sabnzbd.MY_FULLNAME = sabnzbd.MY_FULLNAME.replace("/Resources/SABnzbd.py", "/MacOS/SABnzbd")
# Need console logging for SABnzbd.py and SABnzbd-console.exe
console_logging = (not hasattr(sys, "frozen")) or (sabnzbd.MY_NAME.lower().find('-console') > 0)
console_logging = console_logging and not sabnzbd.DAEMON
@ -1172,10 +1167,6 @@ def main():
if autobrowser is not None:
sabnzbd.cfg.autobrowser.set(autobrowser)
if not sabnzbd.WIN_SERVICE and not getattr(sys, 'frozen', None) == 'macosx_app':
signal.signal(signal.SIGINT, sabnzbd.sig_handler)
signal.signal(signal.SIGTERM, sabnzbd.sig_handler)
sabnzbd.initialize(pause, clean_up, evalSched=True, repair=repair)
os.chdir(sabnzbd.DIR_PROG)
@ -1396,9 +1387,6 @@ def main():
if not autorestarted:
launch_a_browser(browser_url)
if sabnzbd.FOUNDATION:
import sabnzbd.osxmenu
sabnzbd.osxmenu.notify("SAB_Launched", None)
notifier.send_notification('SABnzbd', T('SABnzbd %s started') % sabnzbd.__version__, 'startup')
# Now's the time to check for a new version
check_latest_version()
@ -1478,7 +1466,7 @@ def main():
os.chdir(org_dir)
# If OSX frozen restart of app instead of embedded python
if getattr(sys, 'frozen', None) == 'macosx_app':
if getattr(sys, 'frozen', None) and sabnzbd.DARWIN:
# [[NSProcessInfo processInfo] processIdentifier]]
# logging.info("%s" % (NSProcessInfo.processInfo().processIdentifier()))
my_pid = os.getpid()
@ -1505,20 +1493,21 @@ def main():
mail.send('stop')
if sabnzbd.WIN32:
del_connection_info()
if sabnzbd.FOUNDATION:
sabnzbd.osxmenu.notify("SAB_Shutdown", None)
# Send our final goodbyes!
notifier.send_notification('SABnzbd', T('SABnzbd shutdown finished'), 'startup')
logging.info('Leaving SABnzbd')
sys.stderr.flush()
sys.stdout.flush()
sabnzbd.pid_file()
if getattr(sys, 'frozen', None) == 'macosx_app':
if getattr(sys, 'frozen', None) and sabnzbd.DARWIN:
try:
AppHelper.stopEventLoop()
except:
# Failing AppHelper libary!
os._exit(0)
else:
notifier.send_notification('SABnzbd', T('SABnzbd shutdown finished'), 'startup')
os._exit(0)
@ -1649,37 +1638,43 @@ if __name__ == '__main__':
args.append(txt)
sabnzbd.CMDLINE = ' '.join(args)
# We can only register these in the main thread
signal.signal(signal.SIGINT, sabnzbd.sig_handler)
signal.signal(signal.SIGTERM, sabnzbd.sig_handler)
if sabnzbd.WIN32:
if not HandleCommandLine(allow_service=not hasattr(sys, "frozen")):
main()
elif getattr(sys, 'frozen', None) == 'macosx_app':
try:
# OSX binary runner
from threading import Thread
from PyObjCTools import AppHelper
from sabnzbd.osxmenu import SABnzbdDelegate
class startApp(Thread):
def __init__(self):
logging.info('[osx] sabApp Starting - starting main thread')
Thread.__init__(self)
def run(self):
main()
logging.info('[osx] sabApp Stopping - main thread quit ')
AppHelper.stopEventLoop()
def stop(self):
logging.info('[osx] sabApp Quit - stopping main thread ')
sabnzbd.shutdown_program()
logging.info('[osx] sabApp Quit - main thread stopped')
sabApp = startApp()
sabApp.start()
AppHelper.runEventLoop()
except:
main()
elif sabnzbd.DARWIN and sabnzbd.FOUNDATION:
# OSX binary runner
from threading import Thread
from PyObjCTools import AppHelper
from AppKit import NSApplication
from sabnzbd.osxmenu import SABnzbdDelegate
# Need to run the main application in separate thread because the eventLoop
# has to be in the main thread. The eventLoop is required for the menu.
# This code is made with trial-and-error, please improve!
class startApp(Thread):
def run(self):
logging.info('[osx] sabApp Starting - starting main thread')
main()
logging.info('[osx] sabApp Stopping - main thread quit ')
AppHelper.stopEventLoop()
sabApp = startApp()
sabApp.start()
# Initialize the menu
shared_app = NSApplication.sharedApplication()
sabnzbd_menu = SABnzbdDelegate.alloc().init()
shared_app.setDelegate_(sabnzbd_menu)
# Build the menu
sabnzbd_menu.awakeFromNib()
# Run the main eventloop
AppHelper.runEventLoop()
else:
main()

BIN
icons/sabnzbd_osx_clicked.tiff

Binary file not shown.

BIN
icons/sabnzbd_osx_idle.tiff

Binary file not shown.

BIN
icons/sabnzbd_osx_pause.tiff

Binary file not shown.

2
sabnzbd/__init__.py

@ -462,7 +462,7 @@ def trigger_restart(timeout=None):
del_connection_info()
# Leave the harder restarts to the polling in SABnzbd.py
if sabnzbd.WIN_SERVICE or getattr(sys, "frozen", None) == "macosx_app":
if getattr(sys, "frozen", None):
sabnzbd.TRIGGER_RESTART = True
else:
# Do the restart right now

3
sabnzbd/misc.py

@ -477,10 +477,9 @@ def exit_sab(value):
""" Leave the program after flushing stderr/stdout """
sys.stderr.flush()
sys.stdout.flush()
if getattr(sys, "frozen", None) == "macosx_app":
if getattr(sys, "frozen", None) and sabnzbd.DARWIN:
sabnzbd.SABSTOP = True
from PyObjCTools import AppHelper
AppHelper.stopEventLoop()
sys.exit(value)

38
sabnzbd/osxmenu.py

@ -30,6 +30,7 @@ import sys
import time
import logging
import cherrypy
import sabnzbd
import sabnzbd.cfg
@ -47,7 +48,11 @@ import sabnzbd.downloader
import sabnzbd.dirscanner as dirscanner
from sabnzbd.bpsmeter import BPSMeter
status_icons = {'idle': '../Resources/sab_idle.tiff', 'pause': '../Resources/sab_pause.tiff', 'clicked': '../Resources/sab_clicked.tiff'}
status_icons = {
'idle': 'icons/sabnzbd_osx_idle.tiff',
'pause': 'icons/sabnzbd_osx_pause.tiff',
'clicked': 'icons/sabnzbd_osx_clicked.tiff'
}
start_time = NSDate.date()
debug = 0
@ -77,11 +82,15 @@ class SABnzbdDelegate(NSObject):
# logging.info("building menu")
status_bar = NSStatusBar.systemStatusBar()
self.status_item = status_bar.statusItemWithLength_(NSVariableStatusItemLength)
for i in status_icons.keys():
self.icons[i] = NSImage.alloc().initByReferencingFile_(status_icons[i])
for icon in status_icons:
icon_path = status_icons[icon]
if getattr(sys, 'frozen', None):
# Path is modified for the binary
icon_path = os.path.join(os.path.dirname(sys.executable), '..', 'Resources', status_icons[icon])
self.icons[icon] = NSImage.alloc().initByReferencingFile_(icon_path)
if sabnzbd.DARWIN_VERSION > 9:
# Support for Yosemite Dark Mode
self.icons[i].setTemplate_(YES)
self.icons[icon].setTemplate_(YES)
self.status_item.setImage_(self.icons['idle'])
self.status_item.setAlternateImage_(self.icons['clicked'])
self.status_item.setHighlightMode_(1)
@ -92,7 +101,7 @@ class SABnzbdDelegate(NSObject):
NSLog("[osx] menu 1 building")
# Wait for SABnzbd Initialization
# cherrypy.engine.wait(cherrypy.process.wspbus.states.STARTED)
cherrypy.engine.wait(cherrypy.process.wspbus.states.STARTED)
# Wait for translated texts to be loaded
while not sabnzbd.WEBUI_READY and not sabnzbd.SABSTOP:
@ -704,8 +713,6 @@ class SABnzbdDelegate(NSObject):
def openFolderAction_(self, sender):
folder2open = sender.representedObject()
if isinstance(folder2open, str):
folder2open = folder2open.encode("utf-8")
if debug == 1:
NSLog("[osx] %@", folder2open)
os.system('open "%s"' % folder2open)
@ -760,21 +767,4 @@ class SABnzbdDelegate(NSObject):
self.status_item.setHighlightMode_(NO)
self.osx_icon = False
sabnzbd.shutdown_program()
try:
notifier.send_notification('SABnzbd', T('SABnzbd shutdown finished'), notifier.NOTIFICATION['other'])
except AttributeError:
# Fails for the OSX binary
pass
logging.info('Leaving SABnzbd')
sys.stderr.flush()
sys.stdout.flush()
return NSTerminateNow
def notify(notificationName, message):
""" Send a notification to the OS (OSX-only) """
if sabnzbd.FOUNDATION:
pool = Foundation.NSAutoreleasePool.alloc().init()
nc = Foundation.NSDistributedNotificationCenter.defaultCenter()
nc.postNotificationName_object_(notificationName, message)
del pool

Loading…
Cancel
Save