You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

253 lines
9.6 KiB

#!/usr/bin/python -OO
#from email import header
#import Cheetah.DummyTransaction
import objc
from Foundation import *
from AppKit import *
from PyObjCTools import NibClassBuilder, AppHelper
from objc import YES, NO, nil
from threading import Thread
import os
import cherrypy
import logging
import logging.handlers
import sabnzbd
import sabnzbd.cfg
from sabnzbd.constants import *
from sabnzbd.misc import launch_a_browser
from sabnzbd.utils import osx
from sabnzbd.lang import T
import sabnzbd.scheduler as scheduler
import sabnzbd.downloader as downloader
status_icons = {'idle':'../Resources/sab_idle.png','pause':'../Resources/sab_pause.png','clicked':'../Resources/sab_clicked.png'}
start_time = NSDate.date()
NibClassBuilder.extractClasses("MainMenu")
class SABnzbdDelegate(NibClassBuilder.AutoBaseClass):
icons = {}
status_bar = None
def awakeFromNib(self):
#Status Bar iniatilize
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])
self.status_item.setImage_(self.icons['idle'])
self.status_item.setAlternateImage_(self.icons['clicked'])
self.status_item.setHighlightMode_(1)
self.status_item.setToolTip_('SABnzbd')
#Menu construction
self.menu = NSMenu.alloc().init()
menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Open Web Interface', 'open:', '')
self.menu.addItem_(menu_item)
self.queue_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Queue', 'open:', '')
self.menu.addItem_(self.queue_menu_item)
self.pause_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Pause', 'pause:', '')
self.pause_menu_item.setToolTip_('0')
self.menu_pause = NSMenu.alloc().init()
for i in range(6):
menu_pause_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('%s min.' % ((i+1)*10), 'pause:', '')
menu_pause_item.setToolTip_("%s" % ((i+1)*10))
self.menu_pause.addItem_(menu_pause_item)
self.pause_menu_item.setSubmenu_(self.menu_pause)
self.menu.addItem_(self.pause_menu_item)
self.resume_menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Resume', 'resume:', '')
self.resume_menu_item.setHidden_(YES)
self.menu.addItem_(self.resume_menu_item)
if sabnzbd.cfg.USERNAME_NEWZBIN.get() and sabnzbd.cfg.PASSWORD_NEWZBIN.get() and sabnzbd.cfg.NEWZBIN_BOOKMARKS.get():
menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Get Newzbin Bookmarks', 'getNewzbinBookmarks:', '')
self.menu.addItem_(menu_item)
self.menu.addItem_(NSMenuItem.separatorItem())
menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Complete Folder', 'openCompleteFolder:', '')
self.menu.addItem_(menu_item)
menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Incomplete Folder', 'openIncompleteFolder:', '')
self.menu.addItem_(menu_item)
self.menu.addItem_(NSMenuItem.separatorItem())
#menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('About', 'infoPanel:', '')
#self.menu.addItem_(menu_item)
menu_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Quit', 'terminate:', '')
self.menu.addItem_(menu_item)
self.status_item.setMenu_(self.menu)
#Timer for updating menu
self.timer = NSTimer.alloc().initWithFireDate_interval_target_selector_userInfo_repeats_(start_time, 3.0, self, 'update:', None, True)
NSRunLoop.currentRunLoop().addTimer_forMode_(self.timer, NSDefaultRunLoopMode)
self.timer.fire()
def setMenuTitle(self,text):
style = NSMutableParagraphStyle.new()
style.setParagraphStyle_(NSParagraphStyle.defaultParagraphStyle())
style.setAlignment_(NSCenterTextAlignment)
style.setLineSpacing_(0.0)
style.setMaximumLineHeight_(9.0)
style.setParagraphSpacing_(-3.0)
titleAttributes = {
NSBaselineOffsetAttributeName : 5.0,
NSFontAttributeName: NSFont.menuFontOfSize_(9.0),
NSParagraphStyleAttributeName: style#,
# NSForegroundColorAttributeName: NSColor.colorWithDeviceWhite_alpha_(0.34, 1)
}
title = NSAttributedString.alloc().initWithString_attributes_(text, titleAttributes)
self.status_item.setAttributedTitle_(title)
def update_(self, notification):
try:
qnfo = sabnzbd.nzbqueue.queue_info()
bpsnow = sabnzbd.bpsmeter.method.get_bps()
state = "IDLE"
if downloader.paused():
state = "PAUSED"
if sabnzbd.scheduler.pause_int() != "0":
self.setMenuTitle("\n\n%s\n" % (sabnzbd.scheduler.pause_int()))
else:
self.setMenuTitle("")
elif qnfo[QNFO_BYTES_LEFT_FIELD] / MEBI > 0:
state = "DOWNLOADING"
statusbarText = "\n\n%s\n%d KB/s\n" % (self.calc_timeleft(qnfo[QNFO_BYTES_LEFT_FIELD], bpsnow), (bpsnow/KIBI))
if sabnzbd.SABSTOP:
statusbarText = "..."
self.setMenuTitle(statusbarText)
else:
self.setMenuTitle("")
except:
pass
if downloader.paused():
self.status_item.setImage_(self.icons['pause'])
self.resume_menu_item.setHidden_(NO)
self.pause_menu_item.setHidden_(YES)
else:
self.status_item.setImage_(self.icons['idle'])
self.resume_menu_item.setHidden_(YES)
self.pause_menu_item.setHidden_(NO)
self.queueupdate()
def queueupdate(self):
try:
qnfo = sabnzbd.nzbqueue.queue_info()
pnfo_list = qnfo[QNFO_PNFO_LIST_FIELD]
bytesleftprogess = 0
bpsnow = sabnzbd.bpsmeter.method.get_bps()
self.menu_queue = NSMenu.alloc().init()
job_nb = 1
for pnfo in pnfo_list:
filename = pnfo[PNFO_FILENAME_FIELD]
msgid = pnfo[PNFO_MSGID_FIELD]
bytesleft = pnfo[PNFO_BYTES_LEFT_FIELD] / MEBI
bytesleftprogess += pnfo[PNFO_BYTES_LEFT_FIELD]
bytes = pnfo[PNFO_BYTES_FIELD] / MEBI
nzo_id = pnfo[PNFO_NZO_ID_FIELD]
timeleft = self.calc_timeleft(bytesleftprogess, bpsnow)
job = "%d. %s (%d / %d MB) %s" % (job_nb, filename, bytesleft, bytes, timeleft)
job_nb += 1
menu_queue_item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(job, '', '')
self.menu_queue.addItem_(menu_queue_item)
self.queue_menu_item.setSubmenu_(self.menu_queue)
except:
pass
def calc_timeleft(self, bytesleft, bps):
"""
Calculate the time left in the format HH:MM:SS
"""
try:
totalseconds = int(bytesleft / bps)
minutes, seconds = divmod(totalseconds, 60)
hours, minutes = divmod(minutes, 60)
if minutes <10:
minutes = '0%s' % minutes
if seconds <10:
seconds = '0%s' % seconds
return '%s:%s:%s' % (hours, minutes, seconds)
except:
return '0:00:00'
def pause_(self, notification):
#logging.info("[osx] pause for %s" % (notification.toolTip()))
minutes = int(notification.toolTip())
logging.info("[osx] pause for %s" % (minutes))
scheduler.plan_resume(minutes)
downloader.set_paused(True)
def infoPanel_(self):
self.activateIgnoringOtherApps_(1)
self.orderFrontStandardAboutPanel(self)
def resume_(self, notification):
scheduler.plan_resume(0)
downloader.set_paused(False)
def open_(self, notification):
#logging.info("[osx] opening http://%s:%s/sabnzbd" % (sabnzbd.cfg.CHERRYHOST.get(), sabnzbd.cfg.CHERRYPORT.get()))
launch_a_browser("http://%s:%s/sabnzbd" % (sabnzbd.cfg.CHERRYHOST.get(), sabnzbd.cfg.CHERRYPORT.get()),True)
def openCompleteFolder_(self, notification):
#logging.info("[osx] opening %s" % (sabnzbd.cfg.COMPLETE_DIR.get_path()))
os.system('open "%s"' % sabnzbd.cfg.COMPLETE_DIR.get_path())
def openIncompleteFolder_(self, notification):
#logging.info("[osx] opening %s" % (sabnzbd.cfg.DOWNLOAD_DIR.get_path()))
os.system('open "%s"' % sabnzbd.cfg.DOWNLOAD_DIR.get_path())
def getNewzbinBookmarks_(self, notification):
sabnzbd.newzbin.getBookmarksNow()
def applicationShouldTerminate_(self, sender):
logging.info('[osx] application terminating')
self.setMenuTitle("\n\nStopping...\n")
self.status_item.setHighlightMode_(0)
logging.info('[osx] application stopping daemon')
sabnzbd.halt()
cherrypy.engine.exit()
sabnzbd.SABSTOP = True
osx.sendGrowlMsg('SABnzbd',"SABnzbd shutdown finished")
logging.info('Leaving SABnzbd')
sys.stderr.flush()
sys.stdout.flush()
return NSTerminateNow