Compare commits

..

No commits in common. "master" and "master" have entirely different histories.

9 changed files with 120 additions and 529 deletions

View File

@ -1 +0,0 @@
{}

1
.prettierts.json Normal file
View File

@ -0,0 +1 @@
{}

View File

@ -1,42 +1,3 @@
# Auto Import YouTube
# PeerTube plugin Quickstart
## 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.
See https://docs.joinpeertube.org/#/contribute-plugins?id=write-a-plugintheme

View File

@ -1,110 +0,0 @@
// Api request lib
import fetch, { Headers } from "node-fetch";
import { URL, URLSearchParams } from "url";
namespace PeerTubeRequester {
export type Config = {
domainName: string | URL;
username: string;
password: string;
};
}
type UploadInstruction = {
[key: string]: string;
channelId: string;
targetUrl: string;
};
class PeerTubeRequester {
readonly domainName: URL;
readonly username: string;
readonly password: string;
constructor(readonly config: PeerTubeRequester.Config) {
this.domainName = new URL("/", config.domainName);
this.username = config.username;
this.password = config.password;
}
async requestAuthToken(): Promise<any> {
let response = await fetch(
new URL(`/api/v1/oauth-clients/local`, this.domainName)
);
if (!response.ok) {
throw new Error("Cannot get client credentials : " + response.statusText); // CRASH
}
const { client_id: clientId, client_secret: clientSecret } =
await response.json();
const clientInfo: { [key: string]: string } = {
client_id: clientId,
client_secret: clientSecret,
grant_type: "password",
response_type: "code",
username: this.username,
password: this.password,
};
let myParams = new URLSearchParams();
for (const key in clientInfo) myParams.append(key, clientInfo[key]);
response = await fetch(new URL(`/api/v1/users/token`, this.domainName), {
method: "post",
body: myParams,
});
if (!response.ok) {
throw new Error("Cannot get access Token : " + response.statusText); // CRASH
}
const { access_token: accessToken } = await response.json();
return accessToken;
}
async uploadFromUrl(message: UploadInstruction): Promise<void> {
const accessToken = await this.requestAuthToken();
const myUploadForm = new URLSearchParams();
const myHeader = new Headers();
myHeader.append("Authorization", `Bearer ${accessToken}`);
for (const key in message) myUploadForm.append(key, message[key]);
const response = await fetch(
new URL("/api/v1/videos/imports", this.domainName),
{
method: "post",
headers: myHeader,
body: myUploadForm,
}
);
if (!response.ok) {
switch (response.status) {
case 400:
throw new Error(
`Bad or malformed request. Probably because your target URL (from Youtube?) was not accepted by the API.\
The target URL you attempted to pass: ${message.targetUrl}.
Response from the server: ${response.statusText}`
);
break;
case 403:
throw new Error(response.statusText);
break;
case 409:
throw new Error(
`Oops, your instance did not allowed the HTTPS import.\
Contact your administrator.
${response.statusText}`
);
break;
default:
throw new Error(
`Oh, you encountered an undocumented issues.\
Please create an issue to the plugin project.
ERROR: ${response.statusText}`
);
break;
}
}
}
}
export { PeerTubeRequester };

275
package-lock.json generated
View File

@ -1,17 +1,13 @@
{
"name": "peertube-plugin-auto-import-ytb",
"version": "0.0.1",
"version": "0.0.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"version": "0.0.1",
"version": "0.0.2",
"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"
"listener-rss-agregator": "0.0.2"
},
"devDependencies": {
"ts-node": "^10.0.0",
@ -73,31 +69,9 @@
"dev": true
},
"node_modules/@types/node": {
"version": "16.3.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz",
"integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA=="
},
"node_modules/@types/node-fetch": {
"version": "2.5.11",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.11.tgz",
"integrity": "sha512-2upCKaqVZETDRb8A2VTaRymqFBEgH8u6yr96b/u3+1uQEPDRo3mJLEiPk7vdXBHRtjwkjqzFYMJXrt0Z9QsYjQ==",
"dependencies": {
"@types/node": "*",
"form-data": "^3.0.0"
}
},
"node_modules/@types/node-fetch/node_modules/form-data": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
"integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
"version": "15.12.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.5.tgz",
"integrity": "sha512-se3yX7UHv5Bscf8f1ERKvQOD6sTyycH3hdaoozvaLxgUiY5lIGEeH37AD0G0Qi9kPqihPn0HOfd2yaIEN9VwEg=="
},
"node_modules/@types/sqlite3": {
"version": "3.1.7",
@ -145,11 +119,6 @@
"resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz",
"integrity": "sha1-sqRdpf36ILBJb8N2jMJ8EvqRan0="
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -183,17 +152,6 @@
"node": ">=0.10.0"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -231,14 +189,6 @@
"node": ">=4.0.0"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
@ -272,19 +222,6 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fs-minipass": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
@ -392,20 +329,20 @@
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"node_modules/listener-rss": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/listener-rss/-/listener-rss-0.0.3.tgz",
"integrity": "sha512-rccetOTwyyww/KDuaMX0EMjaGi+Jx+bojp18Ucxra6OeCfz2hC9FEasVNeENR096+ndOCS/rkKTJl+RD9rlAAQ==",
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/listener-rss/-/listener-rss-0.0.1.tgz",
"integrity": "sha512-ljH6FD4NMypkrZ9ZIMdW2YdAlm/Jer++zPI+1HTWK7BbhPJmUF3sSymqUqAjBcfH3xjt+fpYPqYgNYNM1fEYpA==",
"dependencies": {
"rss-parser": "^3.11.0"
"rss-parser": "3.11.0"
}
},
"node_modules/listener-rss-aggregator": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/listener-rss-aggregator/-/listener-rss-aggregator-0.0.5.tgz",
"integrity": "sha512-0QE7kkzurjsWr4gNAJ4X+C7UFSyaVuYq2mKYXZ3shvyj81kULpBgFZSg/70MZkUoqixgWQ5P8oxyztRDOP78tw==",
"node_modules/listener-rss-agregator": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/listener-rss-agregator/-/listener-rss-agregator-0.0.2.tgz",
"integrity": "sha512-ATj4esXtHLThe1/wkJ/ukA9+pC9FwBCNZCbVv7Ywr1eIbxBR+AHR5090lzCQt3WJsBblpTTZMni+vHxmGjRR7Q==",
"dependencies": {
"@databases/sqlite": "^3.0.0",
"listener-rss": "^0.0.3"
"listener-rss": "^0.0.1"
}
},
"node_modules/make-error": {
@ -414,25 +351,6 @@
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true
},
"node_modules/mime-db": {
"version": "1.48.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
"integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.31",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
"integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
"dependencies": {
"mime-db": "1.48.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@ -488,9 +406,9 @@
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ=="
},
"node_modules/needle": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/needle/-/needle-2.8.0.tgz",
"integrity": "sha512-ZTq6WYkN/3782H1393me3utVYdq2XyqNUFBsprEE3VMAT0+hP/cItpnITpqsY6ep2yeFE4Tqtqwc74VqUlUYtw==",
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz",
"integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==",
"dependencies": {
"debug": "^3.2.6",
"iconv-lite": "^0.4.4",
@ -503,14 +421,6 @@
"node": ">= 4.4.x"
}
},
"node_modules/node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
"engines": {
"node": "4.x || >=6.0.0"
}
},
"node_modules/node-pre-gyp": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz",
@ -688,9 +598,9 @@
}
},
"node_modules/rss-parser": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.12.0.tgz",
"integrity": "sha512-aqD3E8iavcCdkhVxNDIdg1nkBI17jgqF+9OqPS1orwNaOgySdpvq6B+DoONLhzjzwV8mWg37sb60e4bmLK117A==",
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.11.0.tgz",
"integrity": "sha512-oTLoYW+bNqNwkz8OpGinBU9s3As0sdczQjETIZFgyAdi7AopyhoVFGPIyFMYXXEY8hayKzD5CH+4CtmiPtJ89g==",
"dependencies": {
"entities": "^2.0.3",
"xml2js": "^0.4.19"
@ -799,9 +709,9 @@
}
},
"node_modules/tar": {
"version": "4.4.14",
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.14.tgz",
"integrity": "sha512-ouN3XcSWYOAHmXZ+P4NEFJvqXL50To9OZBSQNNP30vBUFJFZZ0PLX15fnwupv6azfxMUfUDUr2fhYw4zGAEPcg==",
"version": "4.4.13",
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
"integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
"dependencies": {
"chownr": "^1.1.1",
"fs-minipass": "^1.2.5",
@ -824,9 +734,9 @@
}
},
"node_modules/ts-node": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.1.0.tgz",
"integrity": "sha512-6szn3+J9WyG2hE+5W8e0ruZrzyk1uFLYye6IGMBadnOzDh8aP7t8CbFpsfCiEx2+wMixAhjFt7lOZC4+l+WbEA==",
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.0.0.tgz",
"integrity": "sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg==",
"dev": true,
"dependencies": {
"@tsconfig/node10": "^1.0.7",
@ -851,8 +761,8 @@
"node": ">=12.0.0"
},
"peerDependencies": {
"@swc/core": ">=1.2.50",
"@swc/wasm": ">=1.2.50",
"@swc/core": ">=1.2.45",
"@swc/wasm": ">=1.2.45",
"@types/node": "*",
"typescript": ">=2.7"
},
@ -866,9 +776,9 @@
}
},
"node_modules/typescript": {
"version": "4.3.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
"integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz",
"integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
@ -987,30 +897,9 @@
"dev": true
},
"@types/node": {
"version": "16.3.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz",
"integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA=="
},
"@types/node-fetch": {
"version": "2.5.11",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.11.tgz",
"integrity": "sha512-2upCKaqVZETDRb8A2VTaRymqFBEgH8u6yr96b/u3+1uQEPDRo3mJLEiPk7vdXBHRtjwkjqzFYMJXrt0Z9QsYjQ==",
"requires": {
"@types/node": "*",
"form-data": "^3.0.0"
},
"dependencies": {
"form-data": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
"integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
}
}
"version": "15.12.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.5.tgz",
"integrity": "sha512-se3yX7UHv5Bscf8f1ERKvQOD6sTyycH3hdaoozvaLxgUiY5lIGEeH37AD0G0Qi9kPqihPn0HOfd2yaIEN9VwEg=="
},
"@types/sqlite3": {
"version": "3.1.7",
@ -1055,11 +944,6 @@
"resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz",
"integrity": "sha1-sqRdpf36ILBJb8N2jMJ8EvqRan0="
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -1090,14 +974,6 @@
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -1132,11 +1008,6 @@
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
@ -1158,16 +1029,6 @@
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="
},
"form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
},
"fs-minipass": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
@ -1263,20 +1124,20 @@
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"listener-rss": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/listener-rss/-/listener-rss-0.0.3.tgz",
"integrity": "sha512-rccetOTwyyww/KDuaMX0EMjaGi+Jx+bojp18Ucxra6OeCfz2hC9FEasVNeENR096+ndOCS/rkKTJl+RD9rlAAQ==",
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/listener-rss/-/listener-rss-0.0.1.tgz",
"integrity": "sha512-ljH6FD4NMypkrZ9ZIMdW2YdAlm/Jer++zPI+1HTWK7BbhPJmUF3sSymqUqAjBcfH3xjt+fpYPqYgNYNM1fEYpA==",
"requires": {
"rss-parser": "^3.11.0"
"rss-parser": "3.11.0"
}
},
"listener-rss-aggregator": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/listener-rss-aggregator/-/listener-rss-aggregator-0.0.5.tgz",
"integrity": "sha512-0QE7kkzurjsWr4gNAJ4X+C7UFSyaVuYq2mKYXZ3shvyj81kULpBgFZSg/70MZkUoqixgWQ5P8oxyztRDOP78tw==",
"listener-rss-agregator": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/listener-rss-agregator/-/listener-rss-agregator-0.0.2.tgz",
"integrity": "sha512-ATj4esXtHLThe1/wkJ/ukA9+pC9FwBCNZCbVv7Ywr1eIbxBR+AHR5090lzCQt3WJsBblpTTZMni+vHxmGjRR7Q==",
"requires": {
"@databases/sqlite": "^3.0.0",
"listener-rss": "^0.0.3"
"listener-rss": "^0.0.1"
}
},
"make-error": {
@ -1285,19 +1146,6 @@
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true
},
"mime-db": {
"version": "1.48.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
"integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ=="
},
"mime-types": {
"version": "2.1.31",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
"integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
"requires": {
"mime-db": "1.48.0"
}
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@ -1347,20 +1195,15 @@
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ=="
},
"needle": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/needle/-/needle-2.8.0.tgz",
"integrity": "sha512-ZTq6WYkN/3782H1393me3utVYdq2XyqNUFBsprEE3VMAT0+hP/cItpnITpqsY6ep2yeFE4Tqtqwc74VqUlUYtw==",
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz",
"integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==",
"requires": {
"debug": "^3.2.6",
"iconv-lite": "^0.4.4",
"sax": "^1.2.4"
}
},
"node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
},
"node-pre-gyp": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz",
@ -1510,9 +1353,9 @@
}
},
"rss-parser": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.12.0.tgz",
"integrity": "sha512-aqD3E8iavcCdkhVxNDIdg1nkBI17jgqF+9OqPS1orwNaOgySdpvq6B+DoONLhzjzwV8mWg37sb60e4bmLK117A==",
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.11.0.tgz",
"integrity": "sha512-oTLoYW+bNqNwkz8OpGinBU9s3As0sdczQjETIZFgyAdi7AopyhoVFGPIyFMYXXEY8hayKzD5CH+4CtmiPtJ89g==",
"requires": {
"entities": "^2.0.3",
"xml2js": "^0.4.19"
@ -1605,9 +1448,9 @@
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
},
"tar": {
"version": "4.4.14",
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.14.tgz",
"integrity": "sha512-ouN3XcSWYOAHmXZ+P4NEFJvqXL50To9OZBSQNNP30vBUFJFZZ0PLX15fnwupv6azfxMUfUDUr2fhYw4zGAEPcg==",
"version": "4.4.13",
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
"integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
"requires": {
"chownr": "^1.1.1",
"fs-minipass": "^1.2.5",
@ -1627,9 +1470,9 @@
}
},
"ts-node": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.1.0.tgz",
"integrity": "sha512-6szn3+J9WyG2hE+5W8e0ruZrzyk1uFLYye6IGMBadnOzDh8aP7t8CbFpsfCiEx2+wMixAhjFt7lOZC4+l+WbEA==",
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.0.0.tgz",
"integrity": "sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg==",
"dev": true,
"requires": {
"@tsconfig/node10": "^1.0.7",
@ -1645,9 +1488,9 @@
}
},
"typescript": {
"version": "4.3.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
"integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz",
"integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==",
"dev": true
},
"util-deprecate": {

View File

@ -1,9 +1,9 @@
{
"name": "peertube-plugin-auto-import-ytb",
"description": "Peertube plugin to auto import videos from a youtube channel to a local peertube channel",
"description": "PeerTube plugin quickstart",
"version": "0.0.2",
"author": "AmauryJOLY",
"bugs": "https://zeteo.me/gitea/Outils-PeerTube/peertube-plugin-auto-import-ytb/issues",
"bugs": "https://framagit.org/framasoft/peertube/peertube-plugin-quickstart/issues",
"clientScripts": [],
"css": [],
"devDependencies": {
@ -13,28 +13,24 @@
"engine": {
"peertube": ">=3.2.0"
},
"homepage": "https://zeteo.me/gitea/Outils-PeerTube/peertube-plugin-auto-import-ytb",
"homepage": "https://framagit.org/framasoft/peertube/peertube-plugin-quickstart",
"keywords": [
"peertube",
"plugin"
],
"library": "./dist/src/main.js",
"library": "./dist/main.js",
"files": [
"dist/",
"README.md"
],
"scripts": {
"predeploy": "npm run build",
"buildAndDeploy": "npm run build && npm run deploy",
"deploy": "bash ./scripts/deploy.sh",
"build": "tsc"
},
"staticDirs": {},
"translations": {},
"dependencies": {
"@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"
"listener-rss-agregator": "0.0.2"
}
}

View File

@ -1,13 +1,12 @@
#/bin/bash
tmp_dir=$(mktemp -d)/peertube-plugin-auto-import-ytb
work_dir=$(pwd)
# echo "${work_dir}"
# echo $work_dir
mkdir "${tmp_dir}"
mkdir $tmp_dir
# echo "directory created"
cp "${work_dir}/dist" "${work_dir}/package.json" "${work_dir}/LICENSE" $tmp_dir -r
# echo "rsync --exclude-from=$work_dir.rsyncignore $work_dir $tmp_dir"
# echo "rsync done"
cd "../PeerTube-cli"
cd "../PeerTube"
node "./dist/server/tools/peertube.js" plugins install --path "${tmp_dir}"
# echo $tmp_dir

View File

@ -1,158 +1,63 @@
import { ListenerRssAggregator } from "listener-rss-aggregator";
import { ListenerRss } from "listener-rss";
import { PeerTubeRequester } from "../lib/peertubeRequester";
import { ManageListener } from 'listener-rss-agregator';
type ListenerData = ListenerRss.Config & {
address: string;
channelId: string;
};
let myManager : ManageListener;
let bindistenerChannelId: {[key: string] : string} = {};
let myManager: ListenerRssAggregator;
let listenersDataBinding = new Map<string, ListenerData>();
let logger: any;
let peertube: PeerTubeRequester | undefined = undefined;
let goodPeertubeCredential: boolean = false;
import * as path from "path";
import fs from "fs";
import * as path from 'path';
async function register({
registerSetting,
settingsManager,
registerSetting,
settingsManager,
peertubeHelpers,
}: any) {
registerSetting({
name: 'ytb-urls',
label: 'liste des urls youtube a auto-importer',
type: 'input-textarea'
})
const basePath = peertubeHelpers.plugin.getDataDirectoryPath();
logger = peertubeHelpers.logger;
myManager = new ManageListener(path.join(basePath, '/data/storage.bd'));
registerSetting({
name: "ytb-urls",
label: "URL list of Youtube channel to synchronize",
type: "input-textarea",
});
const inputs = await settingsManager.getSetting('ytb-urls');
registerSetting({
name: "admin-name",
label: "Admin Username",
type: "input",
});
addListeners(inputs);
registerSetting({
name: "admin-password",
label: "Admin Password",
type: "input-password",
});
settingsManager.onSettingsChange((settings: any) => {
myManager.stopAll();
myManager.save();
logger.debug("setting register");
fs.appendFileSync(path.join(basePath, "/storage.bd"), "");
addListeners(settings['ytb-urls']);
})
const configAggregator = await ListenerRssAggregator.instantiateAggregator(
path.join(basePath, "/storage.bd")
);
myManager = new ListenerRssAggregator(configAggregator);
myManager.on('update', (entries: any) => {
// for (const item in entries.items)
// console.info(item.)
logger.debug("Aggregator created");
})
const settingYtbUrls = await settingsManager.getSetting("ytb-urls");
if (settingYtbUrls) await addListeners(settingYtbUrls);
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"]);
});
myManager.on("newEntries", async (entries: any) => {
const datas = listenersDataBinding.get(entries.addressListener);
if (!datas) return;
logger.debug(
"New entries detected from channel #%i: %s",
datas.channelId,
JSON.stringify(entries)
);
for (const item of entries.items)
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);
function addListeners(listenerInput: any) {
for (const line in listenerInput.split('\n'))
if (!myManager.listenerArray.map((it: any) => it.address).includes(line)) // si ligne non présente
{
let splitted = line.split(':');
bindistenerChannelId[splitted[1]] = splitted[0];
myManager.registerListener({ address: splitted[0] });
}
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 {
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();
myManager.save();
myManager.startAll();
}
async function unregister() {
myManager.stopAll();
myManager.save();
return
}
module.exports = {
register,
unregister,
};
unregister
}

View File

@ -4,8 +4,8 @@
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
@ -14,8 +14,8 @@
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./dist/" /* Redirect output structure to the directory. */,
// "rootDir": "./src/", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
"outDir": "./dist/", /* Redirect output structure to the directory. */
"rootDir": "./src/", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
@ -25,7 +25,7 @@
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true /* Enable all strict type-checking options. */,
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
@ -47,14 +47,11 @@
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
"rootDirs": [
"./src/",
"./lib/"
] /* List of root folders whose combined content represents the structure of the project at runtime. */,
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
@ -69,7 +66,7 @@
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true /* Skip type checking of declaration files. */,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}