Python - MenuMaker 日本語化 - アイコン - 作業振り分け Env.py

クラウディア 
1. 作業振り分け Env.py
2. 前半部
3. 後半部

1. 作業振り分け Env.py

 「Env.py」は、「CLI」から各種デスクトップの処理への橋渡しを行うクラスになります。  また、各デスクトップで行う共通的な処理もこのクラス内でメソッドを提供しています。  これが、最も長いソースになるのかしら・・・。  ちょっと分けて掲載します。

2. 前半部

 初期化「__init__」が、前半部を占めています。  オペレーティングシステムシステム依存となる「public」な環境変数と、デスクトップごととなる「public」な環境変数を設定しています。

##
# @file Env.py
# @version 0.1
# @author Show.Kit・更新者
# @date 2020年6月6日・2020年6月8日
# @brief プラットフォームごとの環境変数を設定する

import os
import pprint
import subprocess
import sys
from MenuMaker import Fluxbox
from MenuMaker import IceWM
from MenuMaker import JWM
from MenuMaker import Openbox
from _ast import Try

##
# デスクトプ特有のプロセス有無を調べる
# @param pattern デスクトップ特有のプロセス名
# @brief デスクトプ特有のプロセス有無を調べる

def pgrep(pattern):

    ##
    # @brief 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
# @brief プラットフォームごとの環境変数を設定する

class Env:

    ##
    # @brief Env クラスの初期化関数
    # @return None 戻り値なし
    # @details オペレーティングシステム・デスクトップに合わせて、特有の変数を設定する

    def __init__(self):

        ## オペレーティングシステムの名称
        self.sysname = os.environ['HOSTTYPE']

        ## MenuMaker の本体
        self.mmaker = None

        if (self.sysname == 'FreeBSD'):
            self.mmaker = '/usr/local/bin/mmaker'
        else:
            self.mmaker = '/usr/bin/mmaker'

        ## デスクトップの定義クラス
        self.desktop = None

        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

        ## .desktop の存在するディレクトリ
        self.directory_app = None

        ## .xpm の存在するディレクトリ
        self.directory_xpm = None

        ## .xpm の存在するディレクトリ
        self.directory_xpm = None

        ## .xpm の存在するディレクトリ
        self.directory_png = None

        ## .xpm の存在するディレクトリ
        self.directory_icon_apps = None

        ## .xpm の存在するディレクトリ
        self.directory_icon_category = None

        if (self.sysname == 'FreeBSD'):
            self.directory_app = '/usr/local/share/applications'
            self.directory_xpm = '/usr/local/share/pixmaps'
            self.directory_png = '/usr/local/share/icons/hicolor/48x48/apps'
            self.directory_icon_apps = '/usr/local/share/icons/Papirus/48x48/apps'
            self.directory_icon_category = '/usr/local/share/icons/Papirus/48x48/categories'
        else:
            self.directory_app = '/usr/share/applications'
            self.directory_xpm = '/usr/share/pixmaps'
            self.directory_png = '/usr/share/icons/hicolor/48x48/apps'
            self.directory_icon_apps = '/usr/share/icons/Papirus/48x48/apps'
            self.directory_icon_category = '/usr/share/icons/Papirus/48x48/categories'

        ## メニューのプログラム行 キーワード
        self.exec_keyword = self.desktop.exec_keyword
 23~34行の「pgrep」は、なんのデスクトップかがわかる、セッションプロセスのプロセス名が存在するかを調べて、デスクトップを判定するためのものです。

3. 後半部


##################################################################################
    ##
    # メニューのカテゴリ行を日本語に変える
    # @param line     対象行
    # @param label_en カテゴリ名英語
    # @param label_jp カテゴリ名日本語
    # @param icon     アイコンファイル(拡張子なし)

    def update_category(self, line, label_en, label_jp, icon):
        try:
            line = self.desktop.update_category(self, line, label_en, label_jp, self.directory_icon_category, icon)
        except AttributeError:
            print('Exception update_category')

        return line

######
    # @brief 終了メニュー設定
    # @return None 戻り値なし
    # @details 終了メニューを設定すべきメニューであれば、終了メニューを設定する

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

    ##
    # @brief ディレクトリ内のファイルを再帰的に検索
    # @param pathname 検索対象のディレクトリ名

    def find_all_file(self, pathname):
        for root, dirs, files in os.walk(pathname):
            yield root
            for file in files:
                yield os.path.join(root, file)

    ##
    # @brief フルパスのファイル名を分解して返す
    # @param fullpath フルパスファイル名
    # @return dirname パス
    # @return name    ファイル名
    # @return extend  拡張子 . つき

    def mysplit(self, fullpath):
        dirname, basename = os.path.split(fullpath)
        name, extend = os.path.splitext(basename)
        return dirname, name, extend

    ##
    # @brief ImakeMagick を使用して画像ファイルを変換する
    # @param from_file_path 変換前 画像ファイル フルパス
    # @param to_file_path   変換後 画像ファイル フルパス
    # @return None なし

    def convert(self, from_file_path, to_file_path):

        ## 変換

        result = subprocess.call(['convert', '-background', 'none', from_file_path, to_file_path])

        if (result != 0):
            print("convet", from_file_path, to_file_path, "error")

######
    # @brief  デスクトップクラスに search_icon メソッドが存在すればコールする
    # @return dic_exec_icon exec → icon 辞書

    def get_dic_exec_icon(self):

        ## exec → icon 辞書
        dic_exec_icon = {}

        for filepath in self.find_all_file(self.directory_app):
            name, extend = os.path.splitext(filepath)

            if (extend != '.desktop'):
                continue

            f = open(filepath, "r")                                             ## File Open
            lines = f.readlines()                                               ## Read
            f.close()                                                           ## Close

            pname = None                                                        ## ロードモジュール名
            iname = None                                                        ## アイコン名

            for i in range(0, len(lines)-1):

                str = lines[i].rstrip('\n')                                     ## 行末の改行削除

                if (str.startswith('Exec')):                                    ## ロードモジュールの行
                    head, pname = str.split('=', 1)

                if (str.startswith('Icon')):                                    ## icon
                    head, iname = str.split('=', 1)
                    iname = iname.lower()                                       ## icon はすべて小文字にしちゃう

                if ((pname != None) and (iname != None)):                       ## ロードモジュールとアイコン共に検出
                    pname = pname.split(' ')[0]                                 ## 実行文はロードモジュール名のみにする
                    dic_exec_icon[pname] = iname                                ## 辞書に追加したら終了
                    break                                                       ## アイコンが見つかったらループは終了

        try:
            dic_exec_icon = self.desktop.get_dic_exec_icon(self, dic_exec_icon)
        except AttributeError:
            dic_exec_icon = {}

        return dic_exec_icon

    ##
    # @brief  デスクトップクラスに set_menu_icon メソッドが存在すればコールする
    # @param  line     メニューの対象行
    # @param  nextline line の次の行(Openbox 以外では使用しない)
    # @param  dic_exec_icon exec → icon 辞書
    # @return line 更新した行(set_menu_icon メソッドがない場合はそのまま返す)

    def set_menu_icon(self, line, nextline, dic_exec_icon):
 173~180行で、「ImageMagick」を使用して、アイコン画像ファイルの変換を行っています。  ミソとなるのが、「-background none」のオプションで、これをつけないと、アイコンの背景色が白くなってしまいます。  このオプションに関しては、「svg を png に変換するワンライナー - Qiita」を参考にさせていただきました。
ハイスピードプラン