1 Commits

Author SHA1 Message Date
fa5afd5074 Mise à jour de 'package.json' 2021-07-23 11:43:09 +02:00
4 changed files with 163 additions and 144 deletions

View File

@ -1,6 +1,9 @@
// import { ImplementableApi } from './implementableApi';
// Api request lib // Api request lib
import fetch, { FetchError, Headers } from "node-fetch"; import fetch, { FetchError, Headers } from "node-fetch";
import { URL, URLSearchParams } from "url"; import { URL, URLSearchParams } from "url";
import FormData from "form-data";
// import dedent from "ts-dedent";
namespace PeerTubeRequester { namespace PeerTubeRequester {
export type Config = { export type Config = {
@ -16,6 +19,22 @@ type UploadInstruction = {
targetUrl: string; targetUrl: string;
}; };
type ClientToken = {
client_id: string;
client_secret: string;
grant_type: "password";
response_type: "code";
username: string;
password: string;
};
type UserToken = {
access_token: string;
token_type: string;
expires_in: string;
refresh_token: string;
};
class PeerTubeRequester { class PeerTubeRequester {
readonly domain_name: URL; readonly domain_name: URL;
readonly username: string; readonly username: string;
@ -27,7 +46,7 @@ class PeerTubeRequester {
this.password = config.password; this.password = config.password;
} }
private async requestAuthToken(): Promise<any> { async apiRequest(message: UploadInstruction): Promise<void> {
let response = await fetch( let response = await fetch(
new URL(`/api/v1/oauth-clients/local`, this.domain_name) new URL(`/api/v1/oauth-clients/local`, this.domain_name)
); );
@ -55,18 +74,15 @@ class PeerTubeRequester {
if (!response.ok) { if (!response.ok) {
throw new Error(response.statusText); // CRASH throw new Error(response.statusText); // CRASH
} }
const { access_token: accessToken } = await response.json(); const { access_token } = await response.json();
return accessToken;
}
async uploadFromUrl(message: UploadInstruction): Promise<void> { // Upload
const accessToken = await this.requestAuthToken();
const myUploadForm = new URLSearchParams(); const myUploadForm = new URLSearchParams();
const myHeader = new Headers(); const myHeader = new Headers();
myHeader.append("Authorization", `Bearer ${accessToken}`); myHeader.append("Authorization", `Bearer ${access_token}`);
for (const key in message) myUploadForm.append(key, message[key]); for (const key in message) myUploadForm.append(key, message[key]);
const response = await fetch( response = await fetch(
new URL(`/api/v1/videos/imports`, this.domain_name), new URL(`/api/v1/videos/imports`, this.domain_name),
{ {
method: "post", method: "post",
@ -79,9 +95,9 @@ class PeerTubeRequester {
switch (response.status) { switch (response.status) {
case 400: case 400:
throw new Error( throw new Error(
`Bad or malformed request. Probably because your target URL (from Youtube?) was not accepted by the API.\ `Your target URL was not accepted by the API.\
The target URL you attempted to pass: ${message.targetUrl}. Actualy it's : ${message.targetUrl}
Response from the server: ${response.statusText}` ${response.statusText}`
); );
break; break;
case 403: case 403:
@ -89,15 +105,15 @@ class PeerTubeRequester {
break; break;
case 409: case 409:
throw new Error( throw new Error(
`Oops, your instance did not allowed the HTTPS import.\ `Oops, your instance had not allowed the HTTPS import.\
Contact your administrator. Contact your administrator.
${response.statusText}` ${response.statusText}`
); );
break; break;
default: default:
throw new Error( throw new Error(
`Oh, you encountered an undocumented issues.\ `Oh, you resolved an undocumented issues.\
Please create an issue to the plugin project. Please report this on the git if you have the time.
ERROR: ${response.statusText}` ERROR: ${response.statusText}`
); );
break; break;

34
package-lock.json generated
View File

@ -1,15 +1,15 @@
{ {
"name": "peertube-plugin-auto-import-ytb", "name": "peertube-plugin-auto-import-ytb",
"version": "0.0.1", "version": "0.0.2",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"version": "0.0.1", "version": "0.0.2",
"dependencies": { "dependencies": {
"@types/node-fetch": "^2.5.11", "@types/node-fetch": "^2.5.11",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"listener-rss-aggregator": "^0.0.5", "listener-rss-agregator": "git+https://zeteo.me/gitea/Outils-PeerTube/listener-rss-agregators#1b36afbb34",
"node-fetch": "^2.6.1" "node-fetch": "^2.6.1"
}, },
"devDependencies": { "devDependencies": {
@ -398,10 +398,11 @@
"rss-parser": "^3.11.0" "rss-parser": "^3.11.0"
} }
}, },
"node_modules/listener-rss-aggregator": { "node_modules/listener-rss-agregator": {
"version": "0.0.5", "version": "0.0.3",
"resolved": "https://registry.npmjs.org/listener-rss-aggregator/-/listener-rss-aggregator-0.0.5.tgz", "resolved": "git+https://zeteo.me/gitea/Outils-PeerTube/listener-rss-agregators#1b36afbb344112c3827b5bcea92e1cc60bd8cf6a",
"integrity": "sha512-0QE7kkzurjsWr4gNAJ4X+C7UFSyaVuYq2mKYXZ3shvyj81kULpBgFZSg/70MZkUoqixgWQ5P8oxyztRDOP78tw==", "hasInstallScript": true,
"license": "MIT",
"dependencies": { "dependencies": {
"@databases/sqlite": "^3.0.0", "@databases/sqlite": "^3.0.0",
"listener-rss": "^0.0.3" "listener-rss": "^0.0.3"
@ -798,9 +799,9 @@
} }
}, },
"node_modules/tar": { "node_modules/tar": {
"version": "4.4.14", "version": "4.4.13",
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.14.tgz", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
"integrity": "sha512-ouN3XcSWYOAHmXZ+P4NEFJvqXL50To9OZBSQNNP30vBUFJFZZ0PLX15fnwupv6azfxMUfUDUr2fhYw4zGAEPcg==", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
"dependencies": { "dependencies": {
"chownr": "^1.1.1", "chownr": "^1.1.1",
"fs-minipass": "^1.2.5", "fs-minipass": "^1.2.5",
@ -1269,10 +1270,9 @@
"rss-parser": "^3.11.0" "rss-parser": "^3.11.0"
} }
}, },
"listener-rss-aggregator": { "listener-rss-agregator": {
"version": "0.0.5", "version": "git+https://zeteo.me/gitea/Outils-PeerTube/listener-rss-agregators#1b36afbb344112c3827b5bcea92e1cc60bd8cf6a",
"resolved": "https://registry.npmjs.org/listener-rss-aggregator/-/listener-rss-aggregator-0.0.5.tgz", "from": "listener-rss-agregator@git+https://zeteo.me/gitea/Outils-PeerTube/listener-rss-agregators#1b36afbb34",
"integrity": "sha512-0QE7kkzurjsWr4gNAJ4X+C7UFSyaVuYq2mKYXZ3shvyj81kULpBgFZSg/70MZkUoqixgWQ5P8oxyztRDOP78tw==",
"requires": { "requires": {
"@databases/sqlite": "^3.0.0", "@databases/sqlite": "^3.0.0",
"listener-rss": "^0.0.3" "listener-rss": "^0.0.3"
@ -1604,9 +1604,9 @@
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
}, },
"tar": { "tar": {
"version": "4.4.14", "version": "4.4.13",
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.14.tgz", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
"integrity": "sha512-ouN3XcSWYOAHmXZ+P4NEFJvqXL50To9OZBSQNNP30vBUFJFZZ0PLX15fnwupv6azfxMUfUDUr2fhYw4zGAEPcg==", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
"requires": { "requires": {
"chownr": "^1.1.1", "chownr": "^1.1.1",
"fs-minipass": "^1.2.5", "fs-minipass": "^1.2.5",

View File

@ -1,7 +1,7 @@
{ {
"name": "peertube-plugin-auto-import-ytb", "name": "peertube-plugin-auto-import-ytb",
"description": "PeerTube plugin quickstart", "description": "PeerTube plugin quickstart",
"version": "0.0.1", "version": "0.0.2",
"author": "AmauryJOLY", "author": "AmauryJOLY",
"bugs": "https://framagit.org/framasoft/peertube/peertube-plugin-quickstart/issues", "bugs": "https://framagit.org/framasoft/peertube/peertube-plugin-quickstart/issues",
"clientScripts": [], "clientScripts": [],
@ -24,6 +24,7 @@
"README.md" "README.md"
], ],
"scripts": { "scripts": {
"prepack": "npm i && npm run build",
"predeploy": "npm run build", "predeploy": "npm run build",
"deploy": "bash ./scripts/deploy.sh", "deploy": "bash ./scripts/deploy.sh",
"build": "tsc" "build": "tsc"
@ -33,7 +34,7 @@
"dependencies": { "dependencies": {
"@types/node-fetch": "^2.5.11", "@types/node-fetch": "^2.5.11",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"listener-rss-aggregator": "^0.0.5", "listener-rss-agregator": "git+https://zeteo.me/gitea/Outils-PeerTube/listener-rss-agregators#1b36afbb34",
"node-fetch": "^2.6.1" "node-fetch": "^2.6.1"
} }
} }

View File

@ -1,111 +1,113 @@
import { ListenerRssAggregator } from "listener-rss-aggregator"; import { ListenerRssAggregator } from "listener-rss-agregator";
import { ListenerRss } from "listener-rss"; import { ListenerRss } from "listener-rss";
import { PeerTubeRequester } from "../lib/peertubeRequester"; import { PeerTubeRequester } from "../lib/peertubeRequester";
type ListenerData = ListenerRss.Config & { type ListenerData = ListenerRss.Config & {
address: string; address: string;
channelId: string; channelId: string;
}; };
let myManager: ListenerRssAggregator; let myManager: ListenerRssAggregator;
let listenersDataBinding = new Map<string, ListenerData>(); let listenersDataBinding = new Map<string, ListenerData>();
let logger: any; let logger: any;
let peertube: PeerTubeRequester; let peertube: PeerTubeRequester;
import * as path from "path"; import * as path from "path";
import fs from "fs"; import fs from "fs";
async function register({ async function register({
registerSetting, registerSetting,
settingsManager, settingsManager,
peertubeHelpers, peertubeHelpers,
}: any) { }: any) {
const basePath = peertubeHelpers.plugin.getDataDirectoryPath(); const basePath = peertubeHelpers.plugin.getDataDirectoryPath();
logger = peertubeHelpers.logger; logger = peertubeHelpers.logger;
registerSetting({ registerSetting({
name: "ytb-urls", name: "ytb-urls",
label: "URL list of Youtube channel to synchronize", label: "liste des urls youtube a auto-importer",
type: "input-textarea", type: "input-textarea",
}); });
logger.debug("setting register"); logger.warn("setting register");
fs.appendFileSync(path.join(basePath, "/storage.bd"), ""); fs.appendFileSync(path.join(basePath, "/storage.bd"), "");
const configAggregator = await ListenerRssAggregator.instantiateAggregator( const configAggregator = await ListenerRssAggregator.instantiateAggregator(
path.join(basePath, "/storage.bd") path.join(basePath, "/storage.bd")
); );
myManager = new ListenerRssAggregator(configAggregator); myManager = new ListenerRssAggregator(configAggregator);
peertube = new PeerTubeRequester({ peertube = new PeerTubeRequester({
domain_name: "http://localhost:9000", domain_name: "http://localhost:9000",
username: "root", username: "root",
password: "test", password: "test",
}); });
logger.debug("Aggregator created"); logger.warn("Aggregator created");
const inputs = await settingsManager.getSetting("ytb-urls"); const inputs = await settingsManager.getSetting("ytb-urls");
if (inputs) await addListeners(inputs); if (inputs) await addListeners(inputs);
logger.debug("Config loaded"); logger.warn("Config loaded");
settingsManager.onSettingsChange(async (settings: any) => { settingsManager.onSettingsChange(async (settings: any) => {
await addListeners(settings["ytb-urls"]); await addListeners(settings["ytb-urls"]);
}); });
myManager.on("newEntries", async (entries: any) => { myManager.on("newEntries", (entries: any) => {
const datas = listenersDataBinding.get(entries.addressListener); const datas = listenersDataBinding.get(entries.addressListener);
if (!datas) return; if (!datas) return;
logger.debug( logger.warn(
"New entries detected from channel #%i: %s", "Nouvelles entrées détéctées: " +
datas.channelId, JSON.stringify(entries) +
JSON.stringify(entries) " de " +
); datas.channelId
for (const item of entries.items) );
await peertube.uploadFromUrl({ for (const item of entries.items)
channelId: datas.channelId, peertube.apiRequest({
targetUrl: item.link, channelId: datas.channelId,
}); targetUrl: item.link,
}); });
} });
}
async function addListeners(listenerInput: string) {
let listeners: ListenerData[]; async function addListeners(listenerInput: string) {
try { let listeners: ListenerData[];
listeners = JSON.parse(listenerInput); try {
} catch { listeners = JSON.parse(listenerInput);
logger.error("Malformed URL"); } catch {
return; logger.warn("Erreur: malformé");
} return;
let newListeners = listeners.filter( }
(item) => !listenersDataBinding.has(item.address) let newListeners = listeners.filter(
); (item) => !listenersDataBinding.has(item.address)
let removedUrls = Array.from(listenersDataBinding.keys()).filter( );
(url) => !listeners.some((listener) => listener.address === url) let removedUrls = Array.from(listenersDataBinding.keys()).filter(
); (url) => !listeners.some((listener) => listener.address === url)
);
for (const newItem of newListeners) {
listenersDataBinding.set(newItem.address, newItem); for (const newItem of newListeners) {
} listenersDataBinding.set(newItem.address, newItem);
for (const removedUrl of removedUrls) { }
listenersDataBinding.delete(removedUrl); for (const removedUrl of removedUrls) {
} listenersDataBinding.delete(removedUrl);
}
myManager.stopAll();
await myManager.saveOverride(listeners); myManager.stopAll();
await myManager.saveOverride(listeners);
if (logger) logger.warn("Configuration changed: " + listenerInput);
if (logger) logger.warn("Configuration modifiée: " + listenerInput);
myManager.startAll();
} myManager.startAll();
}
async function unregister() {
myManager.stopAll(); async function unregister() {
} myManager.stopAll();
return;
module.exports = { }
register,
unregister, module.exports = {
}; register,
unregister,
};