forked from Outils-PeerTube/peertube-plugin-auto-import-ytb
		
	Compare commits
	
		
			24 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 6dadf326ac | |||
| 809803a194 | |||
| 2c6df73d02 | |||
|  | 6407c1b072 | ||
|  | b9d99891db | ||
|  | 48b73a89bc | ||
|  | 82f4a3e6ec | ||
| df0e311dbc | |||
|  | ae195d9170 | ||
|  | f579afab16 | ||
|  | 41098d09a7 | ||
| b2b04df23b | |||
| 51126e7f0f | |||
| 8f8f0c3cb0 | |||
|  | 9597cddc80 | ||
|  | 81f540e29d | ||
|  | 4f6587e1f6 | ||
|  | ce19792a28 | ||
|  | ea6adfc1fc | ||
|  | db856aa6e2 | ||
|  | afdd320056 | ||
|  | f26ac80aa5 | ||
| 85d38f7939 | |||
|  | f21f752cbb | 
							
								
								
									
										1
									
								
								.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | {} | ||||||
| @@ -1 +0,0 @@ | |||||||
| {} |  | ||||||
							
								
								
									
										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. | ||||||
|   | |||||||
							
								
								
									
										110
									
								
								lib/peertubeRequester.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								lib/peertubeRequester.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | |||||||
|  | // 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
									
									
									
								
							
							
						
						
									
										275
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,13 +1,17 @@ | |||||||
| { | { | ||||||
|   "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": { | ||||||
|         "listener-rss-agregator": "0.0.2" |         "@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" | ||||||
|       }, |       }, | ||||||
|       "devDependencies": { |       "devDependencies": { | ||||||
|         "ts-node": "^10.0.0", |         "ts-node": "^10.0.0", | ||||||
| @@ -69,9 +73,31 @@ | |||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "node_modules/@types/node": { |     "node_modules/@types/node": { | ||||||
|       "version": "15.12.5", |       "version": "16.3.1", | ||||||
|       "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.5.tgz", |       "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", | ||||||
|       "integrity": "sha512-se3yX7UHv5Bscf8f1ERKvQOD6sTyycH3hdaoozvaLxgUiY5lIGEeH37AD0G0Qi9kPqihPn0HOfd2yaIEN9VwEg==" |       "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" | ||||||
|  |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/@types/sqlite3": { |     "node_modules/@types/sqlite3": { | ||||||
|       "version": "3.1.7", |       "version": "3.1.7", | ||||||
| @@ -119,6 +145,11 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz", |       "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz", | ||||||
|       "integrity": "sha1-sqRdpf36ILBJb8N2jMJ8EvqRan0=" |       "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": { |     "node_modules/balanced-match": { | ||||||
|       "version": "1.0.2", |       "version": "1.0.2", | ||||||
|       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", |       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", | ||||||
| @@ -152,6 +183,17 @@ | |||||||
|         "node": ">=0.10.0" |         "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": { |     "node_modules/concat-map": { | ||||||
|       "version": "0.0.1", |       "version": "0.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", |       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", | ||||||
| @@ -189,6 +231,14 @@ | |||||||
|         "node": ">=4.0.0" |         "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": { |     "node_modules/delegates": { | ||||||
|       "version": "1.0.0", |       "version": "1.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", |       "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", | ||||||
| @@ -222,6 +272,19 @@ | |||||||
|         "url": "https://github.com/fb55/entities?sponsor=1" |         "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": { |     "node_modules/fs-minipass": { | ||||||
|       "version": "1.2.7", |       "version": "1.2.7", | ||||||
|       "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", |       "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", | ||||||
| @@ -329,20 +392,20 @@ | |||||||
|       "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" |       "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" | ||||||
|     }, |     }, | ||||||
|     "node_modules/listener-rss": { |     "node_modules/listener-rss": { | ||||||
|       "version": "0.0.1", |       "version": "0.0.3", | ||||||
|       "resolved": "https://registry.npmjs.org/listener-rss/-/listener-rss-0.0.1.tgz", |       "resolved": "https://registry.npmjs.org/listener-rss/-/listener-rss-0.0.3.tgz", | ||||||
|       "integrity": "sha512-ljH6FD4NMypkrZ9ZIMdW2YdAlm/Jer++zPI+1HTWK7BbhPJmUF3sSymqUqAjBcfH3xjt+fpYPqYgNYNM1fEYpA==", |       "integrity": "sha512-rccetOTwyyww/KDuaMX0EMjaGi+Jx+bojp18Ucxra6OeCfz2hC9FEasVNeENR096+ndOCS/rkKTJl+RD9rlAAQ==", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "rss-parser": "3.11.0" |         "rss-parser": "^3.11.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/listener-rss-agregator": { |     "node_modules/listener-rss-aggregator": { | ||||||
|       "version": "0.0.2", |       "version": "0.0.5", | ||||||
|       "resolved": "https://registry.npmjs.org/listener-rss-agregator/-/listener-rss-agregator-0.0.2.tgz", |       "resolved": "https://registry.npmjs.org/listener-rss-aggregator/-/listener-rss-aggregator-0.0.5.tgz", | ||||||
|       "integrity": "sha512-ATj4esXtHLThe1/wkJ/ukA9+pC9FwBCNZCbVv7Ywr1eIbxBR+AHR5090lzCQt3WJsBblpTTZMni+vHxmGjRR7Q==", |       "integrity": "sha512-0QE7kkzurjsWr4gNAJ4X+C7UFSyaVuYq2mKYXZ3shvyj81kULpBgFZSg/70MZkUoqixgWQ5P8oxyztRDOP78tw==", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "@databases/sqlite": "^3.0.0", |         "@databases/sqlite": "^3.0.0", | ||||||
|         "listener-rss": "^0.0.1" |         "listener-rss": "^0.0.3" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/make-error": { |     "node_modules/make-error": { | ||||||
| @@ -351,6 +414,25 @@ | |||||||
|       "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", |       "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", | ||||||
|       "dev": true |       "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": { |     "node_modules/minimatch": { | ||||||
|       "version": "3.0.4", |       "version": "3.0.4", | ||||||
|       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", |       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", | ||||||
| @@ -406,9 +488,9 @@ | |||||||
|       "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" |       "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" | ||||||
|     }, |     }, | ||||||
|     "node_modules/needle": { |     "node_modules/needle": { | ||||||
|       "version": "2.6.0", |       "version": "2.8.0", | ||||||
|       "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", |       "resolved": "https://registry.npmjs.org/needle/-/needle-2.8.0.tgz", | ||||||
|       "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", |       "integrity": "sha512-ZTq6WYkN/3782H1393me3utVYdq2XyqNUFBsprEE3VMAT0+hP/cItpnITpqsY6ep2yeFE4Tqtqwc74VqUlUYtw==", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "debug": "^3.2.6", |         "debug": "^3.2.6", | ||||||
|         "iconv-lite": "^0.4.4", |         "iconv-lite": "^0.4.4", | ||||||
| @@ -421,6 +503,14 @@ | |||||||
|         "node": ">= 4.4.x" |         "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": { |     "node_modules/node-pre-gyp": { | ||||||
|       "version": "0.11.0", |       "version": "0.11.0", | ||||||
|       "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", |       "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", | ||||||
| @@ -598,9 +688,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/rss-parser": { |     "node_modules/rss-parser": { | ||||||
|       "version": "3.11.0", |       "version": "3.12.0", | ||||||
|       "resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.11.0.tgz", |       "resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.12.0.tgz", | ||||||
|       "integrity": "sha512-oTLoYW+bNqNwkz8OpGinBU9s3As0sdczQjETIZFgyAdi7AopyhoVFGPIyFMYXXEY8hayKzD5CH+4CtmiPtJ89g==", |       "integrity": "sha512-aqD3E8iavcCdkhVxNDIdg1nkBI17jgqF+9OqPS1orwNaOgySdpvq6B+DoONLhzjzwV8mWg37sb60e4bmLK117A==", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "entities": "^2.0.3", |         "entities": "^2.0.3", | ||||||
|         "xml2js": "^0.4.19" |         "xml2js": "^0.4.19" | ||||||
| @@ -709,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", | ||||||
| @@ -734,9 +824,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/ts-node": { |     "node_modules/ts-node": { | ||||||
|       "version": "10.0.0", |       "version": "10.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.0.0.tgz", |       "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.1.0.tgz", | ||||||
|       "integrity": "sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg==", |       "integrity": "sha512-6szn3+J9WyG2hE+5W8e0ruZrzyk1uFLYye6IGMBadnOzDh8aP7t8CbFpsfCiEx2+wMixAhjFt7lOZC4+l+WbEA==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "@tsconfig/node10": "^1.0.7", |         "@tsconfig/node10": "^1.0.7", | ||||||
| @@ -761,8 +851,8 @@ | |||||||
|         "node": ">=12.0.0" |         "node": ">=12.0.0" | ||||||
|       }, |       }, | ||||||
|       "peerDependencies": { |       "peerDependencies": { | ||||||
|         "@swc/core": ">=1.2.45", |         "@swc/core": ">=1.2.50", | ||||||
|         "@swc/wasm": ">=1.2.45", |         "@swc/wasm": ">=1.2.50", | ||||||
|         "@types/node": "*", |         "@types/node": "*", | ||||||
|         "typescript": ">=2.7" |         "typescript": ">=2.7" | ||||||
|       }, |       }, | ||||||
| @@ -776,9 +866,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/typescript": { |     "node_modules/typescript": { | ||||||
|       "version": "4.3.4", |       "version": "4.3.5", | ||||||
|       "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz", |       "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", | ||||||
|       "integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==", |       "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "bin": { |       "bin": { | ||||||
|         "tsc": "bin/tsc", |         "tsc": "bin/tsc", | ||||||
| @@ -897,9 +987,30 @@ | |||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "@types/node": { |     "@types/node": { | ||||||
|       "version": "15.12.5", |       "version": "16.3.1", | ||||||
|       "resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.5.tgz", |       "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", | ||||||
|       "integrity": "sha512-se3yX7UHv5Bscf8f1ERKvQOD6sTyycH3hdaoozvaLxgUiY5lIGEeH37AD0G0Qi9kPqihPn0HOfd2yaIEN9VwEg==" |       "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" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|     }, |     }, | ||||||
|     "@types/sqlite3": { |     "@types/sqlite3": { | ||||||
|       "version": "3.1.7", |       "version": "3.1.7", | ||||||
| @@ -944,6 +1055,11 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz", |       "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz", | ||||||
|       "integrity": "sha1-sqRdpf36ILBJb8N2jMJ8EvqRan0=" |       "integrity": "sha1-sqRdpf36ILBJb8N2jMJ8EvqRan0=" | ||||||
|     }, |     }, | ||||||
|  |     "asynckit": { | ||||||
|  |       "version": "0.4.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", | ||||||
|  |       "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" | ||||||
|  |     }, | ||||||
|     "balanced-match": { |     "balanced-match": { | ||||||
|       "version": "1.0.2", |       "version": "1.0.2", | ||||||
|       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", |       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", | ||||||
| @@ -974,6 +1090,14 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", |       "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", | ||||||
|       "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" |       "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": { |     "concat-map": { | ||||||
|       "version": "0.0.1", |       "version": "0.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", |       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", | ||||||
| @@ -1008,6 +1132,11 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", |       "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", | ||||||
|       "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" |       "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": { |     "delegates": { | ||||||
|       "version": "1.0.0", |       "version": "1.0.0", | ||||||
|       "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", |       "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", | ||||||
| @@ -1029,6 +1158,16 @@ | |||||||
|       "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", |       "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", | ||||||
|       "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" |       "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": { |     "fs-minipass": { | ||||||
|       "version": "1.2.7", |       "version": "1.2.7", | ||||||
|       "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", |       "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", | ||||||
| @@ -1124,20 +1263,20 @@ | |||||||
|       "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" |       "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" | ||||||
|     }, |     }, | ||||||
|     "listener-rss": { |     "listener-rss": { | ||||||
|       "version": "0.0.1", |       "version": "0.0.3", | ||||||
|       "resolved": "https://registry.npmjs.org/listener-rss/-/listener-rss-0.0.1.tgz", |       "resolved": "https://registry.npmjs.org/listener-rss/-/listener-rss-0.0.3.tgz", | ||||||
|       "integrity": "sha512-ljH6FD4NMypkrZ9ZIMdW2YdAlm/Jer++zPI+1HTWK7BbhPJmUF3sSymqUqAjBcfH3xjt+fpYPqYgNYNM1fEYpA==", |       "integrity": "sha512-rccetOTwyyww/KDuaMX0EMjaGi+Jx+bojp18Ucxra6OeCfz2hC9FEasVNeENR096+ndOCS/rkKTJl+RD9rlAAQ==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "rss-parser": "3.11.0" |         "rss-parser": "^3.11.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "listener-rss-agregator": { |     "listener-rss-aggregator": { | ||||||
|       "version": "0.0.2", |       "version": "0.0.5", | ||||||
|       "resolved": "https://registry.npmjs.org/listener-rss-agregator/-/listener-rss-agregator-0.0.2.tgz", |       "resolved": "https://registry.npmjs.org/listener-rss-aggregator/-/listener-rss-aggregator-0.0.5.tgz", | ||||||
|       "integrity": "sha512-ATj4esXtHLThe1/wkJ/ukA9+pC9FwBCNZCbVv7Ywr1eIbxBR+AHR5090lzCQt3WJsBblpTTZMni+vHxmGjRR7Q==", |       "integrity": "sha512-0QE7kkzurjsWr4gNAJ4X+C7UFSyaVuYq2mKYXZ3shvyj81kULpBgFZSg/70MZkUoqixgWQ5P8oxyztRDOP78tw==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "@databases/sqlite": "^3.0.0", |         "@databases/sqlite": "^3.0.0", | ||||||
|         "listener-rss": "^0.0.1" |         "listener-rss": "^0.0.3" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "make-error": { |     "make-error": { | ||||||
| @@ -1146,6 +1285,19 @@ | |||||||
|       "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", |       "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", | ||||||
|       "dev": true |       "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": { |     "minimatch": { | ||||||
|       "version": "3.0.4", |       "version": "3.0.4", | ||||||
|       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", |       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", | ||||||
| @@ -1195,15 +1347,20 @@ | |||||||
|       "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" |       "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" | ||||||
|     }, |     }, | ||||||
|     "needle": { |     "needle": { | ||||||
|       "version": "2.6.0", |       "version": "2.8.0", | ||||||
|       "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", |       "resolved": "https://registry.npmjs.org/needle/-/needle-2.8.0.tgz", | ||||||
|       "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", |       "integrity": "sha512-ZTq6WYkN/3782H1393me3utVYdq2XyqNUFBsprEE3VMAT0+hP/cItpnITpqsY6ep2yeFE4Tqtqwc74VqUlUYtw==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "debug": "^3.2.6", |         "debug": "^3.2.6", | ||||||
|         "iconv-lite": "^0.4.4", |         "iconv-lite": "^0.4.4", | ||||||
|         "sax": "^1.2.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": { |     "node-pre-gyp": { | ||||||
|       "version": "0.11.0", |       "version": "0.11.0", | ||||||
|       "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", |       "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", | ||||||
| @@ -1353,9 +1510,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "rss-parser": { |     "rss-parser": { | ||||||
|       "version": "3.11.0", |       "version": "3.12.0", | ||||||
|       "resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.11.0.tgz", |       "resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.12.0.tgz", | ||||||
|       "integrity": "sha512-oTLoYW+bNqNwkz8OpGinBU9s3As0sdczQjETIZFgyAdi7AopyhoVFGPIyFMYXXEY8hayKzD5CH+4CtmiPtJ89g==", |       "integrity": "sha512-aqD3E8iavcCdkhVxNDIdg1nkBI17jgqF+9OqPS1orwNaOgySdpvq6B+DoONLhzjzwV8mWg37sb60e4bmLK117A==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "entities": "^2.0.3", |         "entities": "^2.0.3", | ||||||
|         "xml2js": "^0.4.19" |         "xml2js": "^0.4.19" | ||||||
| @@ -1448,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", | ||||||
| @@ -1470,9 +1627,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "ts-node": { |     "ts-node": { | ||||||
|       "version": "10.0.0", |       "version": "10.1.0", | ||||||
|       "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.0.0.tgz", |       "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.1.0.tgz", | ||||||
|       "integrity": "sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg==", |       "integrity": "sha512-6szn3+J9WyG2hE+5W8e0ruZrzyk1uFLYye6IGMBadnOzDh8aP7t8CbFpsfCiEx2+wMixAhjFt7lOZC4+l+WbEA==", | ||||||
|       "dev": true, |       "dev": true, | ||||||
|       "requires": { |       "requires": { | ||||||
|         "@tsconfig/node10": "^1.0.7", |         "@tsconfig/node10": "^1.0.7", | ||||||
| @@ -1488,9 +1645,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "typescript": { |     "typescript": { | ||||||
|       "version": "4.3.4", |       "version": "4.3.5", | ||||||
|       "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz", |       "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", | ||||||
|       "integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==", |       "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", | ||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "util-deprecate": { |     "util-deprecate": { | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								package.json
									
									
									
									
									
								
							| @@ -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,24 +13,28 @@ | |||||||
|   "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" | ||||||
|   ], |   ], | ||||||
|   "library": "./dist/main.js", |   "library": "./dist/src/main.js", | ||||||
|   "files": [ |   "files": [ | ||||||
|     "dist/", |     "dist/", | ||||||
|     "README.md" |     "README.md" | ||||||
|   ], |   ], | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "buildAndDeploy": "npm run build && npm run deploy", |     "predeploy": "npm run build", | ||||||
|     "deploy": "bash ./scripts/deploy.sh", |     "deploy": "bash ./scripts/deploy.sh", | ||||||
|     "build": "tsc" |     "build": "tsc" | ||||||
|   }, |   }, | ||||||
|   "staticDirs": {}, |   "staticDirs": {}, | ||||||
|   "translations": {}, |   "translations": {}, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "listener-rss-agregator": "0.0.2" |     "@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" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,12 +1,13 @@ | |||||||
|  | #/bin/bash | ||||||
| tmp_dir=$(mktemp -d)/peertube-plugin-auto-import-ytb | tmp_dir=$(mktemp -d)/peertube-plugin-auto-import-ytb | ||||||
| work_dir=$(pwd) | work_dir=$(pwd) | ||||||
| # echo $work_dir | # echo "${work_dir}" | ||||||
|  |  | ||||||
| mkdir $tmp_dir | mkdir "${tmp_dir}" | ||||||
| # echo "directory created" | # echo "directory created" | ||||||
| cp "${work_dir}/dist" "${work_dir}/package.json" "${work_dir}/LICENSE" $tmp_dir -r | 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 --exclude-from=$work_dir.rsyncignore $work_dir $tmp_dir" | ||||||
| # echo "rsync done" | # echo "rsync done" | ||||||
| cd "../PeerTube" | cd "../PeerTube-cli" | ||||||
| node "./dist/server/tools/peertube.js" plugins install --path "${tmp_dir}" | node "./dist/server/tools/peertube.js" plugins install --path "${tmp_dir}" | ||||||
| # echo $tmp_dir | # echo $tmp_dir | ||||||
							
								
								
									
										165
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										165
									
								
								src/main.ts
									
									
									
									
									
								
							| @@ -1,63 +1,158 @@ | |||||||
| import { ManageListener } from 'listener-rss-agregator'; | import { ListenerRssAggregator } from "listener-rss-aggregator"; | ||||||
|  | import { ListenerRss } from "listener-rss"; | ||||||
|  | import { PeerTubeRequester } from "../lib/peertubeRequester"; | ||||||
|  |  | ||||||
| let myManager : ManageListener; | type ListenerData = ListenerRss.Config & { | ||||||
| let bindistenerChannelId: {[key: string] : string} = {}; |   address: string; | ||||||
|  |   channelId: string; | ||||||
|  | }; | ||||||
|  |  | ||||||
| import * as path from 'path'; | 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"; | ||||||
|  |  | ||||||
| async function register({ | async function register({ | ||||||
|   registerSetting, |   registerSetting, | ||||||
|   settingsManager, |   settingsManager, | ||||||
|   peertubeHelpers, |   peertubeHelpers, | ||||||
| }: any) { | }: any) { | ||||||
|   registerSetting({ |  | ||||||
|     name: 'ytb-urls', |  | ||||||
|     label: 'liste des urls youtube a auto-importer', |  | ||||||
|     type: 'input-textarea' |  | ||||||
|   }) |  | ||||||
|  |  | ||||||
|   const basePath = peertubeHelpers.plugin.getDataDirectoryPath(); |   const basePath = peertubeHelpers.plugin.getDataDirectoryPath(); | ||||||
|   myManager = new ManageListener(path.join(basePath, '/data/storage.bd')); |   logger = peertubeHelpers.logger; | ||||||
|  |  | ||||||
|   const inputs = await settingsManager.getSetting('ytb-urls'); |   registerSetting({ | ||||||
|  |     name: "ytb-urls", | ||||||
|  |     label: "URL list of Youtube channel to synchronize", | ||||||
|  |     type: "input-textarea", | ||||||
|  |   }); | ||||||
|  |  | ||||||
|   addListeners(inputs); |   registerSetting({ | ||||||
|  |     name: "admin-name", | ||||||
|  |     label: "Admin Username", | ||||||
|  |     type: "input", | ||||||
|  |   }); | ||||||
|  |  | ||||||
|   settingsManager.onSettingsChange((settings: any) => { |   registerSetting({ | ||||||
|     myManager.stopAll(); |     name: "admin-password", | ||||||
|     myManager.save(); |     label: "Admin Password", | ||||||
|  |     type: "input-password", | ||||||
|  |   }); | ||||||
|  |  | ||||||
|     addListeners(settings['ytb-urls']); |   logger.debug("setting register"); | ||||||
|   }) |   fs.appendFileSync(path.join(basePath, "/storage.bd"), ""); | ||||||
|  |  | ||||||
|   myManager.on('update', (entries: any) => { |   const configAggregator = await ListenerRssAggregator.instantiateAggregator( | ||||||
|     // for (const item in entries.items) |     path.join(basePath, "/storage.bd") | ||||||
|     //   console.info(item.) |   ); | ||||||
|  |   myManager = new ListenerRssAggregator(configAggregator); | ||||||
|  |  | ||||||
|   }) |   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."); | ||||||
|  |       } | ||||||
|  |   }); | ||||||
| } | } | ||||||
|  |  | ||||||
| function addListeners(listenerInput: any) { | async function apiRequestInitializer(data: PeerTubeRequester.Config) { | ||||||
|   for (const line in listenerInput.split('\n')) |   peertube = new PeerTubeRequester(data); | ||||||
|     if (!myManager.listenerArray.map((it: any) => it.address).includes(line)) // si ligne non présente |  | ||||||
|     { |   try { | ||||||
|       let splitted = line.split(':'); |     await peertube.requestAuthToken(); | ||||||
|       bindistenerChannelId[splitted[1]] = splitted[0]; |     goodPeertubeCredential = true; | ||||||
|       myManager.registerListener({ address: splitted[0] }); |     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.save(); |   myManager.stopAll(); | ||||||
|   myManager.startAll(); |   await myManager.saveOverride(listeners); | ||||||
|  |  | ||||||
|  |   if (logger) logger.debug("Configuration changed: " + listenerInput); | ||||||
|  |  | ||||||
|  |   if (goodPeertubeCredential) myManager.startAll(); | ||||||
| } | } | ||||||
|  |  | ||||||
| async function unregister() { | async function unregister() { | ||||||
|   myManager.stopAll(); |   myManager.stopAll(); | ||||||
|   myManager.save(); |  | ||||||
|   return |  | ||||||
| } | } | ||||||
|  |  | ||||||
| module.exports = { | module.exports = { | ||||||
|   register, |   register, | ||||||
|   unregister |   unregister, | ||||||
| } | }; | ||||||
|   | |||||||
| @@ -4,8 +4,8 @@ | |||||||
|  |  | ||||||
|     /* Basic Options */ |     /* Basic Options */ | ||||||
|     // "incremental": true,                         /* Enable incremental compilation */ |     // "incremental": true,                         /* Enable incremental compilation */ | ||||||
|     "target": "es5",                                /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', 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'. */ |     "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. */ |     // "lib": [],                                   /* Specify library files to be included in the compilation. */ | ||||||
|     // "allowJs": true,                             /* Allow javascript files to be compiled. */ |     // "allowJs": true,                             /* Allow javascript files to be compiled. */ | ||||||
|     // "checkJs": true,                             /* Report errors in .js files. */ |     // "checkJs": true,                             /* Report errors in .js files. */ | ||||||
| @@ -14,8 +14,8 @@ | |||||||
|     // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */ |     // "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */ | ||||||
|     // "sourceMap": true,                           /* Generates corresponding '.map' file. */ |     // "sourceMap": true,                           /* Generates corresponding '.map' file. */ | ||||||
|     // "outFile": "./",                             /* Concatenate and emit output to single file. */ |     // "outFile": "./",                             /* Concatenate and emit output to single file. */ | ||||||
|     "outDir": "./dist/",                              /* Redirect output structure to the directory. */ |     "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. */ |     // "rootDir": "./src/",                             /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ | ||||||
|     // "composite": true,                           /* Enable project compilation */ |     // "composite": true,                           /* Enable project compilation */ | ||||||
|     // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */ |     // "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */ | ||||||
|     // "removeComments": true,                      /* Do not emit comments to output. */ |     // "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'). */ |     // "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ | ||||||
|  |  | ||||||
|     /* Strict Type-Checking Options */ |     /* 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. */ |     // "noImplicitAny": true,                       /* Raise error on expressions and declarations with an implied 'any' type. */ | ||||||
|     // "strictNullChecks": true,                    /* Enable strict null checks. */ |     // "strictNullChecks": true,                    /* Enable strict null checks. */ | ||||||
|     // "strictFunctionTypes": true,                 /* Enable strict checking of function types. */ |     // "strictFunctionTypes": true,                 /* Enable strict checking of function types. */ | ||||||
| @@ -47,11 +47,14 @@ | |||||||
|     // "moduleResolution": "node",                  /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ |     // "moduleResolution": "node",                  /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ | ||||||
|     // "baseUrl": "./",                             /* Base directory to resolve non-absolute module names. */ |     // "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'. */ |     // "paths": {},                                 /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ | ||||||
|     // "rootDirs": [],                              /* List of root folders whose combined content represents the structure of the project at runtime. */ |     "rootDirs": [ | ||||||
|  |       "./src/", | ||||||
|  |       "./lib/" | ||||||
|  |     ] /* List of root folders whose combined content represents the structure of the project at runtime. */, | ||||||
|     // "typeRoots": [],                             /* List of folders to include type definitions from. */ |     // "typeRoots": [],                             /* List of folders to include type definitions from. */ | ||||||
|     // "types": [],                                 /* Type declaration files to be included in compilation. */ |     // "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. */ |     // "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. */ |     // "preserveSymlinks": true,                    /* Do not resolve the real path of symlinks. */ | ||||||
|     // "allowUmdGlobalAccess": true,                /* Allow accessing UMD globals from modules. */ |     // "allowUmdGlobalAccess": true,                /* Allow accessing UMD globals from modules. */ | ||||||
|  |  | ||||||
| @@ -66,7 +69,7 @@ | |||||||
|     // "emitDecoratorMetadata": true,               /* Enables experimental support for emitting type metadata for decorators. */ |     // "emitDecoratorMetadata": true,               /* Enables experimental support for emitting type metadata for decorators. */ | ||||||
|  |  | ||||||
|     /* Advanced Options */ |     /* Advanced Options */ | ||||||
|     "skipLibCheck": true,                           /* Skip type checking of declaration files. */ |     "skipLibCheck": true /* Skip type checking of declaration files. */, | ||||||
|     "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ |     "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user