Skip to content

Commit 4a8e22d

Browse files
committed
mpris: Port to Firefox
Make all necessary changes to the MPRIS support to port Streamkeys to Firefox. The problems found are the following: * Firefox does not have runtime.onSuspend(). Remove it for now. (Do we really need it anyway?)
1 parent dce7644 commit 4a8e22d

4 files changed

Lines changed: 112 additions & 51 deletions

File tree

README.md

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,24 +126,51 @@ installed.
126126

127127
#### Install host script
128128

129-
To install the host script, locate the extension ID from the Chrome extensions page
130-
and run the following commands:
129+
###### Chrome
130+
131+
To install the host script for Chrome, locate the extension ID from the Chrome
132+
extensions page and run the following commands:
131133

132134
```bash
133135
$ extension_id="....."
134136
$ installer=$(find $HOME/.config -name "mpris_host_setup.py" | grep ${extension_id})
135137
$ python3 ${installer} install ${extension_id}
136138
```
137139

140+
###### Firefox
141+
142+
To install the host script for Firefox run the following commands:
143+
144+
```bash
145+
$ xpi=$(find $HOME/.mozilla -name "streamkeys@streamkeys.com.xpi")
146+
$ tmpdir=$(mktemp -d streamkeys.XXXXXX --tmpdir)
147+
$ unzip -d ${tmpdir} ${xpi}
148+
$ python3 ${tmpdir}/native/mpris_host_setup.py install-ff
149+
$ rm -r ${tmpdir}
150+
```
151+
138152
#### Uninstall host script
139153

140-
To uninstall the host script, locate the extension ID from the Chrome extensions page
141-
and run the following commands:
154+
###### Chrome
155+
156+
To uninstall the host script for Chrome, locate the extension ID from the
157+
Chrome extensions page and run the following commands:
142158

143159
```bash
144-
$ extension_id="....."
145-
$ installer=$(find $HOME/.config -name "mpris_host_setup.py" | grep ${extension_id})
146-
$ python3 ${installer} uninstall
160+
$ xpi=$(find $HOME/.mozilla -name "streamkeys@streamkeys.com.xpi")
161+
$ tmpdir=$(mktemp -d streamkeys.XXXXXX --tmpdir)
162+
$ unzip -d ${tmpdir} ${xpi}
163+
$ python3 ${tmpdir}/native/mpris_host_setup.py uninstall-ff
164+
$ rm -r ${tmpdir}
165+
```
166+
167+
###### Firefox
168+
169+
To uninstall the host script for Firefox run the following commands:
170+
171+
```bash
172+
$ installer=$(find $HOME/.mozilla -name "mpris_host_setup.py")
173+
$ python3 ${installer} uninstall-ff
147174
```
148175

149176
## License (MIT)

code/js/background.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -384,13 +384,6 @@
384384
console.log("Starting native messaging host");
385385
mprisPort = chrome.runtime.connectNative("org.mpris.streamkeys_host");
386386
mprisPort.onMessage.addListener(handleNativeMsg);
387-
388-
chrome.runtime.onSuspend.addListener(function() {
389-
if (!--connections)
390-
mprisPort.postMessage({ command: "quit" });
391-
mprisPort.onMessage.removeListener(handleNativeMsg);
392-
mprisPort.disconnect();
393-
});
394387
}
395388
}
396389
});

code/manifest.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,8 @@
3737
"js/inject/seesu_inject.js",
3838
"js/controllers/*"
3939
],
40-
"permissions": ["tabs", "storage", "http://*/*", "https://*/*"],
41-
"optional_permissions": [ "notifications", "http://*/*", "https://*/*",
42-
"nativeMessaging"],
40+
"permissions": ["tabs", "storage", "http://*/*", "https://*/*", "nativeMessaging"],
41+
"optional_permissions": [ "notifications", "http://*/*", "https://*/*"],
4342
"commands": {
4443
"playPause": {
4544
"suggested_key": {

code/native/mpris_host_setup.py

Lines changed: 76 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,21 @@
1010

1111
HOST_FILENAME = "streamkeys_mpris.py"
1212
HOST_MANIFEST_FILENAME = "org.mpris.streamkeys_host.json"
13-
HOST_MANIFEST = {
13+
CHROME_HOST_MANIFEST = {
1414
"name": "org.mpris.streamkeys_host",
1515
"description": "Streamkeys MPRIS native messaging host",
1616
"path": None,
1717
"type": "stdio",
1818
"allowed_origins": []
1919
}
20+
FIREFOX_HOST_MANIFEST = {
21+
"name": "org.mpris.streamkeys_host",
22+
"description": "Streamkeys MPRIS native messaging host",
23+
"path": None,
24+
"type": "stdio",
25+
"allowed_extensions": []
26+
}
27+
FIREFOX_EXT_ID = "streamkeys@streamkeys.com"
2028
XDG_CONFIG_HOME = os.environ.get("XDG_CONFIG_HOME",
2129
default=os.path.expanduser("~/.config"))
2230

@@ -31,20 +39,51 @@ def initialize_parser():
3139
p = subparsers.add_parser("install",
3240
help="Install the native messaging host")
3341
p.add_argument("id", help="The extension ID")
34-
p.set_defaults(func=main_install)
42+
p.set_defaults(func=main_install, firefox=False)
3543

3644
p = subparsers.add_parser("uninstall",
3745
help="Uninstall the native messaging host")
38-
p.set_defaults(func=main_uninstall)
46+
p.set_defaults(func=main_uninstall, firefox=False)
47+
48+
p = subparsers.add_parser("install-ff",
49+
help="Install the native messaging host for"
50+
" Firefox instead of Chrome")
51+
p.add_argument("--id", default=FIREFOX_EXT_ID, help="The extension ID")
52+
p.set_defaults(func=main_install, firefox=True)
53+
54+
p = subparsers.add_parser("uninstall-ff",
55+
help="Uninstall the native messaging host for"
56+
" Firefox instead of Chrome")
57+
p.set_defaults(func=main_uninstall, firefox=True)
3958
return parser
4059

4160

42-
def get_xdg_config_paths():
61+
def get_chrome_xdg_config_paths():
4362
return [os.path.join(XDG_CONFIG_HOME, "chromium"),
4463
os.path.join(XDG_CONFIG_HOME, "google-chrome")]
4564

4665

47-
def install_host(ext_id, install_dir):
66+
def get_chrome_manifest_paths():
67+
paths = []
68+
xdg_paths = get_chrome_xdg_config_paths()
69+
for path in xdg_paths:
70+
if not os.path.exists(path):
71+
continue
72+
message_hosts = os.path.join(path, "NativeMessagingHosts")
73+
manifest_path = os.path.join(message_hosts, HOST_MANIFEST_FILENAME)
74+
paths.append(manifest_path)
75+
return paths
76+
77+
78+
def get_firefox_manifest_paths():
79+
paths = []
80+
message_hosts = os.path.expanduser("~/.mozilla/native-messaging-hosts")
81+
manifest_path = os.path.join(message_hosts, HOST_MANIFEST_FILENAME)
82+
paths.append(manifest_path)
83+
return paths
84+
85+
86+
def install_host(ext_id, install_dir, firefox=False):
4887
# Copy the host script
4988
host_path = os.path.join(install_dir, HOST_FILENAME)
5089
os.makedirs(install_dir, exist_ok=True)
@@ -56,37 +95,39 @@ def install_host(ext_id, install_dir):
5695
os.chmod(host_path, 0o744)
5796

5897
# Create the manifest file
59-
xdg_paths = get_xdg_config_paths()
60-
manifest = dict(HOST_MANIFEST)
61-
manifest["path"] = host_path
62-
manifest["allowed_origins"].append("chrome-extension://%s/" % ext_id)
63-
for path in xdg_paths:
64-
if not os.path.exists(path):
65-
continue
66-
message_hosts = os.path.join(path, "NativeMessagingHosts")
67-
manifest_path = os.path.join(message_hosts, HOST_MANIFEST_FILENAME)
68-
69-
os.makedirs(message_hosts, exist_ok=True)
70-
with open(manifest_path, "w") as f:
98+
if firefox:
99+
manifest_paths = get_firefox_manifest_paths()
100+
manifest = dict(FIREFOX_HOST_MANIFEST)
101+
manifest["path"] = host_path
102+
manifest["allowed_extensions"].append(ext_id)
103+
else:
104+
manifest_paths = get_chrome_manifest_paths()
105+
manifest = dict(CHROME_HOST_MANIFEST)
106+
manifest["path"] = host_path
107+
manifest["allowed_origins"].append("chrome-extension://%s/" % ext_id)
108+
109+
for path in manifest_paths:
110+
os.makedirs(os.path.dirname(path), exist_ok=True)
111+
with open(path, "w") as f:
71112
json.dump(manifest, f, indent=2)
72-
os.chmod(manifest_path, 0o644)
113+
os.chmod(path, 0o644)
73114

74115

75-
def uninstall_host(install_dir):
116+
def uninstall_host(install_dir, firefox=False):
76117
# Remove host script
77118
host_path = os.path.join(install_dir, HOST_FILENAME)
78119
if os.path.isfile(host_path):
79120
os.remove(host_path)
80121

81122
# Remove manifest file
82-
xdg_paths = get_xdg_config_paths()
83-
for path in xdg_paths:
84-
if not os.path.exists(path):
85-
continue
86-
message_hosts = os.path.join(path, "NativeMessagingHosts")
87-
manifest_path = os.path.join(message_hosts, HOST_MANIFEST_FILENAME)
88-
if os.path.isfile(manifest_path):
89-
os.remove(manifest_path)
123+
if firefox:
124+
manifest_paths = get_firefox_manifest_paths()
125+
else:
126+
manifest_paths = get_chrome_manifest_paths()
127+
128+
for path in manifest_paths:
129+
if os.path.isfile(path):
130+
os.remove(path)
90131

91132

92133
def setup_logger(level=logging.DEBUG):
@@ -109,11 +150,12 @@ def main():
109150

110151

111152
def main_install(args):
112-
# Chrome's extension IDs are in hexadecimal but using a-p, referred
113-
# internally as "mpdecimal". See https://stackoverflow.com/a/2050916
114-
if (len(args.id) != 32
115-
or any(ord(c) not in range(97, 113) for c in args.id)):
116-
raise RuntimeError("Not valid extension ID: %s" % args.id)
153+
if not args.firefox:
154+
# Chrome's extension IDs are in hexadecimal but using a-p, referred
155+
# internally as "mpdecimal". See https://stackoverflow.com/a/2050916
156+
if (len(args.id) != 32
157+
or any(ord(c) not in range(97, 113) for c in args.id)):
158+
raise RuntimeError("Not valid extension ID: %s" % args.id)
117159

118160
try:
119161
from gi.repository import GLib, Gio # noqa: F401
@@ -127,11 +169,11 @@ def main_install(args):
127169
raise RuntimeError("Required dependency `python3-pydbus' not"
128170
" found")
129171

130-
install_host(args.id, args.install_dir)
172+
install_host(args.id, args.install_dir, firefox=args.firefox)
131173

132174

133175
def main_uninstall(args):
134-
uninstall_host(args.install_dir)
176+
uninstall_host(args.install_dir, firefox=args.firefox)
135177

136178

137179
if __name__ == "__main__":

0 commit comments

Comments
 (0)