自动生成Fvwm菜单的脚本

sh/bash/dash/ksh/zsh等Shell脚本
回复
头像
xiooli
帖子: 6956
注册时间: 2007-11-19 21:51
来自: 成都
联系:

自动生成Fvwm菜单的脚本

#1

帖子 xiooli » 2009-01-21 13:15

RT,
原文在此:http://joolix.com/2009/01/fvwm-menu-auto-creator/
自动创建缩略图需要convert(安装imagemagick包即可)
看看效果图,还不错哦,会自动根据你的图标主题生成小图标(不过category的图标得自己准备就是了):图片
代码:

代码: 全选

#!/bin/bash
#Name: 		Fvwm menu auto creator (FMAC)
#Author:	xiooli <xioooli[at]yahoo.com.cn,http://joolix.com>
#Licence:	GPLv3
#Version:	09.01.20

Menufile=~/.fvwm/configs/menu_content
Categories=(Network AudioVideo Graphics Office Games Utility Settings System Development Unknow)
Categorieszh=(网络 影音 图像 办公 游戏 附件 设置 系统 开发 未知)
Lang="$(locale|awk -F"." '/LANG=/{gsub("LANG=","",$1);print $1}')"
Fvwmiconspath="`echo ~/.fvwm/icons`"
[ -d "$Fvwmiconspath" ] || mkdir -p "$Fvwmiconspath"
Iconspath=""`echo ~/.icons`" "/usr/share/icons""
#Iconthemedir="Gnome" #在此可以定义使用的图标主题(路径/名称均可,不填就从 ~/.gtkrc-2.0去找) 
Iconthemedir="${Iconthemedir:-$(awk -F"=" '/gtk-icon-theme-name=/{gsub("\"","",$2);print $2}' "`echo ~/.gtkrc-2.0`")}"
[ -d "$Iconthemedir" ] || for i in $Iconspath;do
	[ -d "$i/$Iconthemedir" ] && Iconthemedir="$i/$Iconthemedir" && break
done

RESIZE () {

	convert -resize 24x24 "$1" "$2"
}

ADD_TO_MENU () {
	
	#$1 catnum; $2 iconpath; $3 name; $4 execmd
	local menutip cataicon
	[ -f $Menufile ] ||cat << EOF >$Menufile
#此文件里面是菜单的具体内容,菜单的样式在./menu_style中定义。
DestroyMenu recreate MenuFvwmRoot
AddToMenu MenuFvwmRoot "FVWM 菜单"	Title Top
#MenuCate
EOF
	if [ "`grep -w "Menu${Categories[$1]}" "$Menufile"`" ];then
		menutip="+ \\\"%$2%$3\\\"	Exec exec $4\n#Menu${Categories[$1]}"
		[ "`grep -w "$4" "$Menufile"`" ] || \
		eval "sed -i \"s/^#Menu${Categories[$1]}/${menutip//\//\\/}/\" \"$Menufile\""
	else
		menutip="+ \\\"%$Fvwmiconspath/categrories/${Categories[$1]}.png%${Categorieszh[$1]}\\\"	Popup Menu${Categories[$1]}\n#MenuCate"
		eval "sed -i \"s/^#MenuCate/${menutip//\//\\/}/\" \"$Menufile\""
		echo -e "\nDestroyMenu Menu${Categories[$1]}\nAddToMenu Menu${Categories[$1]}\n#Menu${Categories[$1]}" >> "$Menufile"
		menutip="+ \\\"%$2%$3\\\"	Exec exec $4\n#Menu${Categories[$1]}"
		eval "sed -i \"s/^#Menu${Categories[$1]}/${menutip//\//\\/}/\" \"$Menufile\""
	fi
}

GET_INFO () { # $1 gives the desktop file name

	local j name type execmd icon iconpath cattmp catnum
	name="`grep -i "^name\[$Lang\]" $1|sed "s/^.*=//"`"
	[ "$name" ] || name="`grep -i "^name=" $1|sed "s/^.*=//"`"
	execmd="`grep -i "^exec=" $1|sed "s/^.*=//;s/%.//g"`"
	cattmp="`grep -i "Categories=" $1|sed "s/^.*=//"`"
	for j in `seq 0 "$((${#Categories[@]}-1))"`;do
		[ "${cattmp//${Categories[$j]}/}" != "$cattmp" ] && catnum="$j" && break
	done
	catnum="${catnum:-$((${#Categories[@]}-1))}"
	icon="`grep -i "^icon=" $1|sed "s/^.*=//"`"
	if [ -f "$icon" ];then
		iconpath="$icon"
		[ ! -f "$Fvwmiconspath/$icon" -a "$iconpath" ] && RESIZE "$iconpath" "$Fvwmiconspath/"`basename "$icon"`""
	else
		[ "${icon/%.png/}" = "$icon" ] && icon="${icon}.png"
		iconpath="`find "$Iconthemedir" -type f -name "$icon" -print|sort|tail -n1`"
		[ "$iconpath" ] || iconpath="`find "$Iconthemedir" -type f -name "*$icon" -print|sort|tail -n1`"
		[ ! -f "$Fvwmiconspath/$icon" -a "$iconpath" ] && RESIZE "$iconpath" "$Fvwmiconspath/$icon"
		iconpath="${iconpath:-"$Fvwmiconspath/noicon.png"}"
	fi
	ADD_TO_MENU "$catnum" "$Fvwmiconspath/`basename "$icon"`" "$name" "$execmd"
}

for k in /usr/share/applications/*.desktop;do
	GET_INFO "$k"
done
Joolix live OS: http://joolix.com

代码: 全选

dpkg -l|awk '/^rc/{print $2}'|sudo xargs dpkg -P
头像
leeaman
帖子: 30702
注册时间: 2007-02-02 18:14
系统: debian sid

Re: 自动生成Fvwm菜单的脚本

#2

帖子 leeaman » 2009-01-21 13:20

loli真是好厉害哦 :em01
醉了星星,醉月亮●●●●●The Long Way To Go(*^_^*)
头像
BigSnake.NET
帖子: 12522
注册时间: 2006-07-02 11:16
来自: 廣州
联系:

Re: 自动生成Fvwm菜单的脚本

#3

帖子 BigSnake.NET » 2009-01-21 13:20

代码: 全选

# -*- coding: UTF-8 -*-

import xdg.Menu
import xdg.DesktopEntry

get_id = iter(xrange(10000)).next
menu_list = []
item_list = []

def output_attr(x):
    if isinstance(x,unicode):
        x = x.encode('UTF-8')
    return str(x)

class Menu(list):
    def __init__(self,m=None,label='',id='root-menu',show=True,icon=''):
        if m is None:
            self.label = label
            self.id = str(id)
            self.show = show
            self.icon = icon
            return
        self.label = m.getName()
        self.id = 'menu_' + str(get_id())
        self.show = True # show the menu 
        self.icon = m.getIcon()
        for i in m.getEntries():
            if isinstance(i, xdg.Menu.Menu):
                sub_node = Menu(i)
            elif isinstance(i, xdg.Menu.MenuEntry):
                sub_node = DesktopEntry(i.DesktopEntry)
            else:
                raise Exception('unknown node type')
            self.append(sub_node)
        menu_list.append(self)

    def to_txt(self,indent='  ',dep=0):
        o_indent = indent
        indent = indent * dep
        print indent + '{'
        for i in ['label','id','show','icon']:
            print indent + i + ' : ',
            print output_attr(self.__getattribute__(i))
        print indent + 'sub items:'
        for i in self:
            i.to_txt(o_indent,dep+1)
        print indent + '}'
    def to_xml(self,doc,root_node,parent):
        if len(self) == 0 or not self.show:
            return None
        node = doc.createElement('menu')
        node.setAttribute('id',self.id)
        node.setAttribute('label',self.label)
        for i in self:
            tmp = i.to_xml(doc,root_node,self)
            if tmp != None:
                node.appendChild(tmp)
        if node.hasChildNodes():
            root_node.appendChild(node)
            res_node = doc.createElement('menu')
            res_node.setAttribute('id',self.id)
            return res_node
        else:
            self.show = False
            return None

class DesktopEntry(object):
    def __init__(self,de=None,label='',show=True,icon='',notify=True,command='true'):
        if de is None:
            self.label = label
            self.show = show
            self.icon = icon
            self.notify = notify
            self.command = command
            return
        self.label = de.getName()
        self.show = not de.getHidden()
        self.notify = True
        self.icon = de.getIcon()
        if de.getTerminal():
            self.command = 'rxvt -depth 32 -bg rgba:0000/0000/0000/d000 ' + de.getTerminalOptions() + ' -e ' + repr(de.getExec())
        else:
            self.command = de.getExec()
        item_list.append(self)
    def to_txt(self,indent='  ',dep=0):
        indent = indent * dep
        print indent + '{'
        for i in ['label','show','notify','icon','command']:
            print indent + i + ' :' ,
            print output_attr(self.__getattribute__(i))
        print indent + '}'
    def to_xml(self,doc,root_node,parent):
        if not self.show:
            return None
        item_node = doc.createElement('item')
        item_node.setAttribute('label',self.label)
        action_node = doc.createElement('action')
        item_node.appendChild(action_node)
        action_node.setAttribute('name','Execute')
        command_node = doc.createElement('command')
        action_node.appendChild(command_node)
        cmd_text_node = doc.createTextNode(self.command)
        command_node.appendChild(cmd_text_node)
        if self.notify:
            notify_node = doc.createElement('startupnotify')
            action_node.appendChild(notify_node)
            e_node = doc.createElement('enabled')
            notify_node.appendChild(e_node)
            yes_text_node = doc.createTextNode('true')
            e_node.appendChild(yes_text_node)
        return item_node

class Separator(object):
    def __init__(self,label=None):
        self.label = label
        return
    def to_xml(self,doc,root_node,parent):
        sep_node = doc.createElement('separator')
        if self.label:
            sep_node.setAttribute('label',self.label)
        return sep_node

class ActionItem(object):
    def __init__(self,label,action):
        self.label = label
        self.action = action
    def to_xml(self,doc,root_node,parent):
        item_node = doc.createElement('item')
        item_node.setAttribute('label',self.label)
        action_node = doc.createElement('action')
        item_node.appendChild(action_node)
        action_node.setAttribute('name',self.action)
        return item_node

class MenuItem(object):
    def __init__(self,label,id):
        self.label = label
        self.id = id
    def to_xml(self,doc,root_node,parent):
        res_node = doc.createElement('menu')
        res_node.setAttribute('id',self.id)
        return res_node



menu = xdg.Menu.parse('/etc/xdg/menus/debian-menu.menu')

M = Menu(menu)
# configure code here ...

def find_by_label(label,l):
    res = []
    for i in l:
        if label == i.label:
            res.append(i)
    return res

def find_item(*label):
    res = []
    for i in label:
        res.extend(find_by_label(i,item_list))
    return res

def disable_item(*label):
    for j in label:
        for i in find_by_label(j,item_list):
            i.show = False

def disable_menu(*label):
    for j in label:
        for i in find_by_label(j,menu_list):
            i.show = False

main_menu = Menu(label='Openbox Main Menu')
# main_menu.append(Separator(u'应用程序'))
for i in M[1]:
    main_menu.append(i)
main_menu.append(Separator())
main_menu.append(find_item("ROX Filer")[0])
main_menu.append(DesktopEntry(label=u'终端',command='rxvt -depth 32 -bg rgba:0000/0000/0000/d000 -e screen-wrapper'))
main_menu.extend(find_item("Firefox 3 Browser","Thunderbird Mail",'Pidgin'))
main_menu.append(DesktopEntry(label=u'Eva',command="eva -caption ''"))
main_menu.extend(find_item('LeafPad','htop'))
main_menu.append(Separator())
main_menu.append(MenuItem(label='窗口管理',id='client-list-combined-menu'))
sys_menu = Menu(label='Openbox',id='openbox_sys_menu')
sys_menu.append(ActionItem(u'重新加载配置','Reconfigure'))
sys_menu.append(ActionItem(u'重新启动 Openbox','Restart'))
sys_menu.append(ActionItem(u'退出 Openbox','Exit'))
main_menu.append(sys_menu)

disable_menu(u'辅助工具',u'Shell')
disable_item('fbpanel','X Window Snapshot','dotty','lefty','TiMidity++','moc','XDvi','Xditview')
disable_item('Xcalc','Xvidtune','Aptitude','Editres','KControl','KInfoCenter','Kicker','TeXconfig','Xclipboard','Xfontsel','Xkill','Xrefresh','alsaconf','Cycle')
disable_item('Pstree','Top','Xconsole','Xev','Xload','Rxvt-Unicode (Black,Xft)','GDB','Ocaml','Python (v2.5)','Tclsh8.4','TkWish8.4','Xbiff','Lynx','Telnet','xtightvncviewer','Nano','Xedit')

M = main_menu

# now generate the xml code ...
from xml.dom import minidom
doc = minidom.Document()
openbox_node = doc.createElement('openbox_menu')
doc.appendChild(openbox_node)
M.to_xml(doc,openbox_node,openbox_node)
#print doc.toprettyxml(indent = '    ').encode('UTF-8')
print doc.toxml().encode('UTF-8')

#:M.to_txt('  ')
^_^ ~~~
要理解递归,首先要理解递归。

地球人都知道,理论上,理论跟实际是没有差别的,但实际上,理论跟实际的差别是相当大滴。
头像
lerosua
论坛版主
帖子: 8455
注册时间: 2007-11-29 9:41
联系:

Re: 自动生成Fvwm菜单的脚本

#4

帖子 lerosua » 2009-01-21 13:29

我是来支持的
头像
xiooli
帖子: 6956
注册时间: 2007-11-19 21:51
来自: 成都
联系:

Re: 自动生成Fvwm菜单的脚本

#5

帖子 xiooli » 2009-01-21 13:31

球猫的那个东东是哪里搞来的,不早点弄出来,害我自己写了一个。。。
头像
BigSnake.NET
帖子: 12522
注册时间: 2006-07-02 11:16
来自: 廣州
联系:

Re: 自动生成Fvwm菜单的脚本

#6

帖子 BigSnake.NET » 2009-01-21 13:40

xiooli 写了:球猫的那个东东是哪里搞来的,不早点弄出来,害我自己写了一个。。。
这个是 openbox 版的 ..
N 久前写的, 现在有点看不懂了
^_^ ~~~
要理解递归,首先要理解递归。

地球人都知道,理论上,理论跟实际是没有差别的,但实际上,理论跟实际的差别是相当大滴。
头像
xiooli
帖子: 6956
注册时间: 2007-11-19 21:51
来自: 成都
联系:

Re: 自动生成Fvwm菜单的脚本

#7

帖子 xiooli » 2009-01-21 13:41

BigSnake.NET 写了:
xiooli 写了:球猫的那个东东是哪里搞来的,不早点弄出来,害我自己写了一个。。。
这个是 openbox 版的 ..
N 久前写的, 现在有点看不懂了
说实话,我不太懂python :em06
Tell360
帖子: 6
注册时间: 2008-08-23 12:22

Re: 自动生成Fvwm菜单的脚本

#8

帖子 Tell360 » 2009-01-21 13:44

:em02
还是有些太复杂.....呵呵.
头像
bones7456
帖子: 8495
注册时间: 2006-04-12 20:05
来自: 杭州
联系:

Re: 自动生成Fvwm菜单的脚本

#9

帖子 bones7456 » 2009-01-21 14:58

等哪天用fvwm了再用这...
:em04
关注我的blog: ε==3
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: 自动生成Fvwm菜单的脚本

#10

帖子 eexpress » 2009-01-21 22:03

这很多的哦。只是不遵循xdg的,都不好。
附件
fvwm-menu.html.bz2
(354.56 KiB) 已下载 107 次
● 鸣学
nosymsiee
帖子: 17
注册时间: 2009-01-22 22:05

Re: 自动生成Fvwm菜单的脚本

#11

帖子 nosymsiee » 2009-01-22 22:16

:em09
头像
HuntXu
帖子: 5776
注册时间: 2007-09-29 3:09

Re: 自动生成Fvwm菜单的脚本

#12

帖子 HuntXu » 2009-01-23 9:32

目前为止还是只会手动...唉...
HUNT Unfortunately No Talent...
头像
Ur@nus
帖子: 622
注册时间: 2006-12-01 23:02

Re: 自动生成Fvwm菜单的脚本

#13

帖子 Ur@nus » 2009-01-24 22:00

我都绑定键盘了,菜单里只有重启和关机。 :em05 :em05
phoenixne
帖子: 24
注册时间: 2007-06-03 13:00

Re: 自动生成Fvwm菜单的脚本

#14

帖子 phoenixne » 2009-06-28 7:47

Menufile=~/.fvwm/configs/menu_content

这句是作什么的?
我运行时提示:
sed:无法读取 /home/XXXXX/.fvwm/configs/menu_content:没有该文件或目录

这个是要自己先建立了的吗
回复