Permalink
Browse files

first commit

  • Loading branch information...
evilsocket committed Mar 15, 2011
0 parents commit 5e733094587a307af84d73bd7e4198e2d764a3b9
Showing with 760 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +33 −0 DesktopFile.py
  3. +226 −0 LICENSE
  4. +105 −0 Menu.py
  5. +44 −0 Notifier.py
  6. +7 −0 README
  7. +114 −0 bluebox.py
  8. +141 −0 parsers/DesktopParser.py
  9. +89 −0 parsers/MenuParser.py
  10. 0 parsers/__init__.py
@@ -0,0 +1 @@
+*.pyc
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+# This file is part of BlueBox (BackBox XFCE -> FluxBox Menu Automatic Update Daemon).
+#
+# Copyright(c) 2010-2011 Simone Margaritelli
+# evilsocket@gmail.com - evilsocket@backbox.org
+# http://www.evilsocket.net
+# http://www.backbox.org
+#
+# This file may be licensed under the terms of of the
+# GNU General Public License Version 2 (the ``GPL'').
+#
+# Software distributed under the License is distributed
+# on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+# express or implied. See the GPL for the specific language
+# governing rights and limitations.
+#
+# You should have received a copy of the GPL along with this
+# program. If not, go to http://www.gnu.org/licenses/gpl.html
+# or write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+class DesktopFile:
+ def __init__( self ):
+ self.type = ""
+ self.version = ""
+ self.encoding = "UTF-8"
+ self.name = ""
+ self.generic_name = ""
+ self.comment = ""
+ self.command = ""
+ self.icon = ""
+ self.terminal = False
+ self.categories = []
+ self.mime_types = []
226 LICENSE

Large diffs are not rendered by default.

Oops, something went wrong.
105 Menu.py
@@ -0,0 +1,105 @@
+import os.path
+# -*- coding: utf-8 -*-
+import os
+
+class Menu:
+ def __init__( self, name = "", label = "" ):
+ self.name = name
+ self.label = label
+ self.father = None
+ self.submenus = []
+ self.programs = []
+
+ def setFather( self, menu ):
+ self.father = menu
+
+ def addSubMenu( self, menu ):
+ self.submenus.append( menu )
+
+ def findOwnerAndAdd( self, desktop ):
+ if self.name in desktop.categories:
+ self.programs.append( desktop )
+ return True
+ # special case, tnx to Raffaele messed up brain -.-
+ elif self.father != None and self.father.name == 'Services' and len(desktop.categories) > 0 and self.name in desktop.categories[0]:
+ self.programs.append( desktop )
+ return True
+ else:
+ for menu in self.submenus:
+ if menu.findOwnerAndAdd( desktop ) is True:
+ return True
+
+ return False
+
+ def isEmpty( self ):
+ if len(self.programs) != 0:
+ return False
+ else:
+ for menu in self.submenus:
+ if menu.isEmpty() is False:
+ return False
+
+ return True
+
+ def removeEmptyItems(self):
+ for menu in self.submenus:
+ if menu.isEmpty():
+ self.submenus.remove(menu)
+ else:
+ menu.removeEmptyItems()
+
+ def toFluxBox( self, tabs = 0 ):
+ fluxboxmenu = ""
+
+ if self.name.lower() == 'xfce':
+ fluxboxmenu += """\
+[begin] (fluxbox)'
+ [nop] (BackBox Linux)
+ [nop]
+"""
+ else:
+ fluxboxmenu += '%s[submenu] (%s)\n' % ( '\t' * tabs, self.label )
+
+ for program in self.programs:
+ command = program.command.replace( 'sh -c', 'x-terminal-emulator -e' )
+ name = program.name.replace('(','').replace(')','')
+ # icon = '/usr/share/pixmaps/' + program.icon + '.png' if '/' not in program.icon and program.icon != '' else program.icon
+
+ fluxboxmenu += '%s[exec] (%s) {%s}\n' % ( '\t' * (tabs + 1), name, command )
+
+ for menu in self.submenus:
+ fluxboxmenu += menu.toFluxBox( tabs + 1 )
+
+ if self.name.lower() == 'xfce':
+ if os.path.exists( os.path.expanduser( "~/.fluxbox/custom-menu" ) ):
+ fluxboxmenu += """\
+ [nop]
+ [include] (~/.fluxbox/custom-menu)
+"""
+
+ fluxboxmenu += """\
+ [nop]
+ [config] (Configuration)
+ [submenu] (Styles) {}
+ [stylesdir] (/usr/share/fluxbox/styles)
+ [stylesdir] (~/.fluxbox/styles)
+ [end]
+ [workspaces] (Workspaces)
+ [reconfig] (Reconfigure)
+ [restart] (Restart)
+ [exit] (Exit)
+"""
+
+ fluxboxmenu += '%s[end]\n' % ( '\t' * tabs )
+
+ return fluxboxmenu
+
+ # for debug purpose only, doh!
+ def debug( self, tabs = 0 ):
+ print "%s%s (%s) %s" % ( '\t' * tabs, self.label, self.name, ':' if len(self.submenus) > 0 or len(self.programs) > 0 else '' )
+
+ for program in self.programs:
+ print "%s[P %s]" % ( '\t' * (tabs + 1), program.name )
+
+ for menu in self.submenus:
+ menu.debug( tabs + 1 )
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+# This file is part of BlueBox (BackBox XFCE -> FluxBox Menu Automatic Update Daemon).
+#
+# Copyright(c) 2010-2011 Simone Margaritelli
+# evilsocket@gmail.com - evilsocket@backbox.org
+# http://www.evilsocket.net
+# http://www.backbox.org
+#
+# This file may be licensed under the terms of of the
+# GNU General Public License Version 2 (the ``GPL'').
+#
+# Software distributed under the License is distributed
+# on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+# express or implied. See the GPL for the specific language
+# governing rights and limitations.
+#
+# You should have received a copy of the GPL along with this
+# program. If not, go to http://www.gnu.org/licenses/gpl.html
+# or write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+class Notifier:
+ __instance = None
+
+ def __init__(self):
+ self.libnotify = False
+
+ try:
+ import pynotify
+ if pynotify.init("BlueBox - BackBox Linux Fluxbox Menu Auto Generation Daemon"):
+ self.libnotify = True
+ except:
+ pass
+
+ def notify( self, message ):
+ if self.libnotify:
+ import pynotify
+ notification = pynotify.Notification( "BlueBox Notification", message )
+ notification.show()
+
+ @classmethod
+ def getInstance(cls):
+ if cls.__instance is None:
+ cls.__instance = Notifier()
+ return cls.__instance
7 README
@@ -0,0 +1,7 @@
+A BackBox Linux XFCE -> FluxBox automatic menu updater daemon
+Copyright(c) 2010-2011 Simone 'evilsocket' Margaritelli
+evilsocket@gmail.com - evilsocket@backbox.org
+http://www.evilsocket.net
+http://www.backbox.org
+
+!!! THIS IS STILL IN BETA STAGE, DO NOT USE IT WITHOUT CONTACTING THE AUTHOR !!!
@@ -0,0 +1,114 @@
+import os.path
+# -*- coding: utf-8 -*-
+#!/usr/bin/python
+# This file is part of BlueBox (BackBox XFCE -> FluxBox Menu Automatic Update Daemon).
+#
+# Copyright(c) 2010-2011 Simone Margaritelli
+# evilsocket@gmail.com - evilsocket@backbox.org
+# http://www.evilsocket.net
+# http://www.backbox.org
+#
+# This file may be licensed under the terms of of the
+# GNU General Public License Version 2 (the ``GPL'').
+#
+# Software distributed under the License is distributed
+# on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+# express or implied. See the GPL for the specific language
+# governing rights and limitations.
+#
+# You should have received a copy of the GPL along with this
+# program. If not, go to http://www.gnu.org/licenses/gpl.html
+# or write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+import syslog
+import codecs
+import signal
+import os
+
+from glob import glob
+from time import sleep
+from parsers.MenuParser import MenuParser
+from parsers.DesktopParser import DesktopParser
+from Notifier import Notifier
+
+# just for constants
+class BlueBox:
+ FIRST_RUN_FILE = os.path.expanduser( "~/.fluxbox/.bluebox_generation_done" )
+ FLUXBOX_MENU = os.path.expanduser( "~/.fluxbox/menu" )
+ XFCE_MENU = "/etc/xdg/xdg-backbox/menus/backbox-applications.menu"
+ DESKTOP_PATTERN = "/usr/share/applications/*.desktop"
+ WAIT_DELAY = 3
+
+def exit_signal_handler( sig, func ):
+ syslog.syslog( 'BlueBox Stopped' )
+ quit()
+
+if __name__ == "__main__":
+ try:
+ signal.signal( signal.SIGTERM, exit_signal_handler )
+
+ syslog.openlog( "BlueBox" )
+
+ syslog.syslog( 'BlueBox Started' )
+
+ first_run = not os.path.exists( BlueBox.FIRST_RUN_FILE )
+ first_run_done = False
+
+ menuparser = MenuParser( BlueBox.XFCE_MENU )
+ menu = menuparser.parse()
+ desktopparser = DesktopParser()
+ prev = []
+
+ while True:
+ files = glob( BlueBox.DESKTOP_PATTERN )
+
+ current = len(files)
+ last = len(prev)
+
+ if current != last:
+
+ if first_run:
+ open( BlueBox.FIRST_RUN_FILE, 'w+' ).close()
+ first_run_done = True
+ first_run = False
+ elif not first_run_done:
+ first_run_done = True
+ prev = files
+ continue
+
+ menuparser.reset()
+
+ menu = menuparser.parse()
+
+ for file in files:
+ desktop = desktopparser.parse( file )
+ if desktop == None:
+ syslog.syslog( syslog.LOG_NOTICE, "File '%s' could not be parsed, corrupted content or encoding ." % file )
+ else:
+ menu.findOwnerAndAdd(desktop)
+
+ desktopparser.reset()
+
+ menu.removeEmptyItems()
+
+ fd = codecs.open( BlueBox.FLUXBOX_MENU, 'w+', 'UTF-8' )
+ fd.write( menu.toFluxBox() )
+ fd.close()
+
+ updated = abs(current - last)
+ message = "BlueBox daemon succesfully updated %d item%s in FluxBox menu." % ( updated, "s" if updated > 1 else "" )
+
+ syslog.syslog( message )
+
+ Notifier.getInstance().notify( message )
+
+ prev = files
+
+ sleep( BlueBox.WAIT_DELAY )
+
+ except KeyboardInterrupt:
+ syslog.syslog( 'User interrupted BlueBox daemon with a keyboard interrupt.' )
+
+ except Exception as e:
+ syslog.syslog( syslog.LOG_ERR, str(e) )
Oops, something went wrong.

0 comments on commit 5e73309

Please sign in to comment.