Package: openbox
Version: 3.6.1-6
Severity: important

Dear maintainer,
I have troubles with 'obamenu' here.

In my menu.xml I have:

<menu execute="/usr/bin/obamenu" id="applications-menu" label="Aplicaciones"/>

When my mouse pointer reaches that menu entry, or if I select it via keyboard, 
I get a pop-up window saying:

" Invalide output from pipe-menu "/usr/bin/obamenu" "
-----

Running "/usr/bin/obamenu" from terminal I get:

"Traceback (most recent call last):
  File "/usr/bin/obamenu", line 181, in <module>
    process_dtfile(dtf,  categoryDict)
  File "/usr/bin/obamenu", line 146, in process_dtfile
    if eqi[1][-1] == ';':
IndexError: string index out of range"

---------------------------------------------
This ↓ is the content of obamenu in /usr/bin:
---    --------------------------------------


#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Version 1.1.7 
# ---- config ---
applications_dirs = ("/usr/share/applications", )
image_dir_base = "/usr/share" # without "pixmaps" -/usr/local/share in FreeBSD, 
/usr/share on linux
icon_Theme = "Humanity"
image_cat_prefix = "applications-"  # if empty will create no icon text only 
menu
application_groups = ("Office",  "Development",  "Graphics", "Internet",  
"Games", "System",  "Multimedia",  "Utilities",  "Settings")
group_aliases = 
{"Audio":"Multimedia","AudioVideo":"Multimedia","Network":"Internet","Game":"Games",
 "Utility":"Utilities", "GTK":"",  "GNOME":""}
ignoreList = ("evince-previewer", "Ted",  "wingide3.2", "python3.4", 
"feh","xfce4-power-manager-settings" )
terminal_string = "evte -e"         # your favourites terminal exec string
simpleOBheader = False  # print full xml style OB header
# --- End of user config ---
 
import glob

class dtItem(object):
    def __init__(self, fName):
        self.fileName = fName
        self.Name = ""
        self.Comment = ""
        self.Exec = ""
        self.Terminal = None
        self.Type = ""
        self.Icon = ""
        self.Categories = ()

    def addName(self, data):
        self.Name = xescape(data)

    def addComment(self, data):
        self.Comment = data

    def addExec(self, data):
        if len(data) > 3 and data[-2] == '%':   # get rid of filemanager 
arguments in dt files
            data = data[:-2].strip()
        self.Exec = data

    def addIcon(self, data):
        self.Icon = ""
        if image_cat_prefix == "":
            return
        image_dir = image_dir_base + "/pixmaps/"
        di = data.strip()
        if len(di) < 3:
            #"Error in %s: Invalid or no icon '%s'" % (self.fileName,  di)
            return
        dix = di.find("/")      # is it a full path?
        if dix >= 0 and dix <= 2:    # yes, its a path (./path or ../path or 
/path ...)
            self.Icon = di
            return
        #else a short name like "myapp"
        tmp = image_dir + di + ".*"
        tmp = glob.glob(tmp)
        if len(tmp) > 0:
            self.Icon = tmp[0]
        return

    def addTerminal(self, data):
        if data == "True" or data == "true":
            self.Terminal = True
        else:
            self.Terminal = False

    def addType(self, data):
        self.Type = data

    def addCategories(self, data):
        self.Categories = data

def getCatIcon(cat):
    iconDir = image_dir_base + "/icons/" + icon_Theme + "/categories/24/"
    cat = image_cat_prefix + cat.lower()
    tmp = glob.glob(iconDir + cat + ".*")
    if len(tmp) > 0:
        return tmp[0]
    return ""

def xescape(s):
    Rep = {"&":"&amp;", "<":"&lt;", ">":"&gt;",  "'":"&apos;", "\"":"&quot;"}
    for p in ("&", "<", ">",  "'","\""):
        sl = len(s); last = -1
        while last < sl:
            i = s.find(p,  last+1)
            if i < 0:
                done = True
                break
            last = i
            l = s[:i]
            r = s[i+1:]
            s = l + Rep[p] + r
    return s

def process_category(cat, curCats,  appGroups = application_groups,  aliases = 
group_aliases ):
        # first process aliases
        if aliases.has_key(cat):
                if aliases[cat] == "":
                        return ""                               # ignore this 
one
                cat = aliases[cat]
        if cat in appGroups and cat not in curCats:  # valid categories only 
and no doublettes, please
                curCats.append(cat)
                return cat
        return ""


def process_dtfile(dtf,  catDict):  # process this file & extract relevant info
        active = False          # parse only after "[Desktop Entry]" line
        fh = open(dtf,  "r")
        lines = fh.readlines()
        this = dtItem(dtf)
        for l in lines:
                l = l.strip()
                if l == "[Desktop Entry]":
                        active = True
                        continue
                if active == False:     # we don't care about licenses or other 
comments
                        continue
line 146)               if l == None or len(l) < 1 or l[0] == '#':
                        continue
                if l[0]== '[' and l !=  "[Desktop Entry]":
                        active = False
                        continue
                # else
                eqi = l.split('=')
                if len(eqi) < 2:
                        print "Error: Invalid .desktop line'" + l + "'"
                        continue
                # Check what it is ...
                if eqi[0] == "Name":
                        this.addName(eqi[1])
                elif eqi[0] == "Comment":
                        this.addComment(eqi[1])
                elif eqi[0] == "Exec":
                        this.addExec(eqi[1])
                elif eqi[0] == "Icon":
                        this.addIcon(eqi[1])
                elif eqi[0] == "Terminal":
                        this.addTerminal(eqi[1])
                elif eqi[0] == "Type":
                        if eqi[1] != "Application":
                                continue
                        this.addType(eqi[1])
                elif eqi[0] == "Categories":
                        if eqi[1][-1] == ';':
                                eqi[1] = eqi[1][0:-1]
                        cats = []
                        # DEBUG 
                        dtCats = eqi[1].split(';')
                        for cat in dtCats:
                                result = process_category(cat,  cats)
                        this.addCategories(cats)
                else:
                        continue
line 181)       # add to catDict
        #this.dprint()
        if len(this.Categories) > 0:        # don't care about stuff w/o 
category
                for cat in this.Categories:
                        catDict[cat].append(this)

categoryDict = {}

if __name__ == "__main__":
    # init the application group dict (which will contain list of apps)
    for appGroup in application_groups:
        categoryDict[appGroup] = []

    # now let's look  into the app dirs ...
    for appDir in applications_dirs:
        appDir += "/*.desktop"
        dtFiles = glob.glob(appDir)

        # process each .desktop file in dir
        for dtf in dtFiles:
            skipFlag = False
            for ifn in ignoreList:
                if dtf.find(ifn) >= 0:
                    skipFlag = True
            if skipFlag == False:
                process_dtfile(dtf,  categoryDict)

    # now, generate jwm menu include
    if simpleOBheader == True:
        print '<openbox_pipe_menu>'       # magic header
    else:
        print '<?xml version="1.0" encoding="UTF-8" ?><openbox_pipe_menu 
xmlns="http://openbox.org/";  
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";  
xsi:schemaLocation="http://openbox.org/"; >'       # magic header
    appGroupLen = len(application_groups)
    for ag in range(appGroupLen ):
        catList = categoryDict[application_groups[ag]]
        if len(catList) < 1:
            continue                # don't create empty menus
        catStr = "<menu id=\"openbox-%s\" label=\"%s\" " % 
(application_groups[ag], application_groups[ag])
        tmp = getCatIcon(application_groups[ag])
        if tmp != "":
            catStr += "icon=\"%s\"" % tmp
        print catStr,  ">"
        for app in catList:
            progStr = "<item "
            progStr += "label=\"%s\" "  % app.Name
            if app.Icon != "":
                progStr += "icon=\"%s\" " % app.Icon
            progStr += "><action name=\"Execute\"><command><![CDATA["
            if app.Terminal == True:
                progStr += terminal_string + " "
            progStr += "%s]]></command></action></item>"  % app.Exec
            print progStr
        print "</menu>"
    print "</openbox_pipe_menu>"       # magic footer
    pass # done/debug break
--------------------------------------------------------


Note that in a fresh openbox install (debian sid vm) and in another old sid vm, 
which have a copy of my openbox host config files, I have no problems;
obamenu works fine. I reinstalled openbox (my host) but it doesn't help. This 
bug only affects my host. 
(<menu id="applications-menu" label="Aplicaciones" execute="openbox-menu -i 
gnome-applications.menu"/   works just fine.)
------------------------------------------------------------------------------------------------------------------------------------------------------

-- System Information:
Debian Release: buster/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)

Kernel: Linux 4.14.0-3-amd64 (SMP w/4 CPU cores)
Locale: LANG=es_ES.UTF-8, LC_CTYPE=es_ES.UTF-8 (charmap=UTF-8), 
LANGUAGE=es_ES:es (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages openbox depends on:
ii  libc6                     2.26-3
ii  libglib2.0-0              2.54.3-1
ii  libice6                   2:1.0.9-2
ii  libobrender32v5           3.6.1-6
ii  libobt2v5                 3.6.1-6
ii  libsm6                    2:1.2.2-1+b3
ii  libstartup-notification0  0.12-5
ii  libx11-6                  2:1.6.4-3
ii  libxau6                   1:1.0.8-1+b2
ii  libxcursor1               1:1.1.15-1
ii  libxext6                  2:1.3.3-1+b2
ii  libxi6                    2:1.7.9-1
ii  libxinerama1              2:1.1.3-1+b3
ii  libxrandr2                2:1.5.1-1

Versions of packages openbox recommends:
ii  obconf        1:2.0.4+git20150213-2
ii  obsession     20140608-2+b1
ii  openbox-menu  0.8.0+hg20161009-1
ii  scrot         0.8-18

Versions of packages openbox suggests:
ii  fonts-dejavu           2.37-1
pn  libxml2-dev            <none>
ii  openbox-gnome-session  3.6.1-6
pn  openbox-kde-session    <none>
ii  python                 2.7.14-4
ii  tint2                  15.3-2

-- no debconf information

Reply via email to