Python - MenuMaker 日本語化 - モジュール作成

 クラウディア
1. 概要
2. 本体にマージ処理削除オプション追加
3. モジュール構成
4. メインモジュール
5. デスクトップごとのモジュール
6. 操作

1. 概要

 試行錯誤の末、本体は、マージ処理削除オプションを追加するだけ・・・。  メニュー作成後に日本語化することにしました。

2. 本体にマージ処理削除オプション追加

 元のソースに、マージ処理をスキップするオプションを追加します。

vi /usr/local/share/menumaker/MenuMaker/CLI.py

noDebian = False  # Exclude Debian apps database

vStr = "be verbose"
 マージスキップのオプション有無を示す、「bool」型の変数「noMerge」を定義して「false」で初期化します。

noDebian = False  # Exclude Debian apps database
noMerge = False  # Exclude Merge proccess

vStr = "be verbose"

        "wrong argument %s for option %s" % (value, opt))


class OP(_OP):
 「マージ」オプションがつけられていたら、オプションを有効にする関数を追加します。

        "wrong argument %s for option %s" % (value, opt))


nmStr = "skip merging"

def nmOpt(option, opt, value, parser):
    global noMerge
    noMerge = True


class OP(_OP):

op.add_option("-s", "--skip", metavar="list", nargs=1,
              type="string", action="callback", callback=sOpt, help=sStr)

opts, args = op.parse_args()
 「マージスキップ」のオプションを、「--no-merge」として定義し、有効化する関数を組み込みます。

op.add_option("-s", "--skip", metavar="list", nargs=1,
              type="string", action="callback", callback=sOpt, help=sStr)
op.add_option("--no-merge", action="callback", callback=nmOpt, help=nmStr)


opts, args = op.parse_args()

merged = Prophet.merge(legacy + desktop + debian)
 マージする処理を、「--no-merge」のオプションを指定したら、スキップしています。

if noMerge:
    msg("  skipping Merge")
    merged = legacy + desktop + debian
else:
    merged = Prophet.merge(legacy + desktop + debian)

3. モジュール構成

 以下のようなモジュール構成にします。

jmenumaker/
|-- jmmaker.py
`-- MenuMaker
    |-- __init__.py
    |-- CLI.py
    |-- Env.py
    |-- Fluxbox.py
    |-- IceWM.py
    |-- JWM.py
    `-- Openbox.py
 「MenuMaker」の猿真似で、複雑なところはよくわからないので、わたしが書けるように書いています。

4. メインモジュール

 「jmenumaker/jmmaker.py」は、下記のように記述します。
import os
import sys; sys.path = [os.getcwd()] + sys.path
import MenuMaker.CLI

MenuMaker.CLI.main()
 パスの設定(ディレクトリごと、どこに置いても動けるように)と、「MenuMaker」以下の呼出しと実行です。  「jmenumaker/MenuMaker/__init__.py」は、何を書いたらいいかわからないので、何も記述していません。  「jmenumaker/MenuMaker/CLI.py」が、実際に作業をしています。
import os
import subprocess
import MenuMaker
from MenuMaker import Env

def read_menu(filename):
    f = open(filename, "r")                                                     #    ファイルオープン

    lines = f.readlines()

    f.close()
    return lines

label_dict = {
    "Configure"   : "設定",
    "Development" : "開発",
    "Editors"     : "エディタ",
    "Exit"        : "終了",
    "Graphics"    : "グラフィックス",
    "Multimedia"  : "マルチメディア",
    "Network"     : "ネットワーク",
    "Office"      : "オフィス",
    "Reconfig"    : "再設定",
    "Restart"     : "再起動",
    "Settings"    : "設定",
    "Shells"      : "シェル",
    "Styles"      : "スタイル",
    "System"      : "システム",
    "Utilities"   : "ユーティリティ",
    "Workspaces"  : "ワークスペース",
}

def update_menu(lines, env):

    for i in range(0, len(lines)-1):
        for key, value in label_dict.items():
            lines[i] = lines[i].replace(env.prefix + key + env.suffix, env.prefix + value + env.suffix)

    env.set_end_menu(lines)

def write_menu(filename, lines):
    f = open(filename, "w")                                                     #    ファイルオープン

    f.writelines(lines)

    f.close()
    return

def main():
    env = Env.Env()                                                             #    環境設定

    #    本当は、mmaker の有無をチェックしなくちゃダメなんだろうな

    result = subprocess.call(['mmaker', '-vf', '--no-debian', '--no-legacy', '--no-merge', env.name])

    l = read_menu(env.filename)

    lines = list()

    for i in l:
        lines.append(i)

    update_menu(lines, env)
    write_menu(env.filename, lines)

if __name__=='__main__':
    main()


 「jmenumaker/MenuMaker/Env.py」で、システム・デスクトップの状況を判断しています。
import os
from MenuMaker import Fluxbox
from MenuMaker import IceWM
from MenuMaker import JWM
from MenuMaker import Openbox

def pgrep(pattern):
    """return a list with process IDs which matches the selection criteria"""
    args = ["pgrep", "-a", str(pattern)]
    out = os.popen(" ".join(args)).read().strip()

    if (out != ''):
        return True
    else:
        return False

class Env:

    def __init__(self):
        self.sysname = os.environ['HOSTTYPE']

        if (pgrep("fluxbox")):
            self.desktop = Fluxbox.Fluxbox()
        elif (pgrep("icewm")):
            self.desktop = IceWM.IceWM()
        elif (pgrep("jwm")):
            self.desktop = JWM.JWM()
        elif (pgrep("openbox")):
            self.desktop = Openbox.Openbox()

        self.filename = self.desktop.filename
        self.prefix = self.desktop.prefix
        self.suffix = self.desktop.suffix
        self.name = self.desktop.frontend

    def set_end_menu(self, lines):
        try:
            self.desktop.set_end_menu(lines)
        except AttributeError:
            pass



5. デスクトップごとのモジュール

 デスクトップごとのモジュールです。  ただし、2020年1月6日時点で、「JWM」しか、動作確認していません。  「jmenumaker/MenuMaker/Fluxbox.py」
import os

class Fluxbox:
    def __init__(self):
        self.frontend = 'Fluxbox'
        self.filename = os.environ.get('HOME') + '/.fluxbox/menu'
        self.prefix = "("
        self.suffix = ")"



 「jmenumaker/MenuMaker/IceWM.py」
import os

class IceWM:
    def __init__(self):
        self.frontend = 'IceWM'
        self.filename = os.environ.get('HOME') + '/.icewm/menu'
        self.prefix = "menu \""
        self.suffix = "\""


 「jmenumaker/MenuMaker/JWM.py」
import os

class JWM:
    def __init__(self):
        self.frontend = 'JWM'
        self.filename = os.environ.get('HOME') + '/.jwmrc'
        self.prefix = "label=\""
        self.suffix = "\""

    def set_end_menu(self, lines):

        if '<Restart label="再起動" icon="restart.png"/>' + "\n" in lines:
            i = lines.index('<Restart label="再起動" icon="restart.png"/>'+"\n")
            lines[i] = lines[i].replace('<Restart label="再起動" icon="restart.png"/>'+"\n", '<Restart label="JWM 再起動" icon="restart.png"/>'+"\n")

        if '</RootMenu>' + "\n" in lines:
            point = len(lines) - lines.index('</RootMenu>'+"\n")

        lines.insert(-point, '<Program label="再起動">sudo /sbin/reboot</Program>'+"\n")
        lines.insert(-point, '<Program label="シャットダウン">sudo /sbin/poweroff</Program>'+"\n")


 ちょっと、こいつは苦し紛れ、「再起動」が、「JWM」なのかオペレーティングシステムなのかわからないので書き換えたりしています。  「jmenumaker/MenuMaker/Openbox.py」
import os

class Openbox:
    def __init__(self):
        self.frontend = 'Openbox'
        self.filename = os.environ.get('HOME') + '/.config/openbox/menu.xml'
        self.prefix = "label=\""
        self.suffix = "\""

    def set_enf_menu(self, lines):
        lines.insert(-2, '        <separator/>')
        lines.insert(-2, '        <menu id="50" label="終了">')
        lines.insert(-2, '             <item label="ログアウト"> <action name="Exit"/> </item>')
        lines.insert(-2, '             <item label="再起動"> <action name="Execute">')
        lines.insert(-2, '                 <execute>sudo /sbin/reboot</execute>')
        lines.insert(-2, '             </action> </item>')
        lines.insert(-2, '             <item label="シャットダウン"> <action name="Execute">')
        lines.insert(-2, '                 <execute>sudo /sbin/poweroff</execute>')
        lines.insert(-2, '             </action> </item>')
        lines.insert(-2, '        </menu>')

6. 操作

 フォルダごと、上記までを作成します。  デスクトップにログインして、端末を開いて

python3.6 パス/jmenumaker/jmmaker.py
 で、メニューが作成されます。  2020年6月2日、「python」のデフォルトバージョンが変わっていますのでご注意。  上記コマンドは

python3.7 パス/jmenumaker/jmmaker.py
 になっています。
ハイスピードプランKiPuRuTSUKUMOネットショップTokyo Speed Wi-Fi
 
 
カウンタバックグラウンド