Compare commits
	
		
			8 Commits
		
	
	
		
			archive/va
			...
			develop
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 6dadf326ac | |||
| 809803a194 | |||
| 2c6df73d02 | |||
| 
						 | 
					6407c1b072 | ||
| 
						 | 
					b9d99891db | ||
| 
						 | 
					48b73a89bc | ||
| 
						 | 
					82f4a3e6ec | ||
| df0e311dbc | 
							
								
								
									
										43
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								README.md
									
									
									
									
									
								
							@@ -1,3 +1,42 @@
 | 
			
		||||
# PeerTube plugin Quickstart
 | 
			
		||||
# Auto Import YouTube
 | 
			
		||||
 | 
			
		||||
See https://docs.joinpeertube.org/#/contribute-plugins?id=write-a-plugintheme
 | 
			
		||||
## Config
 | 
			
		||||
 | 
			
		||||
To use this plugin, you need to give some valid admins credential inside the plugin's settings.
 | 
			
		||||
 | 
			
		||||
After this you have to specify some YouTube Channel who need to be bind with a PeerTube Channel.
 | 
			
		||||
For this you have to use this format inside the plugins's setting. Into `URL list of Youtube channel to synchronize`'s text area. :
 | 
			
		||||
 | 
			
		||||
```json
 | 
			
		||||
[
 | 
			
		||||
   {
 | 
			
		||||
       "address":"https://www.youtube.com/feeds/videos.xml?channel_id=${MyYouTubeChannelID}",
 | 
			
		||||
       "ChannelId":"MyPeertubeChannelId"
 | 
			
		||||
   } ,
 | 
			
		||||
   ...
 | 
			
		||||
]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This an array of object who's in this format :
 | 
			
		||||
 | 
			
		||||
```ts
 | 
			
		||||
type SettingsContent = {
 | 
			
		||||
  address: string;
 | 
			
		||||
  channelId: string;
 | 
			
		||||
  timeloop?: number;
 | 
			
		||||
};
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### address
 | 
			
		||||
 | 
			
		||||
For exemple, to the Youtube channel : `https://www.youtube.com/channel/YouTube`, the channel id is `UCBR8-60-B28hp2BmDPdntcQ`. You can get it when you're clicking in the channel button on the video player. (He's not Highlighted by YouTube. Cheer Up !)  
 | 
			
		||||
So you need to specify the following address inside your configuration : `https://www.youtube.com/feeds/videos.xml?channel_id=UCBR8-60-B28hp2BmDPdntcQ`.
 | 
			
		||||
 | 
			
		||||
### channelId
 | 
			
		||||
 | 
			
		||||
The peertube's channel id is a number associated to a peertube's channel. He's unique per channel inside a same instance.
 | 
			
		||||
 | 
			
		||||
### timeloop
 | 
			
		||||
 | 
			
		||||
It's represent the time between two update of the videos list.  
 | 
			
		||||
It's not needful to specify the timeloop. The default value is set to 5 minutes.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
// Api request lib
 | 
			
		||||
import fetch, { FetchError, Headers } from "node-fetch";
 | 
			
		||||
import fetch, { Headers } from "node-fetch";
 | 
			
		||||
import { URL, URLSearchParams } from "url";
 | 
			
		||||
 | 
			
		||||
namespace PeerTubeRequester {
 | 
			
		||||
  export type Config = {
 | 
			
		||||
    domain_name: string | URL;
 | 
			
		||||
    domainName: string | URL;
 | 
			
		||||
    username: string;
 | 
			
		||||
    password: string;
 | 
			
		||||
  };
 | 
			
		||||
@@ -17,28 +17,29 @@ type UploadInstruction = {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class PeerTubeRequester {
 | 
			
		||||
  readonly domain_name: URL;
 | 
			
		||||
  readonly domainName: URL;
 | 
			
		||||
  readonly username: string;
 | 
			
		||||
  readonly password: string;
 | 
			
		||||
 | 
			
		||||
  constructor(readonly config: PeerTubeRequester.Config) {
 | 
			
		||||
    this.domain_name = new URL("/", config.domain_name);
 | 
			
		||||
    this.domainName = new URL("/", config.domainName);
 | 
			
		||||
    this.username = config.username;
 | 
			
		||||
    this.password = config.password;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async requestAuthToken(): Promise<any> {
 | 
			
		||||
  async requestAuthToken(): Promise<any> {
 | 
			
		||||
    let response = await fetch(
 | 
			
		||||
      new URL(`/api/v1/oauth-clients/local`, this.domain_name)
 | 
			
		||||
      new URL(`/api/v1/oauth-clients/local`, this.domainName)
 | 
			
		||||
    );
 | 
			
		||||
    if (!response.ok) {
 | 
			
		||||
      throw new Error(response.statusText); // CRASH
 | 
			
		||||
      throw new Error("Cannot get client credentials : " + response.statusText); // CRASH
 | 
			
		||||
    }
 | 
			
		||||
    const { client_id, client_secret } = await response.json();
 | 
			
		||||
    const { client_id: clientId, client_secret: clientSecret } =
 | 
			
		||||
      await response.json();
 | 
			
		||||
 | 
			
		||||
    const client_info: { [key: string]: string } = {
 | 
			
		||||
      client_id,
 | 
			
		||||
      client_secret,
 | 
			
		||||
    const clientInfo: { [key: string]: string } = {
 | 
			
		||||
      client_id: clientId,
 | 
			
		||||
      client_secret: clientSecret,
 | 
			
		||||
      grant_type: "password",
 | 
			
		||||
      response_type: "code",
 | 
			
		||||
      username: this.username,
 | 
			
		||||
@@ -46,14 +47,14 @@ class PeerTubeRequester {
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let myParams = new URLSearchParams();
 | 
			
		||||
    for (const key in client_info) myParams.append(key, client_info[key]);
 | 
			
		||||
    for (const key in clientInfo) myParams.append(key, clientInfo[key]);
 | 
			
		||||
 | 
			
		||||
    response = await fetch(new URL(`/api/v1/users/token`, this.domain_name), {
 | 
			
		||||
    response = await fetch(new URL(`/api/v1/users/token`, this.domainName), {
 | 
			
		||||
      method: "post",
 | 
			
		||||
      body: myParams,
 | 
			
		||||
    });
 | 
			
		||||
    if (!response.ok) {
 | 
			
		||||
      throw new Error(response.statusText); // CRASH
 | 
			
		||||
      throw new Error("Cannot get access Token : " + response.statusText); // CRASH
 | 
			
		||||
    }
 | 
			
		||||
    const { access_token: accessToken } = await response.json();
 | 
			
		||||
    return accessToken;
 | 
			
		||||
@@ -67,7 +68,7 @@ class PeerTubeRequester {
 | 
			
		||||
    for (const key in message) myUploadForm.append(key, message[key]);
 | 
			
		||||
 | 
			
		||||
    const response = await fetch(
 | 
			
		||||
      new URL(`/api/v1/videos/imports`, this.domain_name),
 | 
			
		||||
      new URL("/api/v1/videos/imports", this.domainName),
 | 
			
		||||
      {
 | 
			
		||||
        method: "post",
 | 
			
		||||
        headers: myHeader,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -9,6 +9,7 @@
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@types/node-fetch": "^2.5.11",
 | 
			
		||||
        "form-data": "^4.0.0",
 | 
			
		||||
        "listener-rss": "^0.0.3",
 | 
			
		||||
        "listener-rss-aggregator": "^0.0.5",
 | 
			
		||||
        "node-fetch": "^2.6.1"
 | 
			
		||||
      },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "peertube-plugin-auto-import-ytb",
 | 
			
		||||
  "description": "PeerTube plugin quickstart",
 | 
			
		||||
  "version": "0.0.1",
 | 
			
		||||
  "description": "Peertube plugin to auto import videos from a youtube channel to a local peertube channel",
 | 
			
		||||
  "version": "0.0.2",
 | 
			
		||||
  "author": "AmauryJOLY",
 | 
			
		||||
  "bugs": "https://framagit.org/framasoft/peertube/peertube-plugin-quickstart/issues",
 | 
			
		||||
  "bugs": "https://zeteo.me/gitea/Outils-PeerTube/peertube-plugin-auto-import-ytb/issues",
 | 
			
		||||
  "clientScripts": [],
 | 
			
		||||
  "css": [],
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
  "engine": {
 | 
			
		||||
    "peertube": ">=3.2.0"
 | 
			
		||||
  },
 | 
			
		||||
  "homepage": "https://framagit.org/framasoft/peertube/peertube-plugin-quickstart",
 | 
			
		||||
  "homepage": "https://zeteo.me/gitea/Outils-PeerTube/peertube-plugin-auto-import-ytb",
 | 
			
		||||
  "keywords": [
 | 
			
		||||
    "peertube",
 | 
			
		||||
    "plugin"
 | 
			
		||||
@@ -34,6 +34,7 @@
 | 
			
		||||
    "@types/node-fetch": "^2.5.11",
 | 
			
		||||
    "form-data": "^4.0.0",
 | 
			
		||||
    "listener-rss-aggregator": "^0.0.5",
 | 
			
		||||
    "listener-rss": "^0.0.3",
 | 
			
		||||
    "node-fetch": "^2.6.1"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										79
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								src/main.ts
									
									
									
									
									
								
							@@ -10,7 +10,8 @@ type ListenerData = ListenerRss.Config & {
 | 
			
		||||
let myManager: ListenerRssAggregator;
 | 
			
		||||
let listenersDataBinding = new Map<string, ListenerData>();
 | 
			
		||||
let logger: any;
 | 
			
		||||
let peertube: PeerTubeRequester;
 | 
			
		||||
let peertube: PeerTubeRequester | undefined = undefined;
 | 
			
		||||
let goodPeertubeCredential: boolean = false;
 | 
			
		||||
 | 
			
		||||
import * as path from "path";
 | 
			
		||||
import fs from "fs";
 | 
			
		||||
@@ -29,6 +30,18 @@ async function register({
 | 
			
		||||
    type: "input-textarea",
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  registerSetting({
 | 
			
		||||
    name: "admin-name",
 | 
			
		||||
    label: "Admin Username",
 | 
			
		||||
    type: "input",
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  registerSetting({
 | 
			
		||||
    name: "admin-password",
 | 
			
		||||
    label: "Admin Password",
 | 
			
		||||
    type: "input-password",
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  logger.debug("setting register");
 | 
			
		||||
  fs.appendFileSync(path.join(basePath, "/storage.bd"), "");
 | 
			
		||||
 | 
			
		||||
@@ -37,20 +50,36 @@ async function register({
 | 
			
		||||
  );
 | 
			
		||||
  myManager = new ListenerRssAggregator(configAggregator);
 | 
			
		||||
 | 
			
		||||
  peertube = new PeerTubeRequester({
 | 
			
		||||
    domain_name: "http://localhost:9000",
 | 
			
		||||
    username: "root",
 | 
			
		||||
    password: "test",
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  logger.debug("Aggregator created");
 | 
			
		||||
 | 
			
		||||
  const inputs = await settingsManager.getSetting("ytb-urls");
 | 
			
		||||
  if (inputs) await addListeners(inputs);
 | 
			
		||||
  const settingYtbUrls = await settingsManager.getSetting("ytb-urls");
 | 
			
		||||
  if (settingYtbUrls) await addListeners(settingYtbUrls);
 | 
			
		||||
 | 
			
		||||
  logger.debug("Config loaded");
 | 
			
		||||
  const settingCredentials: any = await settingsManager.getSettings([
 | 
			
		||||
    "admin-name",
 | 
			
		||||
    "admin-password",
 | 
			
		||||
  ]);
 | 
			
		||||
 | 
			
		||||
  if (settingCredentials["admin-name"] && settingCredentials["admin-password"])
 | 
			
		||||
    apiRequestInitializer({
 | 
			
		||||
      domainName: peertubeHelpers.config.getWebserverUrl(),
 | 
			
		||||
      username: settingCredentials["admin-name"],
 | 
			
		||||
      password: settingCredentials["admin-password"],
 | 
			
		||||
    });
 | 
			
		||||
  logger.debug("Actual config loaded");
 | 
			
		||||
 | 
			
		||||
  settingsManager.onSettingsChange(async (settings: any) => {
 | 
			
		||||
    if (
 | 
			
		||||
      !peertube ||
 | 
			
		||||
      peertube.username != settings["admin-name"] ||
 | 
			
		||||
      peertube.password != settings["admin-password"]
 | 
			
		||||
    )
 | 
			
		||||
      apiRequestInitializer({
 | 
			
		||||
        domainName: peertubeHelpers.config.getWebserverUrl(),
 | 
			
		||||
        username: settings["admin-name"],
 | 
			
		||||
        password: settings["admin-password"],
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    await addListeners(settings["ytb-urls"]);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -64,13 +93,31 @@ async function register({
 | 
			
		||||
      JSON.stringify(entries)
 | 
			
		||||
    );
 | 
			
		||||
    for (const item of entries.items)
 | 
			
		||||
      await peertube.uploadFromUrl({
 | 
			
		||||
        channelId: datas.channelId,
 | 
			
		||||
        targetUrl: item.link,
 | 
			
		||||
      });
 | 
			
		||||
      if (peertube)
 | 
			
		||||
        await peertube.uploadFromUrl({
 | 
			
		||||
          channelId: datas.channelId,
 | 
			
		||||
          targetUrl: item.link,
 | 
			
		||||
        });
 | 
			
		||||
      else {
 | 
			
		||||
        logger.warn("Bad credential provides. New entries Skipped.");
 | 
			
		||||
      }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function apiRequestInitializer(data: PeerTubeRequester.Config) {
 | 
			
		||||
  peertube = new PeerTubeRequester(data);
 | 
			
		||||
 | 
			
		||||
  try {
 | 
			
		||||
    await peertube.requestAuthToken();
 | 
			
		||||
    goodPeertubeCredential = true;
 | 
			
		||||
    logger.debug("credential ok");
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    logger.warn("Error during the credential validation : " + error);
 | 
			
		||||
    peertube = undefined;
 | 
			
		||||
    goodPeertubeCredential = false;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function addListeners(listenerInput: string) {
 | 
			
		||||
  let listeners: ListenerData[];
 | 
			
		||||
  try {
 | 
			
		||||
@@ -96,9 +143,9 @@ async function addListeners(listenerInput: string) {
 | 
			
		||||
  myManager.stopAll();
 | 
			
		||||
  await myManager.saveOverride(listeners);
 | 
			
		||||
 | 
			
		||||
  if (logger) logger.warn("Configuration changed: " + listenerInput);
 | 
			
		||||
  if (logger) logger.debug("Configuration changed: " + listenerInput);
 | 
			
		||||
 | 
			
		||||
  myManager.startAll();
 | 
			
		||||
  if (goodPeertubeCredential) myManager.startAll();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function unregister() {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user