uploader boet

pull/1310/head
streetRAT 4 years ago
parent 82bd71d6a3
commit 6355c2b3b0

5
.gitignore vendored

@ -235,7 +235,7 @@ assets/
out out
.DS_Store .DS_Store
.setup-done-before .setup-done-before
results/* results/*.mp4
reddit-bot-351418-5560ebc49cac.json reddit-bot-351418-5560ebc49cac.json
/.idea /.idea
*.pyc *.pyc
@ -244,3 +244,6 @@ video_creation/data/envvars.txt
config.toml config.toml
video_creation/data/videos.json video_creation/data/videos.json
results/client_secrets.json
results/client_secrets.json.template
results/upload_video.py-oauth2.json

@ -0,0 +1,44 @@
# Upload script
- videos go into this results folder
- script needs to be in the same directory as videos
- videos scheduled to release every 4 hours
# Files needed
- client_secrets.json
I have left a .template for you to copy
```
{
"web": {
"client_id": < your client id goes here >,
"client_secret": < your client secret goes here >,
"redirect_uris": [],
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token"
}
}
```
# Changes required
- All objects in videos.json
```
{
...,
"uploaded": false,
"uploaded_at": "2022-10-20 12:00:00"
}
```
YYYY-MM-DD HH:MM:SS
you can get the uploaded_at time by running the first_time.py script and using the print output.
uploaded : false has been added to the videos.py payload so should be uploaded : false by defualt.
[Link to the docs](https://developers.google.com/youtube/v3/guides/uploading_a_video) I used to get this working.

@ -0,0 +1,5 @@
import datetime
format_data = "%Y-%m-%d %H:%M:%S.%f"
time = datetime.datetime.now().strftime(format_data)
print(time)

@ -0,0 +1,249 @@
import httplib2
import os
import random
import sys
import time
import datetime
import json
from apiclient.discovery import build
from apiclient.errors import HttpError
from apiclient.http import MediaFileUpload
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client.tools import argparser, run_flow
from datetime import timedelta
from datetime import datetime
# Explicitly tell the underlying HTTP transport library not to retry, since
# we are handling retry logic ourselves.
httplib2.RETRIES = 1
# Maximum number of times to retry before giving up.
MAX_RETRIES = 10
# Always retry when these exceptions are raised.
RETRIABLE_EXCEPTIONS = (
httplib2.HttpLib2Error,
IOError,
)
# Always retry when an apiclient.errors.HttpError with one of these status
# codes is raised.
RETRIABLE_STATUS_CODES = [500, 502, 503, 504]
# The CLIENT_SECRETS_FILE variable specifies the name of a file that contains
# the OAuth 2.0 information for this application, including its client_id and
# client_secret. You can acquire an OAuth 2.0 client ID and client secret from
# the Google API Console at
# https://console.developers.google.com/.
# Please ensure that you have enabled the YouTube Data API for your project.
# For more information about using OAuth2 to access the YouTube Data API, see:
# https://developers.google.com/youtube/v3/guides/authentication
# For more information about the client_secrets.json file format, see:
# https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
CLIENT_SECRETS_FILE = "client_secrets.json"
# This OAuth 2.0 access scope allows an application to upload files to the
# authenticated user's YouTube channel, but doesn't allow other types of access.
YOUTUBE_UPLOAD_SCOPE = "https://www.googleapis.com/auth/youtube.upload"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
# This variable defines a message to display if the CLIENT_SECRETS_FILE is
# missing.
MISSING_CLIENT_SECRETS_MESSAGE = """
WARNING: Please configure OAuth 2.0
To make this sample run you will need to populate the client_secrets.json file
found at:
%s
with information from the API Console
https://console.developers.google.com/
For more information about the client_secrets.json file format, please visit:
https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
""" % os.path.abspath(
os.path.join(os.path.dirname(__file__), CLIENT_SECRETS_FILE)
)
VALID_PRIVACY_STATUSES = ("public", "private", "unlisted")
def get_authenticated_service(args):
# print(CLIENT_SECRETS_FILE)
flow = flow_from_clientsecrets(
CLIENT_SECRETS_FILE,
scope=YOUTUBE_UPLOAD_SCOPE,
message=MISSING_CLIENT_SECRETS_MESSAGE,
)
storage = Storage("%s-oauth2.json" % sys.argv[0])
credentials = storage.get()
if credentials is None or credentials.invalid:
credentials = run_flow(flow, storage, args)
return build(
YOUTUBE_API_SERVICE_NAME,
YOUTUBE_API_VERSION,
http=credentials.authorize(httplib2.Http()),
)
def initialize_upload(youtube, options, i, next_upload_time):
tags = None
if options["keywords"]:
tags = options["keywords"].split(",")
body = dict(
snippet=dict(
title=options["title"],
description=options["description"],
tags=tags,
categoryId=options["category"],
),
status=dict(
privacyStatus=options["privacyStatus"],
publishAt=options[
"publishTime"
], # might need to be publishedAt, implement this
),
)
# Call the API's videos.insert method to create and upload the video.
insert_request = youtube.videos().insert(
part=",".join(body.keys()),
body=body,
media_body=MediaFileUpload(options["file"], chunksize=-1, resumable=True),
)
resumable_upload(insert_request, i, next_upload_time)
# This method implements an exponential backoff strategy to resume a
# failed upload.
def resumable_upload(insert_request, i, next_upload_time):
response = None
error = None
retry = 0
while response is None:
try:
print("Uploading file...")
status, response = insert_request.next_chunk()
if response is not None:
if "id" in response:
print("Video id '%s' was successfully uploaded." % response["id"])
## upload success
updateUploadedStatus(i, next_upload_time)
else:
exit("The upload failed with an unexpected response: %s" % response)
except HttpError as e:
if e.resp.status in RETRIABLE_STATUS_CODES:
error = "A retriable HTTP error %d occurred:\n%s" % (
e.resp.status,
e.content,
)
else:
raise
except RETRIABLE_EXCEPTIONS as e:
error = "A retriable error occurred: %s" % e
if error is not None:
print(error)
retry += 1
if retry > MAX_RETRIES:
exit("No longer attempting to retry.")
max_sleep = 2**retry
sleep_seconds = random.random() * max_sleep
print("Sleeping %f seconds and then retrying...") % sleep_seconds
time.sleep(sleep_seconds)
def updateUploadedStatus(currIndex, time):
# opens the json containing video_creation data (used for logic and upload data)
f = open("..\\video_creation\\data\\videos.json")
# loads videos.json into a dictionary
video_data = json.load(f)
video_data[currIndex]["uploaded_at"] = time
video_data[currIndex]["uploaded"] = True
# serialises the dictionary to json
json_obj = json.dumps(video_data, indent=4, default=str)
# writes the file
with open("..\\video_creation\\data\\videos.json", "w") as outfile:
outfile.write(json_obj)
# print(datetime.datetime.now().isoformat())
# print(video_data[i - 1])
# print(video_data[i])
if __name__ == "__main__":
# opens the json containing video_creation data (used for logic and upload data)
f = open("..\\video_creation\\data\\videos.json")
# loads videos.json into a dictionary
video_data = json.load(f)
descriptionBeginning = "r/askReddit | "
descriptionEnd = " 🔔 Hit the bell next to Subscribe so you never miss a video! ❤️ Like and Comment 🧍 Subscribe if you are new on the channel!"
# reddit​ #redditstories​ #askreddit​ #shorts​
titlebBeggining = "r/askReddit: " # 13 characters
options = {}
uploaded = 0
for i, video in enumerate(video_data):
if video["uploaded"] == False:
if uploaded < 2:
prev_video = list(video_data)[i - 1]
############# 2022-10-19 16:39:46.887878
format_data = "%Y-%m-%d %H:%M:%S"
# print("prev_video", prev_video)
# print("video", video)
next_upload = datetime.strptime(
prev_video["uploaded_at"], format_data
) + timedelta(hours=4)
# print(next_upload)
titleEnding = "..."
if len(video["reddit_title"]) < 84:
titleEnding = "?"
# print(len(video["reddit_title"]))
options = {
"file": video["filename"],
"title": titlebBeggining
+ video["reddit_title"][0:84]
+ titleEnding,
"description": descriptionBeginning
+ video["reddit_title"]
+ descriptionEnd,
"category": "22",
"keywords": "reddit,shorts,askReddit",
"privacyStatus": "private",
"publishTime": next_upload.isoformat()
# June 19th, 2022 at 8:20 AM
}
args = argparser.parse_args()
if not os.path.exists(options["file"]):
print(options["file"])
exit("Please specify a valid file using the --file= parameter ")
youtube = get_authenticated_service(
args
) # args must be a new implementation of args object
try:
initialize_upload(youtube, options, i, next_upload)
uploaded += 1
print(options["title"])
video["uploaded_at"] = next_upload.strftime(format_data)
except HttpError as e:
print("An HTTP error %d occurred:\n%s" % (e.resp.status, e.content))

@ -19,7 +19,9 @@ def check_done(
Returns: Returns:
Submission|None: Reddit object in args Submission|None: Reddit object in args
""" """
with open("./video_creation/data/videos.json", "r", encoding="utf-8") as done_vids_raw: with open(
"./video_creation/data/videos.json", "r", encoding="utf-8"
) as done_vids_raw:
done_videos = json.load(done_vids_raw) done_videos = json.load(done_vids_raw)
for video in done_videos: for video in done_videos:
if video["id"] == str(redditobj): if video["id"] == str(redditobj):
@ -33,7 +35,9 @@ def check_done(
return redditobj return redditobj
def save_data(subreddit: str, filename: str, reddit_title: str, reddit_id: str, credit: str): def save_data(
subreddit: str, filename: str, reddit_title: str, reddit_id: str, credit: str
):
"""Saves the videos that have already been generated to a JSON file in video_creation/data/videos.json """Saves the videos that have already been generated to a JSON file in video_creation/data/videos.json
Args: Args:
@ -54,6 +58,7 @@ def save_data(subreddit: str, filename: str, reddit_title: str, reddit_id: str,
"background_credit": credit, "background_credit": credit,
"reddit_title": reddit_title, "reddit_title": reddit_title,
"filename": filename, "filename": filename,
"uploaded": False,
} }
done_vids.append(payload) done_vids.append(payload)
raw_vids.seek(0) raw_vids.seek(0)

Loading…
Cancel
Save