diff --git a/content/.obsidian/workspace.json b/content/.obsidian/workspace.json index e9442cc..1215109 100644 --- a/content/.obsidian/workspace.json +++ b/content/.obsidian/workspace.json @@ -26,12 +26,15 @@ "id": "b6de1b6650c09ff3", "type": "leaf", "state": { - "type": "pdf", + "type": "markdown", "state": { - "file": "Anatomi & Histologi 2/1 Öga anatomi/Slides.pdf.pdf" + "file": "Anatomi & Histologi 2/Schema.md", + "mode": "source", + "source": false, + "backlinks": false }, - "icon": "lucide-file-text", - "title": "Slides.pdf" + "icon": "lucide-file", + "title": "Schema" } } ], @@ -206,6 +209,8 @@ }, "active": "b6de1b6650c09ff3", "lastOpenFiles": [ + "Anatomi & Histologi 2/Statistik.md", + "Anatomi & Histologi 2/1 Öga anatomi/Slides.pdf.pdf", "Anatomi & Histologi 2/1 Öga anatomi/Slides.md", "Anatomi & Histologi 2/1 Öga anatomi/Målbeskrivning.md", "Anatomi & Histologi 2/1 Öga anatomi/Instuderingsfrågor.md", @@ -221,7 +226,6 @@ "Anatomi & Histologi 2/Gamla tentor/2024-01-10/21.md", "Anatomi & Histologi 2/Gamla tentor/2025-01-15/17.md", "Anatomi & Histologi 2/Gamla tentor/2025-02-08/10.md", - "Anatomi & Histologi 2/1 Öga anatomi/Slides.pdf.pdf", "Anatomi & Histologi 2/1 Öga anatomi/Studietips.md", "Anatomi & Histologi 2/Demokompendium.md", "Anatomi & Histologi 2/Gamla tentor/2024-01-10/20.md", @@ -233,12 +237,10 @@ "Anatomi & Histologi 2/1 Öga anatomi/Oculus.md.md", "Anatomi & Histologi 2/2 Öra anatomi/Slides.pdf.pdf", "Anatomi & Histologi 2/2 Öra anatomi/Instuderingsfrågor.md", - "Anatomi & Histologi 2/Statistik.md", "Anatomi & Histologi 2/Gamla tentor/2022-01-15/20.md", "Anatomi & Histologi 2/Gamla tentor/2022-06-01/21.md", "Anatomi & Histologi 2/Gamla tentor/2025-06-03/26.md", "Anatomi & Histologi 2/Gamla tentor/2025-08-08/10.md", - "Anatomi & Histologi 2/Gamla tentor/2025-08-08/8.md", "Anatomi & Histologi 2/Gamla tentor/2023-01-11/!2023-01-11-0044-PRX.pdf", "Anatomi & Histologi 2/Gamla tentor/2022-06-01/!2022-06-01-0101-MGY.pdf", "Anatomi & Histologi 2/Gamla tentor/2022-01-15/!2022-01-15-0032-BWD.pdf", diff --git a/content/Anatomi & Histologi 2/Schema.md b/content/Anatomi & Histologi 2/Schema.md index c8d824c..f77599d 100644 --- a/content/Anatomi & Histologi 2/Schema.md +++ b/content/Anatomi & Histologi 2/Schema.md @@ -20,8 +20,8 @@ | 2026-01-14 | 10:00–12:00 2h | Frågestund inför skriftliga tentamen | [Zoom](https://app.zoom.us/wc/join/62993534868?fromPWA=1&pwd=dmVuVXc0NXRoRnFqdXR1dEVSc2Urdz09) | Anne Uv, Helena Carén, Magnus Rudenholm | | 2026-01-15 | 08:00–16:00 8h | Förberedelse vetenskaplig artikel | Distansundervisning/Online Självstudier | | | 2026-01-15 | 19:00–21:00 2h | [Skriftig tentamen anatomi/histologi del 2](https://canvas.gu.se/courses/91586/pages/f-tentamen?module_item_id=1418976) | [Andra Långgatan 19](https://www.google.com/maps/place/Andra+L%C3%A5nggatan+19,+413+28+G%C3%B6teborg/@57.6992557,11.9457214,478m/data=!3m2!1e3!4b1!4m6!3m5!1s0x464ff3415f98b55d:0x652d07c9960bd44b!8m2!3d57.6992557!4d11.9482963!16s%2Fg%2F11c2gks9gc?entry=ttu&g_ep=EgoyMDI1MTIwOS4wIKXMDSoKLDEwMDc5MjA3M0gBUAM%3D) | | -| 2026-01-16 | 09:15–12:00 3h | TBL vetenskaplig artikel: B1-B10 - Obligatorisk | 2045 T Bjurström | Joan Camuñas, Abhishek Niroula | -| 2026-01-16 | 13:15–16:00 3h | TBL vetenskaplig artikel: A1-A10 - Obligatorisk | 2045 T Bjurström | Joan Camuñas, Abhishek Niroula | +| 2026-01-16 | 09:15–12:00 3h | TBL vetenskaplig artikel: B1-B10 - **Obligatorisk** | 2045 T Bjurström | Joan Camuñas, Abhishek Niroula | +| 2026-01-16 | 13:15–16:00 3h | TBL vetenskaplig artikel: A1-A10 - **Obligatorisk** | 2045 T Bjurström | Joan Camuñas, Abhishek Niroula | | 2026-01-31 | 08:30–12:30 4h | Digital omtentamen - biokemi med skannat papper | Första Långgatan 16 | | | 2026-02-07 | 08:30–10:30 2h | Digital omtentamen anatomi/histologi del 2 | [Andra Långgatan 19](https://www.google.com/maps/place/Andra+L%C3%A5nggatan+19,+413+28+G%C3%B6teborg/@57.6992557,11.9457214,478m/data=!3m2!1e3!4b1!4m6!3m5!1s0x464ff3415f98b55d:0x652d07c9960bd44b!8m2!3d57.6992557!4d11.9482963!16s%2Fg%2F11c2gks9gc?entry=ttu&g_ep=EgoyMDI1MTIwOS4wIKXMDSoKLDEwMDc5MjA3M0gBUAM%3D) | | diff --git a/quiz/templates/partials/quiz_question.html b/quiz/templates/partials/quiz_question.html index bae624b..527df1d 100644 --- a/quiz/templates/partials/quiz_question.html +++ b/quiz/templates/partials/quiz_question.html @@ -5,12 +5,13 @@
{% for option in question.options.all %} -
- + {{ option.letter }} {{ option.text }} -
+ {% endfor %}
diff --git a/wip/download-subs.py b/wip/download-subs.py index ac436d6..01b3265 100644 --- a/wip/download-subs.py +++ b/wip/download-subs.py @@ -1,80 +1,161 @@ #!/usr/bin/env python3 - +""" +Download Swedish auto-generated subtitles from YouTube videos using yt-dlp. +""" import subprocess import sys -import os -import glob - -def get_clipboard(): - result = subprocess.run(['pbpaste'], capture_output=True, text=True) - return result.stdout.strip() - -def set_clipboard(text): - subprocess.run(['pbcopy'], input=text, text=True) +import platform def get_url_from_dialog(): + """ + Show a macOS dialog to get the YouTube URL. + Uses osascript (AppleScript) - similar to zenity on Linux or prompt() in HTML. + + Returns: + str: The URL entered by the user, or None if cancelled + """ + if platform.system() != 'Darwin': + print("Error: Dialog is only supported on macOS", file=sys.stderr) + return None + + # AppleScript to show a text input dialog applescript = ''' display dialog "Enter YouTube URL:" default answer "" with title "Download Swedish Subtitles" buttons {"Cancel", "OK"} default button "OK" set userInput to text returned of result return userInput ''' + try: - result = subprocess.run(['osascript', '-e', applescript], capture_output=True, text=True, check=True) + result = subprocess.run( + ['osascript', '-e', applescript], + capture_output=True, + text=True, + check=True + ) return result.stdout.strip() except subprocess.CalledProcessError: + # User cancelled or error occurred return None def clean_subtitles(srt_content): + """ + Clean SRT subtitle content by removing timestamps, unwrapping lines, and removing duplicates. + + Args: + srt_content: Raw SRT subtitle content + + Returns: + Cleaned text content with timestamps removed and duplicates filtered + """ lines = srt_content.strip().split('\n') text_lines = [] seen_lines = set() for line in lines: line = line.strip() - if not line or line.isdigit() or '-->' in line: + + # Skip empty lines, sequence numbers, and timestamp lines + if not line: continue + if line.isdigit(): + continue + if '-->' in line: + continue + + # Skip duplicate lines (auto-generated subtitles often repeat) if line in seen_lines: continue + seen_lines.add(line) text_lines.append(line) + # Join all lines with spaces to unwrap return ' '.join(text_lines) def download_subtitles(url): - cmd = [ - 'yt-dlp', - '--write-auto-sub', - '--sub-lang', 'sv', - '--skip-download', - '--convert-subs', 'srt', - '-o', '%(id)s.%(ext)s', - url - ] + """ + Download auto-generated Swedish subtitles from a YouTube video or playlist. - subprocess.run(cmd, capture_output=True, text=True, check=True) + Args: + url: YouTube video or playlist URL + """ + import os + import glob - srt_files = glob.glob('*.sv.srt') + try: + # Get video ID to construct subtitle filename + # Download subtitles to current directory, then read and delete + cmd = [ + 'yt-dlp', + '--write-auto-sub', + '--sub-lang', 'sv', + '--skip-download', + '--convert-subs', 'srt', + '-o', '%(id)s.%(ext)s', + url + ] - if srt_files: - subtitle_file = srt_files[0] - with open(subtitle_file, 'r', encoding='utf-8') as f: - raw_content = f.read() - cleaned_content = clean_subtitles(raw_content) - os.remove(subtitle_file) - return cleaned_content + print(f"Downloading subtitles...", file=sys.stderr) + result = subprocess.run(cmd, capture_output=True, text=True, check=True) - sys.exit(1) + # Find the generated .srt file + srt_files = glob.glob('*.sv.srt') -if __name__ == '__main__': - url = get_clipboard() + if srt_files: + subtitle_file = srt_files[0] + print(f"Reading subtitles from: {subtitle_file}", file=sys.stderr) - if not url or 'youtube.com' not in url and 'youtu.be' not in url: - url = get_url_from_dialog() - if not url: + # Read, clean and print the subtitle file + with open(subtitle_file, 'r', encoding='utf-8') as f: + raw_content = f.read() + cleaned_content = clean_subtitles(raw_content) + print(cleaned_content) + + # Clean up the subtitle file + os.remove(subtitle_file) + print(f"Cleaned up: {subtitle_file}", file=sys.stderr) + else: + print("Error: No Swedish subtitles found for this video", file=sys.stderr) + print("Available subtitle languages might not include Swedish auto-generated", file=sys.stderr) sys.exit(1) - subtitles = download_subtitles(url) - set_clipboard(subtitles) + except subprocess.CalledProcessError as e: + print(f"Error running yt-dlp: {e}", file=sys.stderr) + if e.stderr: + print(e.stderr, file=sys.stderr) + sys.exit(1) + except FileNotFoundError: + print("Error: yt-dlp not found. Please install it first:", file=sys.stderr) + print(" pip install yt-dlp", file=sys.stderr) + sys.exit(1) + except Exception as e: + print(f"Unexpected error: {e}", file=sys.stderr) + import traceback + traceback.print_exc() + sys.exit(1) + +if __name__ == '__main__': + url = None + + # Get URL from command line argument or dialog + if len(sys.argv) == 2: + url = sys.argv[1] + elif len(sys.argv) == 1: + # No argument provided - show dialog (macOS only) + if platform.system() == 'Darwin': + url = get_url_from_dialog() + if not url: + print("No URL provided. Exiting.", file=sys.stderr) + sys.exit(1) + else: + print("Usage: python download-subs.py ", file=sys.stderr) + sys.exit(1) + else: + print("Usage: python download-subs.py [youtube_url]", file=sys.stderr) + print(" If no URL is provided on macOS, a dialog will appear.", file=sys.stderr) + sys.exit(1) + + download_subtitles(url)