Firefox のプロファイルフォルダを探す
Firefox のプロファイルフォルダを探す Python の関数 get_profile_path(profile_name=None) を作ったので晒してみる。
もう一工夫すれば Thunderbird, SeaMonkey らにも対応できるかも。
Firefox 3 の クッキーを読み出そうとしていたときの副産物。クッキーを保持している cookies.sqlite のパスを直打ちしないために profiles.ini を探したり読んだりでしていたら、これが出来上がった。
os.path.join(get_profile_path(), u'cookies.sqlite')
といった感じで使っている。
参考
コード
5月7日現在、 Mac, Linux での動作は未確認。os.path.expanduser でチルダ展開しないと動かない? Linux での確認予定はあり。 Mac は用意できないため、確認できないと思う。
# coding: utf-8 u"""Firefox のプロファイルフォルダを探す 参考: http://kb.mozillazine.org/Profiles.ini_file http://kb.mozillazine.org/Profile_folder http://kb.mozillazine.org/Profile_folder_-_Firefox """ import os import ConfigParser def get_profiles_folder(): u"""profiles.ini ファイルのあるフォルダを得る""" if os.name == u'nt': profiles_folder = ur'%(AppData)s\Mozilla\Firefox' % os.environ if not os.path.isdir(profiles_folder): raise IOError(u'Profile folder is not found') elif os.name == u'mac': #XXX: 動作未確認 profiles_folders = ( u'~/Library/Mozilla/Firefox', u'~/Library/Application Support/Firefox') for d in profiles_folders: if os.path.isdir(d): profiles_folder = d break else: raise IOError(u'Profile folder is not found') else: #XXX: 動作未確認 profiles_folder = u'~/.mozilla/firefox' if not os.path.isdir(profiles_folder): raise IOError(u'Profile folder is not found') return profiles_folder def get_profiles_ini_path(): u"""profiles.ini ファイルのパスを得る""" profiles_ini_path = os.path.join( get_profiles_folder(), u'profiles.ini') if not os.path.isfile(profiles_ini_path): raise IOError(u'profiles.ini is not found') return profiles_ini_path def get_profile(profile_name=None): u"""profiles.ini より profile_name の設定を読み出す""" parser = ConfigParser.SafeConfigParser() parser.read(get_profiles_ini_path()) if profile_name: # プロファイル名 profile_name の指定がある、これを探す sections = [s for s in parser.sections() if s != u'General'] for section in sections: if parser.has_option(section, u'Name'): if parser.get(section, u'Name'): section_name = section break else: raise IOError(u'%r is not section' % profile_name) else: # プロファイル名 profile_name の指定が無い、デフォルトを探す sections = [s for s in parser.sections() if s != u'General'] if len(sections) == 1: # プロファイルが 1 つだけの時、これを用いる section_name = sections[0] else: # 複数あるとき、 Defalut=1 を持つプロファイルを探す for section in sections: if parser.has_option(section, u'Default') and \ parser.getboolean(section, u'Default'): section_name = section break else: raise IOError(u'The default profile is not found') profile = dict(parser.items(section_name)) for key in ('IsRelative', 'Default'): key = key.lower() if key in profile: profile[key] = int(profile[key]) return profile def get_profile_path(profile_name=None): u"""profile_name プロファイルが使用しているフォルダを返す""" profile = get_profile(profile_name) if profile[u'IsRelative'.lower()]: profile_dir = os.path.join( get_profiles_folder(), profile[u'Path'.lower()],) else: profile_dir = profile[u'Path'] return os.path.normpath(profile_dir)
自分用メモ os.expandvars
posixpath.expandvars (Linux などの os.expandvars) は存在しない環境変数 ${name} をそのまま返す。ntpath.expandvars (Windows 上での os.expandvars) は ${name} を削除する。
どちらにせよ、存在しない環境変数を見つけても例外が起こったりはしない。あたりまえの動作といわれればそれまで。
存在しないとき動作を変えたければ '%(name)s' % os.environ で KeyError を起こす。もしくはめんどくさがらずに 'name' in os.environ できちんと調べる。