#!/usr/bin/python
# Copyright 2023 Ted Clark
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License, version 2, as published by the Free
# Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
from sys import argv, exit, stderr
from os import listdir
class Item:
name = ''
icon = ''
Exec = ''
only_show_in = ''
categories = ''
menu = ''
terminal = False
no_display = False
PROGRAM = 'mkmenu'
TERMINAL = 'xfce4-terminal -x '
all_items = []
accessories_items = []
development_items = []
education_items = []
games_items = []
graphics_items = []
internet_items = []
multimedia_items = []
office_items = []
other_items = []
settings_items = []
system_items = []
output_mode = ''
def add_item(item):
all_items.append(item)
if item.menu:
if item.menu == 'Accessories':
accessories_items.append(item)
elif item.menu == 'Development':
development_items.append(item)
elif item.menu == 'Education':
education_items.append(item)
elif item.menu == 'Games':
games_items.append(item)
elif item.menu == 'Graphics':
graphics_items.append(item)
elif item.menu == 'Internet':
internet_items.append(item)
elif item.menu == 'Multimedia':
multimedia_items.append(item)
elif item.menu == 'Office':
office_items.append(item)
elif item.menu == 'Other':
other_items.append(item)
elif item.menu == 'Settings':
settings_items.append(item)
elif item.menu == 'System':
system_items.append(item)
def derive_menu_name(categories):
name = ''
if 'AudioVideo' in categories:
name = 'Multimedia'
elif 'Development' in categories:
name = 'Development'
elif 'Education' in categories:
name = 'Education'
elif 'Game' in categories:
name = 'Games'
elif 'Graphics' in categories:
name = 'Graphics'
elif 'Network' in categories and 'Settings' not in categories:
name = 'Internet'
elif 'Office' in categories:
name = 'Office'
# 'Utility' must precede 'Settings' and 'System', and follow everything else.
elif 'Utility' in categories:
name = 'Accessories'
# 'Settings' must precede 'System' and follow everything else.
elif 'Settings' in categories:
name = 'Settings'
# 'System' must follow everything else.
elif 'System' in categories:
name = 'System'
else:
name = 'Other'
return name
def print_tabs(width, length):
if width == 3:
if length < 8:
return '\t\t\t'
if length < 16:
return '\t\t'
elif width == 4:
if length < 8:
return '\t\t\t\t'
if length < 16:
return '\t\t\t'
if length < 24:
return '\t\t'
return '\t'
def print_terminal(terminal):
if terminal:
return TERMINAL
return ''
def read_input():
PATH = '/usr/share/applications/'
files = listdir(PATH)
for filename in files:
if '.desktop' not in filename:
continue
File = open(PATH + filename, 'r')
desktop_entry = False
item = Item()
for line in File:
line = line.rstrip()
if len(line) and line[0] == '[':
desktop_entry = True if line == '[Desktop Entry]' else False
continue
if not desktop_entry:
continue
# Split on the first occurrence only -- subsequent occurrences are data.
parts = line.split('=', 1)
if parts[0] == 'Name':
item.name = parts[1].rstrip()
# Don't use foo.capitalize() -- it may alter characters other than
# the first.
if item.name[0] >= 'a' and item.name[0] <= 'z':
capstr = item.name.upper()
item.name = capstr[0] + item.name[1:]
elif parts[0] == 'Icon':
item.icon = parts[1].rstrip()
elif parts[0] == 'Exec':
item.Exec = parts[1].rstrip()
# Remove field codes from the command line, which are always two
# characters long, but not always at the end of the line.
if item.Exec.find('%') != -1:
parts = item.Exec.split('%')
if len(parts) == 2 and len(parts[1]) > 0:
item.Exec = parts[0] + ' ' + parts[1][1:]
item.Exec = item.Exec.rstrip()
elif parts[0] == 'OnlyShowIn':
item.only_show_in = parts[1].rstrip()
elif parts[0] == 'Categories':
item.categories = parts[1].rstrip()
elif parts[0] == 'Terminal':
if parts[1] == 'true':
item.terminal = True
elif parts[0] == 'NoDisplay':
if parts[1] == 'true':
item.no_display = True
if item.name and item.Exec and item.only_show_in == '' and not item.no_display:
item.menu = derive_menu_name(item.categories)
if item.icon == '':
item.icon = 'app-launcher'
add_item(item)
File.close()
def sort_cb(item):
return item.name
def sort_items():
all_items.sort(key = sort_cb)
accessories_items.sort(key = sort_cb)
development_items.sort(key = sort_cb)
education_items.sort(key = sort_cb)
games_items.sort(key = sort_cb)
graphics_items.sort(key = sort_cb)
internet_items.sort(key = sort_cb)
multimedia_items.sort(key = sort_cb)
office_items.sort(key = sort_cb)
other_items.sort(key = sort_cb)
settings_items.sort(key = sort_cb)
system_items.sort(key = sort_cb)
def write_fluxbox_output():
print(' [submenu] (All)')
for item in all_items:
print(' [exec] (%s) {%s%s}'
% (item.name, print_terminal(item.terminal), item.Exec))
print(' [end]')
print(' [submenu] (Accessories)')
for item in accessories_items:
print(' [exec] (%s) {%s%s}'
% (item.name, print_terminal(item.terminal), item.Exec))
print(' [end]')
print(' [submenu] (Development)')
for item in development_items:
print(' [exec] (%s) {%s%s}'
% (item.name, print_terminal(item.terminal), item.Exec))
print(' [end]')
print(' [submenu] (Education)')
for item in education_items:
print(' [exec] (%s) {%s%s}'
% (item.name, print_terminal(item.terminal), item.Exec))
print(' [end]')
print(' [submenu] (Games)')
for item in games_items:
print(' [exec] (%s) {%s%s}'
% (item.name, print_terminal(item.terminal), item.Exec))
print(' [end]')
print(' [submenu] (Graphics)')
for item in graphics_items:
print(' [exec] (%s) {%s%s}'
% (item.name, print_terminal(item.terminal), item.Exec))
print(' [end]')
print(' [submenu] (Internet)')
for item in internet_items:
print(' [exec] (%s) {%s%s}'
% (item.name, print_terminal(item.terminal), item.Exec))
print(' [end]')
print(' [submenu] (Multimedia)')
for item in multimedia_items:
print(' [exec] (%s) {%s%s}'
% (item.name, print_terminal(item.terminal), item.Exec))
print(' [end]')
print(' [submenu] (Office)')
for item in office_items:
print(' [exec] (%s) {%s%s}'
% (item.name, print_terminal(item.terminal), item.Exec))
print(' [end]')
print(' [submenu] (Other)')
for item in other_items:
print(' [exec] (%s) {%s%s}'
% (item.name, print_terminal(item.terminal), item.Exec))
print(' [end]')
print(' [submenu] (Settings)')
for item in settings_items:
print(' [exec] (%s) {%s%s}'
% (item.name, print_terminal(item.terminal), item.Exec))
print(' [end]')
print(' [submenu] (System)')
for item in system_items:
print(' [exec] (%s) {%s%s}'
% (item.name, print_terminal(item.terminal), item.Exec))
print(' [end]')
def write_jwm_output():
print('')
print('')
if len(accessories_items):
print('\t')
if len(development_items):
print('\t')
if len(education_items):
print('\t')
if len(games_items):
print('\t')
if len(graphics_items):
print('\t')
if len(internet_items):
print('\t')
if len(multimedia_items):
print('\t')
if len(office_items):
print('\t')
if len(other_items):
print('\t')
if len(settings_items):
print('\t')
if len(system_items):
print('\t')
print('\t')
print('\t')
print('')
def write_openbox_output():
print('
')
print(' ')
print(' ')
print(' ')
print(' ')
print(' ')
print(' ')
print(' ')
print(' ')
print(' ')
print(' ')
print(' ')
def write_output():
if output_mode == 'FLUXBOX':
write_fluxbox_output()
elif output_mode == 'JWM':
write_jwm_output()
elif output_mode == 'OPENBOX':
write_openbox_output()
elif output_mode == 'RAW':
write_raw_output()
elif output_mode == 'THEOWIN':
write_theowin_output()
def write_raw_output():
for item in accessories_items:
print('%s%s%s%s%s%s%s' % (item.menu, print_tabs(3, len(item.menu)),
item.name, print_tabs(4, len(item.name)), item.icon,
print_tabs(4, len(item.icon)), item.Exec))
for item in development_items:
print('%s%s%s%s%s%s%s' % (item.menu, print_tabs(3, len(item.menu)),
item.name, print_tabs(4, len(item.name)), item.icon,
print_tabs(4, len(item.icon)), item.Exec))
for item in education_items:
print('%s%s%s%s%s%s%s' % (item.menu, print_tabs(3, len(item.menu)),
item.name, print_tabs(4, len(item.name)), item.icon,
print_tabs(4, len(item.icon)), item.Exec))
for item in games_items:
print('%s%s%s%s%s%s%s' % (item.menu, print_tabs(3, len(item.menu)),
item.name, print_tabs(4, len(item.name)), item.icon,
print_tabs(4, len(item.icon)), item.Exec))
for item in graphics_items:
print('%s%s%s%s%s%s%s' % (item.menu, print_tabs(3, len(item.menu)),
item.name, print_tabs(4, len(item.name)), item.icon,
print_tabs(4, len(item.icon)), item.Exec))
for item in internet_items:
print('%s%s%s%s%s%s%s' % (item.menu, print_tabs(3, len(item.menu)),
item.name, print_tabs(4, len(item.name)), item.icon,
print_tabs(4, len(item.icon)), item.Exec))
for item in multimedia_items:
print('%s%s%s%s%s%s%s' % (item.menu, print_tabs(3, len(item.menu)),
item.name, print_tabs(4, len(item.name)), item.icon,
print_tabs(4, len(item.icon)), item.Exec))
for item in office_items:
print('%s%s%s%s%s%s%s' % (item.menu, print_tabs(3, len(item.menu)),
item.name, print_tabs(4, len(item.name)), item.icon,
print_tabs(4, len(item.icon)), item.Exec))
for item in other_items:
print('%s%s%s%s%s%s%s' % (item.menu, print_tabs(3, len(item.menu)),
item.name, print_tabs(4, len(item.name)), item.icon,
print_tabs(4, len(item.icon)), item.Exec))
for item in settings_items:
print('%s%s%s%s%s%s%s' % (item.menu, print_tabs(3, len(item.menu)),
item.name, print_tabs(4, len(item.name)), item.icon,
print_tabs(4, len(item.icon)), item.Exec))
for item in system_items:
print('%s%s%s%s%s%s%s' % (item.menu, print_tabs(3, len(item.menu)),
item.name, print_tabs(4, len(item.name)), item.icon,
print_tabs(4, len(item.icon)), item.Exec))
def write_theowin_output():
print('menu All {')
print('\ticon folder')
for item in all_items:
print('\tprogram %s {' % item.name)
print('\t\ticon %s' % item.icon if item.icon else '')
print('\t\texec %s%s' % (print_terminal(item.terminal), item.Exec))
print('\t}')
print('}')
if len(accessories_items):
print('\nmenu Accessories {')
print('\ticon folder')
for item in accessories_items:
print('\tprogram %s {' % item.name)
print('\t\ticon %s' % item.icon if item.icon else '')
print('\t\texec %s%s' % (print_terminal(item.terminal), item.Exec))
print('\t}')
print('}')
if len(development_items):
print('\nmenu Development {')
print('\ticon folder')
for item in development_items:
print('\tprogram %s {' % item.name)
print('\t\ticon %s' % item.icon if item.icon else '')
print('\t\texec %s%s' % (print_terminal(item.terminal), item.Exec))
print('\t}')
print('}')
if len(education_items):
print('\nmenu Education {')
print('\ticon folder')
for item in education_items:
print('\tprogram %s {' % item.name)
print('\t\ticon %s' % item.icon if item.icon else '')
print('\t\texec %s%s' % (print_terminal(item.terminal), item.Exec))
print('\t}')
print('}')
if len(games_items):
print('\nmenu Games {')
print('\ticon folder')
for item in games_items:
print('\tprogram %s {' % item.name)
print('\t\ticon %s' % item.icon if item.icon else '')
print('\t\texec %s%s' % (print_terminal(item.terminal), item.Exec))
print('\t}')
print('}')
if len(graphics_items):
print('\nmenu Graphics {')
print('\ticon folder')
for item in graphics_items:
print('\tprogram %s {' % item.name)
print('\t\ticon %s' % item.icon if item.icon else '')
print('\t\texec %s%s' % (print_terminal(item.terminal), item.Exec))
print('\t}')
print('}')
if len(internet_items):
print('\nmenu Internet {')
print('\ticon folder')
for item in internet_items:
print('\tprogram %s {' % item.name)
print('\t\ticon %s' % item.icon if item.icon else '')
print('\t\texec %s%s' % (print_terminal(item.terminal), item.Exec))
print('\t}')
print('}')
if len(multimedia_items):
print('\nmenu Multimedia {')
print('\ticon folder')
for item in multimedia_items:
print('\tprogram %s {' % item.name)
print('\t\ticon %s' % item.icon if item.icon else '')
print('\t\texec %s%s' % (print_terminal(item.terminal), item.Exec))
print('\t}')
print('}')
if len(office_items):
print('\nmenu Office {')
print('\ticon folder')
for item in office_items:
print('\tprogram %s {' % item.name)
print('\t\ticon %s' % item.icon if item.icon else '')
print('\t\texec %s%s' % (print_terminal(item.terminal), item.Exec))
print('\t}')
print('}')
if len(other_items):
print('\nmenu Other {')
print('\ticon folder')
for item in other_items:
print('\tprogram %s {' % item.name)
print('\t\ticon %s' % item.icon if item.icon else '')
print('\t\texec %s%s' % (print_terminal(item.terminal), item.Exec))
print('\t}')
print('}')
if len(settings_items):
print('\nmenu Settings {')
print('\ticon folder')
for item in settings_items:
print('\tprogram %s {' % item.name)
print('\t\ticon %s' % item.icon if item.icon else '')
print('\t\texec %s%s' % (print_terminal(item.terminal), item.Exec))
print('\t}')
print('}')
if len(system_items):
print('\nmenu System {')
print('\ticon folder')
for item in system_items:
print('\tprogram %s {' % item.name)
print('\t\ticon %s' % item.icon if item.icon else '')
print('\t\texec %s%s' % (print_terminal(item.terminal), item.Exec))
print('\t}')
print('}')
if len(argv) != 2:
stderr.write('%s: Usage: %s [--fluxbox | --jwm | --openbox]\n' % (PROGRAM, PROGRAM))
exit(1)
if argv[1] == '--fluxbox':
output_mode = 'FLUXBOX'
elif argv[1] == '--jwm':
output_mode = 'JWM'
elif argv[1] == '--openbox':
output_mode = 'OPENBOX'
elif argv[1] == '--raw':
output_mode = 'RAW'
elif argv[1] == '--theowin':
output_mode = 'THEOWIN'
else:
stderr.write('%s: Usage: %s [--fluxbox | --jwm | --openbox]\n' % (PROGRAM, PROGRAM))
exit(1)
read_input()
if len(all_items) == 0:
stderr.write("%s: No items found.\n", PROGRAM)
exit(1)
sort_items()
write_output()