#!/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') for item in accessories_items: print('\t\t%s%s' % (item.icon if item.icon else '', item.name, print_terminal(item.terminal), item.Exec)) print('\t') if len(development_items): print('\t') for item in development_items: print('\t\t%s%s' % (item.icon if item.icon else '', item.name, print_terminal(item.terminal), item.Exec)) print('\t') if len(education_items): print('\t') for item in education_items: print('\t\t%s%s' % (item.icon if item.icon else '', item.name, print_terminal(item.terminal), item.Exec)) print('\t') if len(games_items): print('\t') for item in games_items: print('\t\t%s%s' % (item.icon if item.icon else '', item.name, print_terminal(item.terminal), item.Exec)) print('\t') if len(graphics_items): print('\t') for item in graphics_items: print('\t\t%s%s' % (item.icon if item.icon else '', item.name, print_terminal(item.terminal), item.Exec)) print('\t') if len(internet_items): print('\t') for item in internet_items: print('\t\t%s%s' % (item.icon if item.icon else '', item.name, print_terminal(item.terminal), item.Exec)) print('\t') if len(multimedia_items): print('\t') for item in multimedia_items: print('\t\t%s%s' % (item.icon if item.icon else '', item.name, print_terminal(item.terminal), item.Exec)) print('\t') if len(office_items): print('\t') for item in office_items: print('\t\t%s%s' % (item.icon if item.icon else '', item.name, print_terminal(item.terminal), item.Exec)) print('\t') if len(other_items): print('\t') for item in other_items: print('\t\t%s%s' % (item.icon if item.icon else '', item.name, print_terminal(item.terminal), item.Exec)) print('\t') if len(settings_items): print('\t') for item in settings_items: print('\t\t%s%s' % (item.icon if item.icon else '', item.name, print_terminal(item.terminal), item.Exec)) print('\t') if len(system_items): print('\t') for item in system_items: print('\t\t%s%s' % (item.icon if item.icon else '', item.name, print_terminal(item.terminal), item.Exec)) print('\t') print('\t') print('\t') for item in all_items: print('\t\t%s%s' % (item.icon if item.icon else '', item.name, print_terminal(item.terminal), item.Exec)) print('\t') print('') def write_openbox_output(): print(' ') for item in all_items: print(' ' % item.name) print(' ') print(' %s%s' % (print_terminal(item.terminal), item.Exec)) print(' ') print(' ') print(' ') print(' ') for item in accessories_items: print(' ' % item.name) print(' ') print(' %s%s' % (print_terminal(item.terminal), item.Exec)) print(' ') print(' ') print(' ') print(' ') for item in development_items: print(' ' % item.name) print(' ') print(' %s%s' % (print_terminal(item.terminal), item.Exec)) print(' ') print(' ') print(' ') print(' ') for item in education_items: print(' ' % item.name) print(' ') print(' %s%s' % (print_terminal(item.terminal), item.Exec)) print(' ') print(' ') print(' ') print(' ') for item in games_items: print(' ' % item.name) print(' ') print(' %s%s' % (print_terminal(item.terminal), item.Exec)) print(' ') print(' ') print(' ') print(' ') for item in graphics_items: print(' ' % item.name) print(' ') print(' %s%s' % (print_terminal(item.terminal), item.Exec)) print(' ') print(' ') print(' ') print(' ') for item in internet_items: print(' ' % item.name) print(' ') print(' %s%s' % (print_terminal(item.terminal), item.Exec)) print(' ') print(' ') print(' ') print(' ') for item in multimedia_items: print(' ' % item.name) print(' ') print(' %s%s' % (print_terminal(item.terminal), item.Exec)) print(' ') print(' ') print(' ') print(' ') for item in office_items: print(' ' % item.name) print(' ') print(' %s%s' % (print_terminal(item.terminal), item.Exec)) print(' ') print(' ') print(' ') print(' ') for item in other_items: print(' ' % item.name) print(' ') print(' %s%s' % (print_terminal(item.terminal), item.Exec)) print(' ') print(' ') print(' ') print(' ') for item in settings_items: print(' ' % item.name) print(' ') print(' %s%s' % (print_terminal(item.terminal), item.Exec)) print(' ') print(' ') print(' ') print(' ') for item in system_items: print(' ' % item.name) print(' ') print(' %s%s' % (print_terminal(item.terminal), item.Exec)) 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()