Compare commits
	
		
			15 Commits
		
	
	
		
			archive/te
			...
			florent-pa
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 8d06f144ca | |||
| 6dadf326ac | |||
| 809803a194 | |||
| 2c6df73d02 | |||
| 
						 | 
					6407c1b072 | ||
| 
						 | 
					b9d99891db | ||
| 
						 | 
					48b73a89bc | ||
| 
						 | 
					82f4a3e6ec | ||
| df0e311dbc | |||
| 
						 | 
					ae195d9170 | ||
| 
						 | 
					f579afab16 | ||
| 
						 | 
					41098d09a7 | ||
| b2b04df23b | |||
| 51126e7f0f | |||
| 8f8f0c3cb0 | 
							
								
								
									
										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,13 +1,10 @@
 | 
				
			|||||||
// import { ImplementableApi } from './implementableApi';
 | 
					 | 
				
			||||||
// Api request lib
 | 
					// Api request lib
 | 
				
			||||||
import fetch, { FetchError, Headers } from "node-fetch";
 | 
					import fetch, { 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 = {
 | 
				
			||||||
    domain_name: string | URL;
 | 
					    domainName: string | URL;
 | 
				
			||||||
    username: string;
 | 
					    username: string;
 | 
				
			||||||
    password: string;
 | 
					    password: string;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
@@ -19,45 +16,30 @@ 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 domainName: URL;
 | 
				
			||||||
  readonly username: string;
 | 
					  readonly username: string;
 | 
				
			||||||
  readonly password: string;
 | 
					  readonly password: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(readonly config: PeerTubeRequester.Config) {
 | 
					  constructor(readonly config: PeerTubeRequester.Config) {
 | 
				
			||||||
    this.domain_name = new URL("/", config.domain_name);
 | 
					    this.domainName = new URL("/", config.domainName);
 | 
				
			||||||
    this.username = config.username;
 | 
					    this.username = config.username;
 | 
				
			||||||
    this.password = config.password;
 | 
					    this.password = config.password;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async apiRequest(message: UploadInstruction): Promise<void> {
 | 
					  async requestAuthToken(): Promise<any> {
 | 
				
			||||||
    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.domainName)
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    if (!response.ok) {
 | 
					    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 } = {
 | 
					    const clientInfo: { [key: string]: string } = {
 | 
				
			||||||
      client_id,
 | 
					      client_id: clientId,
 | 
				
			||||||
      client_secret,
 | 
					      client_secret: clientSecret,
 | 
				
			||||||
      grant_type: "password",
 | 
					      grant_type: "password",
 | 
				
			||||||
      response_type: "code",
 | 
					      response_type: "code",
 | 
				
			||||||
      username: this.username,
 | 
					      username: this.username,
 | 
				
			||||||
@@ -65,25 +47,28 @@ class PeerTubeRequester {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let myParams = new URLSearchParams();
 | 
					    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",
 | 
					      method: "post",
 | 
				
			||||||
      body: myParams,
 | 
					      body: myParams,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    if (!response.ok) {
 | 
					    if (!response.ok) {
 | 
				
			||||||
      throw new Error(response.statusText); // CRASH
 | 
					      throw new Error("Cannot get access Token : " + response.statusText); // CRASH
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const { access_token } = await response.json();
 | 
					    const { access_token: accessToken } = await response.json();
 | 
				
			||||||
 | 
					    return accessToken;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Upload
 | 
					  async uploadFromUrl(message: UploadInstruction): Promise<void> {
 | 
				
			||||||
 | 
					    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 ${access_token}`);
 | 
					    myHeader.append("Authorization", `Bearer ${accessToken}`);
 | 
				
			||||||
    for (const key in message) myUploadForm.append(key, message[key]);
 | 
					    for (const key in message) myUploadForm.append(key, message[key]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    response = await fetch(
 | 
					    const response = await fetch(
 | 
				
			||||||
      new URL(`/api/v1/videos/imports`, this.domain_name),
 | 
					      new URL("/api/v1/videos/imports", this.domainName),
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        method: "post",
 | 
					        method: "post",
 | 
				
			||||||
        headers: myHeader,
 | 
					        headers: myHeader,
 | 
				
			||||||
@@ -95,9 +80,9 @@ class PeerTubeRequester {
 | 
				
			|||||||
      switch (response.status) {
 | 
					      switch (response.status) {
 | 
				
			||||||
        case 400:
 | 
					        case 400:
 | 
				
			||||||
          throw new Error(
 | 
					          throw new Error(
 | 
				
			||||||
            `Your target URL was not accepted by the API.\
 | 
					            `Bad or malformed request. Probably because your target URL (from Youtube?) was not accepted by the API.\
 | 
				
			||||||
                        Actualy it's : ${message.targetUrl}
 | 
					                        The target URL you attempted to pass: ${message.targetUrl}.
 | 
				
			||||||
                        ${response.statusText}`
 | 
					                        Response from the server: ${response.statusText}`
 | 
				
			||||||
          );
 | 
					          );
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case 403:
 | 
					        case 403:
 | 
				
			||||||
@@ -105,15 +90,15 @@ class PeerTubeRequester {
 | 
				
			|||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case 409:
 | 
					        case 409:
 | 
				
			||||||
          throw new Error(
 | 
					          throw new Error(
 | 
				
			||||||
            `Oops, your instance had not allowed the HTTPS import.\
 | 
					            `Oops, your instance did 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 resolved an undocumented issues.\
 | 
					            `Oh, you encountered an undocumented issues.\
 | 
				
			||||||
                        Please report this on the git if you have the time.
 | 
					                        Please create an issue to the plugin project.
 | 
				
			||||||
                        ERROR: ${response.statusText}`
 | 
					                        ERROR: ${response.statusText}`
 | 
				
			||||||
          );
 | 
					          );
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										35
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										35
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -1,15 +1,16 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "peertube-plugin-auto-import-ytb",
 | 
					  "name": "peertube-plugin-auto-import-ytb",
 | 
				
			||||||
  "version": "0.0.2",
 | 
					  "version": "0.0.1",
 | 
				
			||||||
  "lockfileVersion": 2,
 | 
					  "lockfileVersion": 2,
 | 
				
			||||||
  "requires": true,
 | 
					  "requires": true,
 | 
				
			||||||
  "packages": {
 | 
					  "packages": {
 | 
				
			||||||
    "": {
 | 
					    "": {
 | 
				
			||||||
      "version": "0.0.2",
 | 
					      "version": "0.0.1",
 | 
				
			||||||
      "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-agregator": "git+https://zeteo.me/gitea/Outils-PeerTube/listener-rss-agregators#1b36afbb34",
 | 
					        "listener-rss": "^0.0.3",
 | 
				
			||||||
 | 
					        "listener-rss-aggregator": "^0.0.5",
 | 
				
			||||||
        "node-fetch": "^2.6.1"
 | 
					        "node-fetch": "^2.6.1"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      "devDependencies": {
 | 
					      "devDependencies": {
 | 
				
			||||||
@@ -398,11 +399,10 @@
 | 
				
			|||||||
        "rss-parser": "^3.11.0"
 | 
					        "rss-parser": "^3.11.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/listener-rss-agregator": {
 | 
					    "node_modules/listener-rss-aggregator": {
 | 
				
			||||||
      "version": "0.0.3",
 | 
					      "version": "0.0.5",
 | 
				
			||||||
      "resolved": "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",
 | 
				
			||||||
      "hasInstallScript": true,
 | 
					      "integrity": "sha512-0QE7kkzurjsWr4gNAJ4X+C7UFSyaVuYq2mKYXZ3shvyj81kULpBgFZSg/70MZkUoqixgWQ5P8oxyztRDOP78tw==",
 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@databases/sqlite": "^3.0.0",
 | 
					        "@databases/sqlite": "^3.0.0",
 | 
				
			||||||
        "listener-rss": "^0.0.3"
 | 
					        "listener-rss": "^0.0.3"
 | 
				
			||||||
@@ -799,9 +799,9 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/tar": {
 | 
					    "node_modules/tar": {
 | 
				
			||||||
      "version": "4.4.13",
 | 
					      "version": "4.4.14",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.14.tgz",
 | 
				
			||||||
      "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
 | 
					      "integrity": "sha512-ouN3XcSWYOAHmXZ+P4NEFJvqXL50To9OZBSQNNP30vBUFJFZZ0PLX15fnwupv6azfxMUfUDUr2fhYw4zGAEPcg==",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "chownr": "^1.1.1",
 | 
					        "chownr": "^1.1.1",
 | 
				
			||||||
        "fs-minipass": "^1.2.5",
 | 
					        "fs-minipass": "^1.2.5",
 | 
				
			||||||
@@ -1270,9 +1270,10 @@
 | 
				
			|||||||
        "rss-parser": "^3.11.0"
 | 
					        "rss-parser": "^3.11.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "listener-rss-agregator": {
 | 
					    "listener-rss-aggregator": {
 | 
				
			||||||
      "version": "git+https://zeteo.me/gitea/Outils-PeerTube/listener-rss-agregators#1b36afbb344112c3827b5bcea92e1cc60bd8cf6a",
 | 
					      "version": "0.0.5",
 | 
				
			||||||
      "from": "listener-rss-agregator@git+https://zeteo.me/gitea/Outils-PeerTube/listener-rss-agregators#1b36afbb34",
 | 
					      "resolved": "https://registry.npmjs.org/listener-rss-aggregator/-/listener-rss-aggregator-0.0.5.tgz",
 | 
				
			||||||
 | 
					      "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 +1605,9 @@
 | 
				
			|||||||
      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
 | 
					      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "tar": {
 | 
					    "tar": {
 | 
				
			||||||
      "version": "4.4.13",
 | 
					      "version": "4.4.14",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.14.tgz",
 | 
				
			||||||
      "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
 | 
					      "integrity": "sha512-ouN3XcSWYOAHmXZ+P4NEFJvqXL50To9OZBSQNNP30vBUFJFZZ0PLX15fnwupv6azfxMUfUDUr2fhYw4zGAEPcg==",
 | 
				
			||||||
      "requires": {
 | 
					      "requires": {
 | 
				
			||||||
        "chownr": "^1.1.1",
 | 
					        "chownr": "^1.1.1",
 | 
				
			||||||
        "fs-minipass": "^1.2.5",
 | 
					        "fs-minipass": "^1.2.5",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,9 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "peertube-plugin-auto-import-ytb",
 | 
					  "name": "peertube-plugin-auto-import-ytb",
 | 
				
			||||||
  "description": "PeerTube plugin quickstart",
 | 
					  "description": "Peertube plugin to auto import videos from a youtube channel to a local peertube channel",
 | 
				
			||||||
  "version": "0.0.2",
 | 
					  "version": "0.0.2",
 | 
				
			||||||
  "author": "AmauryJOLY",
 | 
					  "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": [],
 | 
					  "clientScripts": [],
 | 
				
			||||||
  "css": [],
 | 
					  "css": [],
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
@@ -13,7 +13,7 @@
 | 
				
			|||||||
  "engine": {
 | 
					  "engine": {
 | 
				
			||||||
    "peertube": ">=3.2.0"
 | 
					    "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": [
 | 
					  "keywords": [
 | 
				
			||||||
    "peertube",
 | 
					    "peertube",
 | 
				
			||||||
    "plugin"
 | 
					    "plugin"
 | 
				
			||||||
@@ -33,7 +33,8 @@
 | 
				
			|||||||
  "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-agregator": "git+https://zeteo.me/gitea/Outils-PeerTube/listener-rss-agregators#1b36afbb34",
 | 
					    "listener-rss-aggregator": "^0.0.5",
 | 
				
			||||||
 | 
					    "listener-rss": "^0.0.3",
 | 
				
			||||||
    "node-fetch": "^2.6.1"
 | 
					    "node-fetch": "^2.6.1"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										271
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										271
									
								
								src/main.ts
									
									
									
									
									
								
							@@ -1,113 +1,158 @@
 | 
				
			|||||||
import { ListenerRssAggregator } from "listener-rss-agregator";
 | 
					import { ListenerRssAggregator } from "listener-rss-aggregator";
 | 
				
			||||||
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 | undefined = undefined;
 | 
				
			||||||
 | 
					let goodPeertubeCredential: boolean = false;
 | 
				
			||||||
import * as path from "path";
 | 
					
 | 
				
			||||||
import fs from "fs";
 | 
					import * as path from "path";
 | 
				
			||||||
 | 
					import fs from "fs";
 | 
				
			||||||
async function register({
 | 
					
 | 
				
			||||||
  registerSetting,
 | 
					async function register({
 | 
				
			||||||
  settingsManager,
 | 
					  registerSetting,
 | 
				
			||||||
  peertubeHelpers,
 | 
					  settingsManager,
 | 
				
			||||||
}: any) {
 | 
					  peertubeHelpers,
 | 
				
			||||||
  const basePath = peertubeHelpers.plugin.getDataDirectoryPath();
 | 
					}: any) {
 | 
				
			||||||
  logger = peertubeHelpers.logger;
 | 
					  const basePath = peertubeHelpers.plugin.getDataDirectoryPath();
 | 
				
			||||||
 | 
					  logger = peertubeHelpers.logger;
 | 
				
			||||||
  registerSetting({
 | 
					
 | 
				
			||||||
    name: "ytb-urls",
 | 
					  registerSetting({
 | 
				
			||||||
    label: "liste des urls youtube a auto-importer",
 | 
					    name: "ytb-urls",
 | 
				
			||||||
    type: "input-textarea",
 | 
					    label: "URL list of Youtube channel to synchronize",
 | 
				
			||||||
  });
 | 
					    type: "input-textarea",
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
  logger.warn("setting register");
 | 
					
 | 
				
			||||||
  fs.appendFileSync(path.join(basePath, "/storage.bd"), "");
 | 
					  registerSetting({
 | 
				
			||||||
 | 
					    name: "admin-name",
 | 
				
			||||||
  const configAggregator = await ListenerRssAggregator.instantiateAggregator(
 | 
					    label: "Admin Username",
 | 
				
			||||||
    path.join(basePath, "/storage.bd")
 | 
					    type: "input",
 | 
				
			||||||
  );
 | 
					  });
 | 
				
			||||||
  myManager = new ListenerRssAggregator(configAggregator);
 | 
					
 | 
				
			||||||
 | 
					  registerSetting({
 | 
				
			||||||
  peertube = new PeerTubeRequester({
 | 
					    name: "admin-password",
 | 
				
			||||||
    domain_name: "http://localhost:9000",
 | 
					    label: "Admin Password",
 | 
				
			||||||
    username: "root",
 | 
					    type: "input-password",
 | 
				
			||||||
    password: "test",
 | 
					  });
 | 
				
			||||||
  });
 | 
					
 | 
				
			||||||
 | 
					  logger.debug("setting register");
 | 
				
			||||||
  logger.warn("Aggregator created");
 | 
					  fs.appendFileSync(path.join(basePath, "/storage.bd"), "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const inputs = await settingsManager.getSetting("ytb-urls");
 | 
					  const configAggregator = await ListenerRssAggregator.instantiateAggregator(
 | 
				
			||||||
  if (inputs) await addListeners(inputs);
 | 
					    path.join(basePath, "/storage.bd")
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
  logger.warn("Config loaded");
 | 
					  myManager = new ListenerRssAggregator(configAggregator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  settingsManager.onSettingsChange(async (settings: any) => {
 | 
					  logger.debug("Aggregator created");
 | 
				
			||||||
    await addListeners(settings["ytb-urls"]);
 | 
					
 | 
				
			||||||
  });
 | 
					  const settingYtbUrls = await settingsManager.getSetting("ytb-urls");
 | 
				
			||||||
 | 
					  if (settingYtbUrls) await addListeners(settingYtbUrls);
 | 
				
			||||||
  myManager.on("newEntries", (entries: any) => {
 | 
					
 | 
				
			||||||
    const datas = listenersDataBinding.get(entries.addressListener);
 | 
					  const settingCredentials: any = await settingsManager.getSettings([
 | 
				
			||||||
    if (!datas) return;
 | 
					    "admin-name",
 | 
				
			||||||
 | 
					    "admin-password",
 | 
				
			||||||
    logger.warn(
 | 
					  ]);
 | 
				
			||||||
      "Nouvelles entrées détéctées: " +
 | 
					
 | 
				
			||||||
        JSON.stringify(entries) +
 | 
					  if (settingCredentials["admin-name"] && settingCredentials["admin-password"])
 | 
				
			||||||
        " de " +
 | 
					    apiRequestInitializer({
 | 
				
			||||||
        datas.channelId
 | 
					      domainName: peertubeHelpers.config.getWebserverUrl(),
 | 
				
			||||||
    );
 | 
					      username: settingCredentials["admin-name"],
 | 
				
			||||||
    for (const item of entries.items)
 | 
					      password: settingCredentials["admin-password"],
 | 
				
			||||||
      peertube.apiRequest({
 | 
					    });
 | 
				
			||||||
        channelId: datas.channelId,
 | 
					  logger.debug("Actual config loaded");
 | 
				
			||||||
        targetUrl: item.link,
 | 
					
 | 
				
			||||||
      });
 | 
					  settingsManager.onSettingsChange(async (settings: any) => {
 | 
				
			||||||
  });
 | 
					    if (
 | 
				
			||||||
}
 | 
					      !peertube ||
 | 
				
			||||||
 | 
					      peertube.username != settings["admin-name"] ||
 | 
				
			||||||
async function addListeners(listenerInput: string) {
 | 
					      peertube.password != settings["admin-password"]
 | 
				
			||||||
  let listeners: ListenerData[];
 | 
					    )
 | 
				
			||||||
  try {
 | 
					      apiRequestInitializer({
 | 
				
			||||||
    listeners = JSON.parse(listenerInput);
 | 
					        domainName: peertubeHelpers.config.getWebserverUrl(),
 | 
				
			||||||
  } catch {
 | 
					        username: settings["admin-name"],
 | 
				
			||||||
    logger.warn("Erreur: malformé");
 | 
					        password: settings["admin-password"],
 | 
				
			||||||
    return;
 | 
					      });
 | 
				
			||||||
  }
 | 
					
 | 
				
			||||||
  let newListeners = listeners.filter(
 | 
					    await addListeners(settings["ytb-urls"]);
 | 
				
			||||||
    (item) => !listenersDataBinding.has(item.address)
 | 
					  });
 | 
				
			||||||
  );
 | 
					
 | 
				
			||||||
  let removedUrls = Array.from(listenersDataBinding.keys()).filter(
 | 
					  myManager.on("newEntries", async (entries: any) => {
 | 
				
			||||||
    (url) => !listeners.some((listener) => listener.address === url)
 | 
					    const datas = listenersDataBinding.get(entries.addressListener);
 | 
				
			||||||
  );
 | 
					    if (!datas) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (const newItem of newListeners) {
 | 
					    logger.debug(
 | 
				
			||||||
    listenersDataBinding.set(newItem.address, newItem);
 | 
					      "New entries detected from channel #%i: %s",
 | 
				
			||||||
  }
 | 
					      datas.channelId,
 | 
				
			||||||
  for (const removedUrl of removedUrls) {
 | 
					      JSON.stringify(entries)
 | 
				
			||||||
    listenersDataBinding.delete(removedUrl);
 | 
					    );
 | 
				
			||||||
  }
 | 
					    for (const item of entries.items)
 | 
				
			||||||
 | 
					      if (peertube)
 | 
				
			||||||
  myManager.stopAll();
 | 
					        await peertube.uploadFromUrl({
 | 
				
			||||||
  await myManager.saveOverride(listeners);
 | 
					          channelId: datas.channelId,
 | 
				
			||||||
 | 
					          targetUrl: item.link,
 | 
				
			||||||
  if (logger) logger.warn("Configuration modifiée: " + listenerInput);
 | 
					        });
 | 
				
			||||||
 | 
					      else {
 | 
				
			||||||
  myManager.startAll();
 | 
					        logger.warn("Bad credential provides. New entries Skipped.");
 | 
				
			||||||
}
 | 
					      }
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
async function unregister() {
 | 
					}
 | 
				
			||||||
  myManager.stopAll();
 | 
					
 | 
				
			||||||
  return;
 | 
					async function apiRequestInitializer(data: PeerTubeRequester.Config) {
 | 
				
			||||||
}
 | 
					  peertube = new PeerTubeRequester(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = {
 | 
					  try {
 | 
				
			||||||
  register,
 | 
					    await peertube.requestAuthToken();
 | 
				
			||||||
  unregister,
 | 
					    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 {
 | 
				
			||||||
 | 
					    listeners = JSON.parse(listenerInput);
 | 
				
			||||||
 | 
					  } catch {
 | 
				
			||||||
 | 
					    logger.error("Malformed URL");
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  let newListeners = listeners.filter(
 | 
				
			||||||
 | 
					    (item) => !listenersDataBinding.has(item.address)
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					  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 removedUrl of removedUrls) {
 | 
				
			||||||
 | 
					    listenersDataBinding.delete(removedUrl);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  myManager.stopAll();
 | 
				
			||||||
 | 
					  await myManager.saveOverride(listeners);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (logger) logger.debug("Configuration changed: " + listenerInput);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (goodPeertubeCredential) myManager.startAll();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function unregister() {
 | 
				
			||||||
 | 
					  myManager.stopAll();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = {
 | 
				
			||||||
 | 
					  register,
 | 
				
			||||||
 | 
					  unregister,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user