Index: Hellanzb/Core.py
===================================================================
--- Hellanzb/Core.py	(revision 992)
+++ Hellanzb/Core.py	(working copy)
@@ -342,6 +342,20 @@
             error('Config file option: Hellanzb.UMASK is not a valid integer')
             sys.exit(1)
 
+    if not hasattr(Hellanzb, 'LIBNOTIFY_NOTIFY'):
+        error('Required option not defined in config file: Hellanzb.LIBNOTIFY_NOTIFY')
+        sys.exit(1)
+    elif Hellanzb.LIBNOTIFY_NOTIFY:
+        try:
+            import pynotify
+        except ImportError:
+            error('Please install notify-python or disable Hellanzb.LIBNOTIFY_NOTIFY')
+            sys.exit(1)
+
+        if not pynotify.init("HellaNZB"):
+            error('Cannot initialize libnotify')
+            sys.exit(1)
+
     if not hasattr(Hellanzb, 'GROWL_NOTIFY'):
         error('Required option not defined in config file: Hellanzb.GROWL_NOTIFY')
         sys.exit(1)
Index: Hellanzb/NZBLeecher/ArticleDecoder.py
===================================================================
--- Hellanzb/NZBLeecher/ArticleDecoder.py	(revision 992)
+++ Hellanzb/NZBLeecher/ArticleDecoder.py	(working copy)
@@ -448,6 +448,7 @@
             error('No space left on device!')
             pauseCurrent()
             growlNotify('Error', 'hellanzb Download Paused', 'No space left on device!', True)
+            libnotifyNotify('Error', 'hellanzb Download Paused', 'No space left on device!', True)
         raise OutOfDiskSpace('LOL BURN SOME DVDS LOL')
     else:
         debug('handleIOError: got: %s' % str(ioe))
Index: Hellanzb/NZBQueue.py
===================================================================
--- Hellanzb/NZBQueue.py	(revision 992)
+++ Hellanzb/NZBQueue.py	(working copy)
@@ -191,6 +191,7 @@
 
             if not firstRun and not justScan and not Hellanzb.loggedIdleMessage:
                 growlNotify('Queue', 'hellanzb', 'No more nzbs left to download', False)
+                libnotifyNotify('Queue', 'hellanzb', 'No more nzbs left to download', False)
                 Hellanzb.loggedIdleMessage = True
             return
 
@@ -417,6 +418,8 @@
         info(notification + ': ' + nzb.archiveName)
         growlNotify('Queue', 'hellanzb ' + notification + ':', nzb.archiveName,
                     False)
+        libnotifyNotify('Queue', 'hellanzb ' + notification + ':',
+                    nzb.archiveName, False)
 
     try:
         findAndLoadPostponedDir(nzb)
@@ -431,6 +434,7 @@
         error('Problem while parsing the NZB', fe)
         growlNotify('Error', 'hellanzb', 'Problem while parsing the NZB: ' + prettyException(fe),
                     True)
+        libnotifyNotify('Error', 'hellanzb', 'Problem while parsing the NZB: '  + prettyException(fe), True)
         error('Moving bad NZB out of queue into TEMP_DIR: ' + Hellanzb.TEMP_DIR)
         move(nzb.nzbFileName, Hellanzb.TEMP_DIR + os.sep)
         reactor.callLater(5, scanQueueDir)
@@ -676,6 +680,7 @@
             msg += ': '
             info(logMsg + nzb.archiveName)
             growlNotify('Queue', 'hellanzb ' + msg, nzb.archiveName, False)
+            libnotifyNotify('Queue', 'hellanzb' + msg, nzb.archiveName, False)
 
             if nzb.totalBytes == 0 and len(Hellanzb.queue.currentNZBs()) or \
                     not writeQueue:
Index: Hellanzb/Daemon.py
===================================================================
--- Hellanzb/Daemon.py	(revision 992)
+++ Hellanzb/Daemon.py	(working copy)
@@ -86,6 +86,7 @@
 
     reactor.callLater(0, info, 'hellanzb - Now monitoring queue...')
     reactor.callLater(0, growlNotify, 'Queue', 'hellanzb', 'Now monitoring queue..', False)
+    reactor.callLater(0, libnotifyNotify, 'Queue', 'hellanzb', 'Now monitoring queue..', False)
     # Twisted does not guarantee callLater(0, first); callLater(0, second) will run in
     # that order: http://twistedmatrix.com/trac/ticket/1396
     # This is especially problematic on some platforms (cygwin):
Index: Hellanzb/Log.py
===================================================================
--- Hellanzb/Log.py	(revision 992)
+++ Hellanzb/Log.py	(working copy)
@@ -87,6 +87,21 @@
         message = '%s\n' % message
     Hellanzb.logger.log(ScrollableHandler.NOLOGFILE, message)
 
+def libnotifyNotify(type, title, description, sticky = False):
+    """ send a message to libnotify daemon """
+    if not Hellanzb.LIBNOTIFY_NOTIFY:
+        return
+
+    import pynotify
+    n = pynotify.Notification(title, description)
+    n.set_category(type)
+    if not sticky:
+        n.set_timeout(10000) # 10 Seconds
+
+    if not n.show():
+        debug('Failed to send notification')
+
+
 def growlNotify(type, title, description, sticky = False):
     """ send a message to the remote growl daemon via udp """
     # NOTE: growl doesn't tie in with logging yet because all it's sublevels/args makes it
Index: Hellanzb/PostProcessorUtil.py
===================================================================
--- Hellanzb/PostProcessorUtil.py	(revision 992)
+++ Hellanzb/PostProcessorUtil.py	(working copy)
@@ -538,6 +538,9 @@
         growlNotify('Archive Error', 'hellanzb requires password',
                     archiveName(postProcessor.dirName) + \
                     ' requires a rar password for extraction', True)
+        libnotifyNotify('Archive Error', 'hellanzb requires password',
+                    archiveName(postProcessor.dirName) + \
+                    ' requires a rar password for extraction', True)
         raise FatalError('Cannot continue, this archive requires a RAR password. Run ' + \
                              sys.argv[0] + \
                              ' -p on the archive directory with the -P option to specify a password')
@@ -576,6 +579,9 @@
         growlNotify('Archive Error', 'hellanzb requires password',
                     archiveName(postProcessor.dirName) + \
                     ' requires a rar password for extraction', True)
+        libnotifyNotify('Archive Error', 'hellanzb requires password',
+                    archiveName(postProcessor.dirName) + \
+                    ' requires a rar password for extraction', True)
         raise FatalError('Cannot continue, this archive requires a RAR password. Run ' + \
                          sys.argv[0] + \
                          ' -p on the archive directory with the -P option to specify a password')
@@ -888,6 +894,8 @@
         if len(damagedAndRequired) > 0:
             growlNotify('Error', 'hellanzb Cannot par repair:', archiveName(dirName) + \
                         '\nNeed ' + neededBlocks + ' more recovery ' + needType, True)
+            libnotifyNotify('Error', 'hellanzb Cannot par repair:', archiveName(dirName) + \
+                        '\nNeed ' + neededBlocks + ' more recovery ' + needType, True)
             raise FatalError('Unable to par repair: archive requires ' + neededBlocks + \
                              ' more recovery ' + needType + ' for repair')
 
Index: Hellanzb/PostProcessor.py
===================================================================
--- Hellanzb/PostProcessor.py	(revision 992)
+++ Hellanzb/PostProcessor.py	(working copy)
@@ -422,6 +422,8 @@
                 parMessage = '\n' + parMessage
             growlNotify('Archive Success', 'hellanzb Done Processing%s:' % parMessage,
                         '%s\ntook: %s%s' % (archive, elapsed, totalTime), True)
+            libnotifyNotify('Archive Success', 'hellanzb Done Processing%s:' % parMessage,
+                        '%s\ntook: %s%s' % (archive, elapsed, totalTime), True)
                        #self.background)
         # FIXME: could unsticky the message if we're running hellanzb.py -p
         # and preferably if the post processing took say over 30 seconds
Index: etc/hellanzb.conf.sample
===================================================================
--- etc/hellanzb.conf.sample	(revision 992)
+++ etc/hellanzb.conf.sample	(working copy)
@@ -148,6 +148,10 @@
 Hellanzb.GROWL_PASSWORD = 'password'
 
 
+# Enable libNotify Daemon notifications (Linux)
+Hellanzb.LIBNOTIFY_NOTIFY = False
+
+
 # Hostname for the XMLRPC client to connect to. By default, localhost
 Hellanzb.XMLRPC_SERVER = 'localhost'
 
