File: createmenu.py

package info (click to toggle)
fvwm-crystal 3.4.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, stretch
  • size: 21,700 kB
  • ctags: 1,494
  • sloc: sh: 3,265; cs: 1,335; python: 875; makefile: 214
file content (152 lines) | stat: -rwxr-xr-x 5,861 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env python
# -*- encoding: iso-8859-15 -*-

# (c) Copyright 2008 Vincent Bernat <bernat@debian.org>
# and licensed under GPL
# Inspired by scripts by Michael Stilkerich <ms@mike2k.de>

# Helper script to create menu from the output of
# /etc/menu-methods/fvwm-crystal

# Here is what we should have:

# text|*|/usr/bin/emacs22 -nw|*|Emacs 22 (text)|*|/debian/Applications/diteurs|*|/usr/share/emacs/22.2/etc/images/icons/emacs_32.xpm
# x11|*|/usr/bin/emacs22|*|Emacs 22 (X11)|*|/debian/Applications/diteurs|*|/usr/share/emacs/22.2/etc/images/icons/emacs_32.xpm

import os

FC_ICONBASE="/usr/share/fvwm-crystal/fvwm/icons/Default"
DM_ICONBASE="/var/lib/fvwm-crystal/icons/Default"
if os.getuid() == 0:
    DM_ICONBASE_W=DM_ICONBASE
else:
    DM_ICONBASE_W=os.path.expanduser("~/.fvwm/icons/Default")
SYSTEM_ICONDIRS = [ "/usr/share/pixmaps", "/usr/share/icons" ]
SIZES = [ "22x22", "32x32", "48x48" ]

import sys
import stat
import getopt
import subprocess

def trans(char):
    if char.isalnum():
        return char
    if char in ["-", "_", ".", "(", ")", ",", "+"]:
        return char
    return "_"
transtable = "".join([trans(chr(x)) for x in range(0,256)])

def remove(base):
    for top in [base, DM_ICONBASE]:
        for root, dirs, files in os.walk(top, topdown=False):
            for name in files:
                os.remove(os.path.join(root, name))
            for name in dirs:
                os.rmdir(os.path.join(root, name))

def install(base):

    icons = {}
    noicons = []
    for l in open(os.path.join(base, "fvwm-crystal.debian-menu")).readlines():
        if l.startswith("#"):
            continue
        try:
            needs, command, title, section, icon = l.strip().split("|*|")
        except ValueError:
            continue

        # Translate dangerous characters
        title = title.translate(transtable)
        shortcommand = command.split(" ")[0].split("/")[-1].translate(transtable)

        # Create the file/directory
        filename = "%s%s/~%s~%s" % (base, section, shortcommand, title)
        if not os.path.isdir(os.path.dirname(filename)):
            os.makedirs(os.path.dirname(filename))
        target = file(filename, "w")
        target.write("""#!/bin/sh
# This file has been generated automatically by fvwm-crystal
# update-menus method. Do not edit it. Any change will be lost.
# If you are not happy with the content of this file, override
# it in one of those locations:
#  - %s
#  - %s
#
# You can either provide a new content or use a non executable
# file to discard it.

""" % (filename.replace("/var/lib/fvwm-crystal", "/usr/share/fvwm-crystal/fvwm"),
       filename.replace("/var/lib/fvwm-crystal", "~/.fvwm")))
        if needs == "text":
            # We try to escape a bit the command but we don't try to be overly complex
            target.write("exec FvwmCommand 'A %s $@'\n" % command.replace("'", "\'"))
        elif needs == "x11":
            # We use exec, this means that if the command is a shell
            # built-in, this won't work. We prefer to do that instead
            # of having a shell behind each command. Some shell are
            # intelligent enough to autoexec if needed but dash is
            # not.
            target.write("exec %s $@\n" % command)
        target.close()
        os.chmod(filename, stat.S_IRWXU | stat.S_IRGRP | stat.S_IROTH | stat.S_IXGRP | stat.S_IXOTH)

        # We need to take care of the icon now
        if shortcommand in noicons:
            # We have alread searched for an icon
            continue
        if os.path.isfile(os.path.join(FC_ICONBASE, SIZES[0], "apps", "%s.png" % shortcommand)) or \
                os.path.isfile(os.path.join(DM_ICONBASE, SIZES[0], "apps", "%s.png" % shortcommand)) or \
                os.path.isfile(os.path.join(DM_ICONBASE_W, SIZES[0], "apps", "%s.png" % shortcommand)):
            # Nothing to do, the icon exists
            continue
        if not os.path.isfile(icon):
            # No icon has been provided, we need to find one
            if not icons:
                # We build a dictionary with all icons (only done one time)
                for bd in SYSTEM_ICONDIRS:
                    for root, dirs, files in os.walk(bd):
                        for name in files:
                            if name.endswith(".png") or name.endswith(".xpm"):
                                m = name.lower()[:-4]
                                if m not in icons or name.endswith(".png"):
                                    icons[m] = os.path.join(root, name)
            if shortcommand.lower() in icons:
                icon = icons[shortcommand.lower()]
        if os.path.isfile(icon):
            # We have an icon, convert it
            for size in SIZES:
                if not os.path.isdir(os.path.join(DM_ICONBASE_W, size, "apps")):
                    os.makedirs(os.path.join(DM_ICONBASE_W, size, "apps"))
                subprocess.call(["convert", "-resize", size, icon,
                                 os.path.join(DM_ICONBASE_W, size, "apps", "%s.png" % shortcommand)])
        else:
            noicons.append(shortcommand)

    # Clean up
    os.unlink(os.path.join(base, "fvwm-crystal.debian-menu"))
            

def usage():
    print >>sys.stderr, "%s [--install|--remove] base" % sys.argv[0]

if __name__ == "__main__":
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'hi:r:', ["help", "install=", "remove="])
    except getopt.GetoptError, err:
        print >>sys.stderr, str(err)
        usage()
        sys.exit(2)
    if args:
        print "Don't know what to do with %s" % " ".join(args)
        usage()
        sys.exit(1)
    for o, a in opts:
        if o in ("-r", "--remove"):
            remove(a)
        elif o in ("-i", "--install"):
            install(a)
        else:
            usage()
            sys.exit(0)