From b132f3c28d6fe4deb8c8793681c8d96096c7368f Mon Sep 17 00:00:00 2001 From: Bradley Bickford Date: Sun, 30 Jun 2024 11:21:39 -0400 Subject: [PATCH] Start of work to bring everything together into one program --- config.json | 10 +++ get_calendar_events.py | 3 +- insert_live_api_broadcast.py | 29 +++++++- reauthorize.py | 36 +++++++++ service_orchestrator.py | 140 +++++++++++++++++++++++++++++++++++ 5 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 config.json create mode 100644 reauthorize.py create mode 100644 service_orchestrator.py diff --git a/config.json b/config.json new file mode 100644 index 0000000..5b0ef38 --- /dev/null +++ b/config.json @@ -0,0 +1,10 @@ +{ + "schedulingCalendarToObserve": "Experimental Calendar", + "streamsToMaintain": [ + { + "name": "Steeple Cam Live Stream", + "description": "Live stream from the Steeple Cam of China Baptist Church", + "streamKeyName": "Steeple Cam Stream" + } + ] +} \ No newline at end of file diff --git a/get_calendar_events.py b/get_calendar_events.py index 440e793..bf1f6a7 100644 --- a/get_calendar_events.py +++ b/get_calendar_events.py @@ -3,6 +3,7 @@ from __future__ import print_function import datetime import os.path import argparse +import time from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials @@ -57,7 +58,7 @@ def get_calendar_events(calendar_service, calendar_id, num_events): calendarId=calendar_id, timeMin=now, maxResults=num_events, - singleEvents=True, + singleEvents=True, orderBy='startTime' ).execute() diff --git a/insert_live_api_broadcast.py b/insert_live_api_broadcast.py index 0526897..3d26ba3 100644 --- a/insert_live_api_broadcast.py +++ b/insert_live_api_broadcast.py @@ -94,7 +94,17 @@ def main(): if len(source) == 0: print("The source name specified does not exist") - sys.exit(1) + sys.exit(1) + + all_categories = list_all_video_categories(youtube_service) + + desired_category_id = [element["id"] for element in all_categories if element["name"] == args.category] + + if len(desired_category_id) == 0: + print("The category name specified does not exist") + sys.exit(1) + + desired_category_id = desired_category_id[0] startTime = datetime.strptime(args.starttime, "%m-%d-%Y %H:%M") actualStartTime = startTime - timedelta(hours=0, minutes=5) @@ -128,6 +138,23 @@ def main(): ).execute() print(json.dumps(response, indent=4)) + print("----------------------------") + print("----------------------------") + print("----------------------------") + print("----------------------------") + + response = youtube_service.videos().update( + part = "id,snippet", + body = { + "id": response["id"], + "snippet": { + "categoryId": desired_category_id, + "title": args.name + } + } + ).execute() + + print(json.dumps(response, indent=4)) if __name__ == '__main__': main() \ No newline at end of file diff --git a/reauthorize.py b/reauthorize.py new file mode 100644 index 0000000..7d3bcf7 --- /dev/null +++ b/reauthorize.py @@ -0,0 +1,36 @@ +from __future__ import print_function + +import os.path + +from google.auth.transport.requests import Request +from google.oauth2.credentials import Credentials +from google_auth_oauthlib.flow import InstalledAppFlow + +SCOPES = [ + 'https://www.googleapis.com/auth/calendar.readonly', + "https://www.googleapis.com/auth/youtube" +] + +def authorize(): + creds = None + + if os.path.exists('token.json'): + creds = Credentials.from_authorized_user_file('token.json', SCOPES) + + if not creds or not creds.valid: + if creds and creds.expired and creds.refresh_token: + creds.refresh(Request()) + else: + flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES) + creds = flow.run_local_server(port=7384) + + with open('token.json', 'w') as token: + token.write(creds.to_json()) + + return creds + +def main(): + creds = authorize() + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/service_orchestrator.py b/service_orchestrator.py new file mode 100644 index 0000000..f16fdb0 --- /dev/null +++ b/service_orchestrator.py @@ -0,0 +1,140 @@ +from __future__ import print_function + +import datetime +import os.path +import argparse +import json + +from google.auth.transport.requests import Request +from google.oauth2.credentials import Credentials +from google_auth_oauthlib.flow import InstalledAppFlow +from googleapiclient.discovery import build + +SCOPES = [ + 'https://www.googleapis.com/auth/calendar.readonly', + "https://www.googleapis.com/auth/youtube" +] + +def authorize(): + creds = None + + if os.path.exists('token.json'): + creds = Credentials.from_authorized_user_file('token.json', SCOPES) + + if not creds or not creds.valid: + if creds and creds.expired and creds.refresh_token: + creds.refresh(Request()) + else: + flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES) + creds = flow.run_local_server(port=7384) + + with open('token.json', 'w') as token: + token.write(creds.to_json()) + + return creds + +def construct_calendar_service(creds): + return build('calendar', 'v3', credentials=creds) + +def list_all_calendars(calendar_service): + page_token = None + list_of_entries = [] + + while True: + calendar_list = calendar_service.calendarList().list(pageToken=page_token).execute() + + list_of_entries.extend(calendar_list['items']) + + page_token = calendar_list.get('nextPageToken') + + if not page_token: + break + + return list_of_entries + +def get_calendar_events(calendar_service, calendar_id, num_events): + now = datetime.datetime.utcnow().isoformat() + "Z" + + events_result = calendar_service.events().list( + calendarId=calendar_id, + timeMin=now, + maxResults=num_events, + singleEvents=True, + orderBy='startTime' + ).execute() + + events = events_result.get('items', []) + + return events + +def construct_youtube_service(creds): + return build('youtube', 'v3', credentials=creds) + +def list_all_stream_sources(youtube_service): + page_token = None + list_of_entries = [] + + while True: + stream_list = youtube_service.liveStreams().list( + part="snippet", + mine=True, + pageToken=page_token + ).execute() + + list_of_entries.extend(stream_list["items"]) + + page_token = stream_list.get("nextPageToken") + + if not page_token: + break + + return list_of_entries + +def list_all_video_categories(youtube_service): + category_list = youtube_service.videoCategories().list( + part="snippet", + regionCode="US" + ).execute() + + return [ + { + "name": element["snippet"]["title"], + "id": element["id"] + } + for element in category_list["items"] if element["snippet"]["assignable"] + ] + +def list_all_live_broadcasts(youtube_service, broadcastStatus): + page_token = None + list_of_entries = [] + + while True: + broadcast_list = youtube_service.liveBroadcasts().list( + part="snippet", + broadcastStatus=broadcastStatus, + pageToken=page_token + ).execute() + + list_of_entries.extend(broadcast_list["items"]) + + page_token = broadcast_list.get("nextPageToken") + + if not page_token: + break + + return list_of_entries + +def main(): + with open("config.json", "r") as config_file: + config_json = json.loads(config_file.read()) + + creds = authorize() + + calendar_service = construct_calendar_service(creds) + youtube_service = construct_youtube_service(creds) + + + + + + \ No newline at end of file