Skip to content

Commit d8374cd

Browse files
committedOct 9, 2021
feat: Gérer le plugin Tubed.
1 parent 5a52f65 commit d8374cd

29 files changed

+620
-196
lines changed
 

‎src/background/menu.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ const capitalize = function (text) {
2020
*
2121
* @param {browser.contextMenus.OnClickData} info Les informations fournies par
2222
* le menu contextuel.
23-
* @returns {Promise<string[]>} Une promesse contenant les liens récupérés.
23+
* @returns {Promise<(string|undefined)[]>} Une promesse contenant les liens
24+
* récupérés.
2425
*/
2526
const aggregate = async function (info) {
2627
if ("bookmarkId" in info) {

‎src/background/migrate.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ browser.storage.local.get().then(async (current) => {
7474
"menu-actions": ["send", "insert", "add"],
7575
"menu-contexts": DEFAULT_MENU_CONTEXTS[name],
7676
"youtube-playlist": "playlist",
77-
"youtube-order": "",
77+
"youtube-order": "default",
7878
});
7979
}
8080
});

‎src/core/index.js

+6-27
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,10 @@
22
* @module
33
*/
44

5-
import { Kodi } from "./jsonrpc/kodi.js";
5+
import { kodi } from "./kodi.js";
66
import { extract } from "./scrapers.js";
77
import { PebkacError } from "./tools/pebkac.js";
88

9-
/**
10-
* Le client JSON-RPC pour contacter Kodi.
11-
*
12-
* @type {Kodi}
13-
*/
14-
export const kodi = new Kodi();
15-
169
/**
1710
* Récupère le lien à analyser parmi les données récupérées.
1811
*
@@ -46,9 +39,11 @@ export const mux = function (urls) {
4639
/**
4740
* Diffuse un média sur Kodi.
4841
*
49-
* @param {string} action L'action à effectuer (<code>"send"</code>,
50-
* <code>"insert"</code> ou <code>"add"</code>).
51-
* @param {string[]} urls La liste des éventuelles URLs.
42+
* @param {string} action L'action à effectuer
43+
* (<code>"send"</code>,
44+
* <code>"insert"</code> ou
45+
* <code>"add"</code>).
46+
* @param {(string|undefined)[]} urls La liste des éventuelles URLs.
5247
* @returns {Promise<void>} Une promesse tenue vide.
5348
*/
5449
export const cast = async function (action, urls) {
@@ -86,19 +81,3 @@ export const cast = async function (action, urls) {
8681
}
8782
}
8883
};
89-
90-
/**
91-
* Ferme la connexion avec Kodi pour forcer la reconnexion avec la nouvelle
92-
* configuration.
93-
*
94-
* @param {browser.storage.StorageChange} changes Les paramètres modifiés dans
95-
* la configuration.
96-
*/
97-
const handleChange = function (changes) {
98-
// Garder seulement les changements liés au serveur.
99-
if (Object.keys(changes).some((k) => k.startsWith("server-"))) {
100-
kodi.close();
101-
}
102-
};
103-
104-
browser.storage.onChanged.addListener(handleChange);

‎src/core/jsonrpc/addons.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* @module
3+
*/
4+
5+
/**
6+
* @typedef {import("./kodi.js").Kodi} Kodi
7+
*/
8+
9+
/**
10+
* Le client JSON-RPC pour contacter l'espace de nom <em>Addons</em> de Kodi.
11+
*
12+
* @see https://kodi.wiki/view/JSON-RPC_API
13+
*/
14+
export const Addons = class {
15+
16+
/**
17+
* Crée un client JSON-RPC pour l'espace de nom <em>Addons</em>.
18+
*
19+
* @param {Kodi} kodi Le client pour contacter Kodi.
20+
*/
21+
constructor(kodi) {
22+
23+
/**
24+
* Le client pour contacter Kodi.
25+
*
26+
* @private
27+
* @type {Kodi}
28+
*/
29+
this._kodi = kodi;
30+
}
31+
32+
/**
33+
* Retourne une liste d'addons gérant un type de contenu.
34+
*
35+
* @param {string} content Le type de contenu géré par les addons à
36+
* retourner (<code>"unknown"</code>,
37+
* <code>"video"</code>, <code>"audio"</code>,
38+
* <code>"image"</code> ou
39+
* <code>"executable"</code>).
40+
* @returns {Promise<string[]>} Une promesse contenant les identifiants des
41+
* addons.
42+
*/
43+
async getAddons(content) {
44+
const results = await this._kodi.send("Addons.GetAddons", {
45+
content,
46+
properties: ["enabled"],
47+
});
48+
return results.addons.filter((a) => a.enabled)
49+
.map((a) => a.addonid);
50+
}
51+
};

‎src/core/jsonrpc/kodi.js

+22-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import { JSONRPC } from "../tools/jsonrpc.js";
66
import { PebkacError } from "../tools/pebkac.js";
7+
import { Addons } from "./addons.js";
78
import { Application } from "./application.js";
89
import { GUI } from "./gui.js";
910
import { Input } from "./input.js";
@@ -112,6 +113,15 @@ export const Kodi = class {
112113
*/
113114
this._jsonrpc = null;
114115

116+
/**
117+
* Le client JSON-RPC pour contacter l'espace de nom <em>Addons</em> de
118+
* Kodi.
119+
*
120+
* @private
121+
* @type {Addons}
122+
*/
123+
this._addons = new Addons(this);
124+
115125
/**
116126
* Le client JSON-RPC pour contacter l'espace de nom
117127
* <em>Application</em> de Kodi.
@@ -169,6 +179,17 @@ export const Kodi = class {
169179
return this._url;
170180
}
171181

182+
/**
183+
* Retourne le client JSON-RPC pour contacter l'espace de nom
184+
* <em>Addons</em> de Kodi.
185+
*
186+
* @returns {Addons} Le client JSON-RPC pour contacter l'espace de nom
187+
* <em>Addons</em> de Kodi.
188+
*/
189+
get addons() {
190+
return this._addons;
191+
}
192+
172193
/**
173194
* Retourne le client JSON-RPC pour contacter l'espace de nom
174195
* <em>Application</em> de Kodi.
@@ -263,8 +284,8 @@ export const Kodi = class {
263284
this._jsonrpc = null;
264285
});
265286
this._jsonrpc.addEventListener("notification", (event) => {
266-
this._input.handleNotification(event);
267287
this._application.handleNotification(event);
288+
this._input.handleNotification(event);
268289
this._player.handleNotification(event);
269290
this._playlist.handleNotification(event);
270291
});

‎src/core/kodi.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* @module
3+
*/
4+
5+
import { Kodi } from "./jsonrpc/kodi.js";
6+
7+
/**
8+
* Le client JSON-RPC pour contacter Kodi.
9+
*
10+
* @type {Kodi}
11+
*/
12+
export const kodi = new Kodi();
13+
14+
/**
15+
* Ferme la connexion avec Kodi pour forcer la reconnexion avec la nouvelle
16+
* configuration.
17+
*
18+
* @param {browser.storage.StorageChange} changes Les paramètres modifiés dans
19+
* la configuration.
20+
*/
21+
const handleChange = function (changes) {
22+
// Garder seulement les changements liés au serveur.
23+
if (Object.keys(changes).some((k) => k.startsWith("server-"))) {
24+
kodi.close();
25+
}
26+
};
27+
28+
browser.storage.onChanged.addListener(handleChange);

‎src/core/labeller/youtube.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
* Extrait le titre d'une vidéo YouTube.
88
*
99
* @param {string} videoId L'identifiant de la vidéo YouTube.
10-
* @returns {Promise<?string>} Une promesse contenant le titre ou
11-
* <code>null</code>.
10+
* @returns {Promise<string>} Une promesse contenant le titre ou le texte pour
11+
* les vidéos non-disponibles.
1212
*/
1313
export const extractVideo = async function (videoId) {
1414
const response = await fetch(`https://www.youtube.com/watch?v=${videoId}`);
@@ -19,11 +19,11 @@ export const extractVideo = async function (videoId) {
1919
};
2020

2121
/**
22-
* Extrait le titre d'une liste de lecture YouTube.
22+
* Extrait le titre d'une playlist YouTube.
2323
*
2424
* @param {string} playlistId L'identifiant de la playlist YouTube.
25-
* @returns {Promise<?string>} Une promesse contenant le titre ou
26-
* <code>null</code>.
25+
* @returns {Promise<string>} Une promesse contenant le titre ou le texte par
26+
* défaut pour les playlists sans titre.
2727
*/
2828
export const extractPlaylist = async function (playlistId) {
2929
const response = await fetch("https://www.youtube.com/playlist" +

‎src/core/plugin/youtube.js

+36-9
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,23 @@
44
*/
55
/* eslint-disable require-await */
66

7+
import { kodi } from "../kodi.js";
78
import * as labeller from "../labeller/youtube.js";
89
import { matchPattern } from "../tools/matchpattern.js";
910

1011
/**
11-
* L'URL de l'extension pour lire des vidéos issues de YouTube.
12+
* L'URL de l'extension <em>YouTube</em> pour lire des vidéos issues de YouTube.
1213
*
1314
* @type {string}
1415
*/
15-
const PLUGIN_URL = "plugin://plugin.video.youtube/play/";
16+
const YOUTUBE_PLUGIN_URL = "plugin://plugin.video.youtube/play/";
17+
18+
/**
19+
* L'URL de l'extension <em>Tubed</em> pour lire des vidéos issues de YouTube.
20+
*
21+
* @type {string}
22+
*/
23+
const TUBED_PLUGIN_URL = "plugin://plugin.video.tubed/?mode=play";
1624

1725
/**
1826
* Génère l'URL d'une vidéo dans l'extension YouTube.
@@ -24,8 +32,17 @@ const PLUGIN_URL = "plugin://plugin.video.youtube/play/";
2432
* <em>fichier</em>.
2533
*/
2634
export const generateVideoUrl = async function (videoId, incognito) {
27-
return `${PLUGIN_URL}?video_id=${videoId}` +
28-
`&incognito=${incognito.toString()}`;
35+
const addons = await kodi.addons.getAddons("video");
36+
// Si les deux extensions YouTube et Tubed sont présentes ou si aucune est
37+
// présente : envoyer les vidéos à YouTube ; sinon envoyer à l'extension
38+
// présente.
39+
if (addons.includes("plugin.video.tubed") &&
40+
!addons.includes("plugin.video.youtube")) {
41+
return `${TUBED_PLUGIN_URL}&video_id=${videoId}`;
42+
}
43+
44+
return `${YOUTUBE_PLUGIN_URL}?video_id=${videoId}` +
45+
`&incognito=${incognito.toString()}`;
2946
};
3047

3148
/**
@@ -38,14 +55,23 @@ export const generateVideoUrl = async function (videoId, incognito) {
3855
* <em>fichier</em>.
3956
*/
4057
export const generatePlaylistUrl = async function (playlistId, incognito) {
58+
const addons = await kodi.addons.getAddons("video");
59+
// Si les deux extensions YouTube et Tubed sont présentes ou si aucune est
60+
// présente : envoyer les vidéos à YouTube ; sinon envoyer à l'extension
61+
// présente.
62+
if (addons.includes("plugin.video.tubed") &&
63+
!addons.includes("plugin.video.youtube")) {
64+
return `${TUBED_PLUGIN_URL}&playlist_id=${playlistId}`;
65+
}
66+
4167
const config = await browser.storage.local.get(["youtube-order"]);
42-
return `${PLUGIN_URL}?playlist_id=${playlistId}` +
43-
`&order=${config["youtube-order"]}` +
44-
`&play=1&incognito=${incognito.toString()}`;
68+
return `${YOUTUBE_PLUGIN_URL}?playlist_id=${playlistId}` +
69+
`&order=${config["youtube-order"]}` +
70+
`&play=1&incognito=${incognito.toString()}`;
4571
};
4672

4773
/**
48-
* Extrait le titre d'une vidéo ou d'une liste de lecture YouTube.
74+
* Extrait le titre d'une vidéo ou d'une playlist YouTube.
4975
*
5076
* @param {URL} url L'URL utilisant le plugin de YouTube.
5177
* @returns {Promise<?string>} Une promesse contenant le titre ou
@@ -61,4 +87,5 @@ const action = async function ({ searchParams }) {
6187
return null;
6288
};
6389
export const extract = matchPattern(action,
64-
"plugin://plugin.video.youtube/play/*");
90+
"plugin://plugin.video.youtube/play/*",
91+
"plugin://plugin.video.tubed/*");

‎src/popup/script.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
* @module
33
*/
44

5-
import { cast, kodi } from "../core/index.js";
5+
import { cast } from "../core/index.js";
6+
import { kodi } from "../core/kodi.js";
67
import { complete } from "../core/labellers.js";
78
import { notify } from "../core/tools/notify.js";
89
import { ping } from "../core/tools/ping.js";

0 commit comments

Comments
 (0)
Please sign in to comment.