diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6654ef2 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python Debugger: Flask", + "type": "debugpy", + "request": "launch", + "module": "flask", + "env": { + "FLASK_APP": "app.py", + "FLASK_DEBUG": "1" + }, + "args": [ + "run", + "--debug", + "--no-reload" + ], + "jinja": true, + "autoStartBrowser": false + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..8ec53f6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "html.autoClosingTags": true, + "html.format.enable": true, + "html.autoCreateQuotes": true +} \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..5cb8c16 --- /dev/null +++ b/app.py @@ -0,0 +1,31 @@ +from flask import Flask, render_template, request +from main import get_auto_transcript, get_video_id, create_and_stream + +app = Flask(__name__, static_folder="website/static", template_folder="website") + +@app.route('/') +def home(): + return render_template('index.html') + +@app.route('/process_url', methods=['POST']) +def process_url(): + url = request.form['url'] + + # Extract the video ID from the URL + video_id = get_video_id(url) # Modify this function to accept the URL + if not video_id: + return "Couldn't parse video ID from URL. (Are you sure you entered a valid YouTube.com or YouTu.be URL?)" + + # Get the transcript for that video ID + transcript = get_auto_transcript(video_id) + if (not transcript): + return "Successfully parsed video ID from URL, however the ID was either invalid, the transcript was disabled by the video owner, or some other error was raised because of YouTube." + + # Process the transcript and stream the result. + stream = create_and_stream(transcript) + + # Return a response + return stream # Add more detailed output if needed + +if __name__ == '__main__': # Change this line to properly check for main + app.run(debug=True) \ No newline at end of file diff --git a/main.py b/main.py index 1e8a460..3746838 100644 --- a/main.py +++ b/main.py @@ -3,6 +3,7 @@ import re # Youtube Transcript stuff import +import youtube_transcript_api._errors from youtube_transcript_api import YouTubeTranscriptApi from youtube_transcript_api.formatters import TextFormatter @@ -40,6 +41,7 @@ class EventHandler(AssistantEventHandler): for output in delta.code_interpreter.outputs: if output.type == "logs": print(f"\n{output.logs}", flush=True) + # Setting up OpenAI Client with API Key api_key =os.getenv("OPENAI_API_KEY") @@ -65,44 +67,42 @@ def create_and_stream(transcript): event_handler=EventHandler() ) as stream: stream.until_done() - return + messages = stream.get_final_messages() + return messages[0].content[0].text.value -def get_video_id(): - # local consts +def get_video_id(url): youtu_be = r'(?<=youtu.be/)([A-Za-z0-9_-]{11})' youtube_com = r'(?<=youtube\.com\/watch\?v=)([A-Za-z0-9_-]{11})' - # local vars - valid_id = False - # Get URL from user - while(not valid_id): - user_url = input("Enter the URL of the YouTube video: ") - id = re.search(youtu_be, user_url) - - if (not id): - id = re.search(youtube_com, user_url) - - if (not id): - print("Error: Couldn't parse video ID from URL, please make sure you are pasting a full \"youtube.com\" or \"youtu.be url\"\n") - else: - valid_id = True - - id = id.group(1) - print(id) - return id + id = re.search(youtu_be, url) + if not id: + id = re.search(youtube_com, url) + + if not id: + print("Couldn't parse video ID from URL") + return None + + return id.group(1) # Takes the transcript and formats it in basic text before writing it to auto-transcript.txt def get_auto_transcript(video_id): - transcript = YouTubeTranscriptApi.get_transcript(video_id, languages=['en'], proxies=None, cookies=None, preserve_formatting=False) - formatter = TextFormatter + trans_api_errors = youtube_transcript_api._errors + try: + transcript = YouTubeTranscriptApi.get_transcript(video_id, languages=['en'], proxies=None, cookies=None, preserve_formatting=False) + except trans_api_errors.TranscriptsDisabled: + return None + + formatter = TextFormatter() # Ensure that you create an instance of TextFormatter - txt_transcript = formatter.format_transcript(self=any, transcript=transcript) - print(txt_transcript) + txt_transcript = formatter.format_transcript(transcript) return txt_transcript + # Stores the video id imputted by the user +""" video_id = get_video_id() transcript = get_auto_transcript(video_id) -create_and_stream(transcript) \ No newline at end of file +create_and_stream(transcript) +""" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..302c6a9 Binary files /dev/null and b/requirements.txt differ diff --git a/website/app.py b/website/app.py deleted file mode 100644 index e69de29..0000000 diff --git a/website/index.html b/website/index.html new file mode 100644 index 0000000..24cc215 --- /dev/null +++ b/website/index.html @@ -0,0 +1,30 @@ + + + + + + + + + Screw You Bardo + + + + + + + + + +
+

Response will appear here.

+
+ + +
+ + +
+ + + \ No newline at end of file diff --git a/website/static/font-files/nimbus-sans-d-ot-light.woff b/website/static/font-files/nimbus-sans-d-ot-light.woff new file mode 100644 index 0000000..6ad134e Binary files /dev/null and b/website/static/font-files/nimbus-sans-d-ot-light.woff differ diff --git a/website/static/font-files/nimbus-sans-d-ot-light.woff2 b/website/static/font-files/nimbus-sans-d-ot-light.woff2 new file mode 100644 index 0000000..cdfbc6d Binary files /dev/null and b/website/static/font-files/nimbus-sans-d-ot-light.woff2 differ diff --git a/website/static/script.js b/website/static/script.js new file mode 100644 index 0000000..474c14c --- /dev/null +++ b/website/static/script.js @@ -0,0 +1,31 @@ + +document.addEventListener("DOMContentLoaded", (event) => { + document.getElementById('submit').addEventListener('click', function() { + var url = document.getElementById('url_box').value; + const response_area = document.getElementById('response-area'); + + if (!url) { + response_area.innerText = 'Please enter a URL.'; + return; + } + else{ + response_area.innerText = "Sending URL and retriving transcript." + } + + fetch('/process_url', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: new URLSearchParams({ url: url }) + }) + .then(response => response.text()) + .then(data => { + response_area.innerText = data; + }) + .catch(error => { + console.error('Error:', error); + response_area.innerText = 'An error occurred. Please try again.'; + }); + }); +}); diff --git a/website/static/style.css b/website/static/style.css index e69de29..afc363b 100644 --- a/website/static/style.css +++ b/website/static/style.css @@ -0,0 +1,77 @@ + + +@font-face { + font-family: 'nimbus_sans_d_otlight'; + src: url('font-files/nimbus-sans-d-ot-light.woff2') format('woff2'), + url('font-files/nimbus-sans-d-ot-light.woff') format('woff'); + font-weight: normal; + font-style: normal; +} + +* { + font-family: 'nimbus_sans_d_otlight'; + color: white; +} + +body { + display: flex; + flex-direction: column; + width: 100%; + max-width: 100vw; + height: 100%; + min-height: 100vh; + max-height: 100vh; + margin: 0; + background-color: rgb(31, 31, 31); +} + +body .content { + display: flex; + flex-direction: column; + align-self: center; + width: 75%; + max-width: 65vw; + height: 100%; + min-height: 100vh; + max-height: 100vh; +} + +#response-area { + display: block; + height: 90%; + min-height: 90vh; + overflow: auto; + flex-wrap: wrap; + align-content: flex-end; +} + +.form_box { + display: flex; + width: 100%; + justify-content: space-between; + align-content: space-around; +} + +#url_box { + display: flex; + height: 5%; + min-height: 5vh; + width: 90%; + min-width: 80vh; + background-color: rgb(31, 31, 31); +} + +#submit { + display: flex; + width: 5%; + min-width: 3vw; + background-color: rgb(49, 49, 49); +} +#submit:hover { + cursor: pointer; + background-color: rgb(31, 31, 31); +} + +input { + border-radius: 15px; +} diff --git a/website/templates/index.html b/website/templates/index.html deleted file mode 100644 index e69de29..0000000