From 3ea2970ab1e1ae5482c8641c55ad3fcea261510f Mon Sep 17 00:00:00 2001 From: Samuel ORTION Date: Fri, 2 Jul 2021 17:06:49 +0200 Subject: [PATCH] Initial version of you2peer found functionnal with SigmaTube --- .gitignore | 3 ++ README.md | 40 +++++++++++++++++++++++++- config.json.sample | 19 +++++++++++++ src/mirror.py | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 config.json.sample create mode 100755 src/mirror.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1268165 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +config.json +token.sh +data/* \ No newline at end of file diff --git a/README.md b/README.md index 80d8e5d..bc86d51 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,41 @@ # you2peer -Python script that mirrors YouTube Channels or playlist on a PeerTube instance \ No newline at end of file +Python script that mirrors YouTube Channels or playlist on a PeerTube instance + +## Requirements + +* youtube-dl (both on machine running this script, and on peertube host) +* python3 requests +* cURL (to retrieve credentials first time) + +## Usage + +Copy config file sample +```bash +cp config.json.sample config.json +``` + +Get *Peer*Tube config: (Populate config.json with json response values..) +```bash +# Get client tokens +curl https://peertube.example.com/api/v1/oauth-clients/local + +# Get user token +curl -X POST \ + -d "client_id=zip6rwzni6hplvtw3dp9t02hnkfugpzu&client_secret=AjWiOapPltI6EnsWQwlFarRtLh4u8tDt&grant_type=password&response_type=code&username=your_user&password=your_password" \ + https://peertube.example.com/api/v1/users/token +``` + +First create target channels and playlists (using an admin account) and then Get channels id, and playlists id using api in navigator (to be added in `config.json`): +* https://peertube.example.com/api/v1/accounts/{username}/video-channels +* https://peertube.example.com/api/v1/video-playlists + +## Contributors + +* Samuel ORTION + +Others are welcome ! + +## License + +* GNU GPL v3 or later (see [LICENSE](LICENSE)) \ No newline at end of file diff --git a/config.json.sample b/config.json.sample new file mode 100644 index 0000000..6aa1c12 --- /dev/null +++ b/config.json.sample @@ -0,0 +1,19 @@ +{ + "you2peer": { + "channels": [{ + "name": "fouloscopie", + "url": "https://www.youtube.com/watch?v=5CaVhGTG8eA&list=UULXDNUOO3EQ80VmD9nQBHPg&index=2", + "channel_id": 3048, + "playlist_id": 3478 + }] + }, + "peertube": { + "username": "username", + "password": "password", + "base_url": "peertube.example.com", + "client_id": "client_id", + "client_secret": "client_secret", + "access_token": "access_token", + "token_type": "Bearer" + } +} \ No newline at end of file diff --git a/src/mirror.py b/src/mirror.py new file mode 100755 index 0000000..5b55b82 --- /dev/null +++ b/src/mirror.py @@ -0,0 +1,70 @@ +#!/usr/bin/python3 + +""" +Mirror YouTube playlist +(all channel content for instance) +into PeerTube playlist +using PeerTube API and youtube-dl +""" + +import requests +import json +import os + +with open("config.json", 'r') as f: + config = json.load(f) + +def update_mirror(channel): + name = channel['name'] + playlist_url = channel['url'] + os.system(f"youtube-dl '{playlist_url}' --flat-playlist --dump-single-json | jq . > 'data/{name}.playlist.last.json'") + base_yt_url = "https://www.youtube.com/watch?v=" + added_previous = [] + if os.path.exists(f"data/{name}.playlist.previous.json"): + with open(f"data/{name}.playlist.previous.json", 'r') as f: + playlist_previous = json.load(f) + for entry in playlist_previous['entries']: + video_id = entry['id'] + added_previous.append(video_id) + urls = [] + with open(f"data/{name}.playlist.last.json", 'r') as f: + playlist = json.load(f) + for entry in playlist['entries']: + if not entry['id'] in added_previous: + url = base_yt_url + entry['url'] + urls.append(url) + + print(urls) + + TOKEN = config['peertube']['access_token'] + hed = {'Authorization': 'Bearer ' + TOKEN} + i = 1 + n = len(urls) + for url in urls: + payload = { + 'channelId': channel['channel_id'], + 'targetUrl': url, + 'privacy': 1, + 'waitTranscoding': True + } + req = f"https://{config['peertube']['base_url']}/api/v1/videos/imports" + response = requests.post(req, json=payload, headers=hed) + # print(response.content) + video_data = response.json() + video_id = video_data['video']['id'] + url = f"https://{config['peertube']['base_url']}/api/v1/video-playlists/{channel['playlist_id']}/videos" + payload = { + 'videoId': video_id + } + response = requests.post(url, json=payload, headers=hed) + print(response.status_code) + print("{0}/{1} done ({2:.2f}%)".format(i, n, i/n * 100)) + i += 1 + +def main(): + channels = config['you2peer']['channels'] + for channel in channels: + update_mirror(channel) + +if __name__ == "__main__": + main() \ No newline at end of file