mirror of
				https://github.com/ae-utbm/sith.git
				synced 2025-11-04 11:03:04 +00:00 
			
		
		
		
	Return calendars as real files
This commit is contained in:
		
							
								
								
									
										50
									
								
								com/api.py
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								com/api.py
									
									
									
									
									
								
							@@ -1,7 +1,8 @@
 | 
				
			|||||||
from datetime import timedelta
 | 
					from datetime import datetime, timedelta
 | 
				
			||||||
 | 
					from pathlib import Path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import urllib3
 | 
					import urllib3
 | 
				
			||||||
from django.core.cache import cache
 | 
					from django.conf import settings
 | 
				
			||||||
from django.http import HttpResponse
 | 
					from django.http import HttpResponse
 | 
				
			||||||
from django.urls import reverse
 | 
					from django.urls import reverse
 | 
				
			||||||
from django.utils import timezone
 | 
					from django.utils import timezone
 | 
				
			||||||
@@ -9,30 +10,37 @@ from ics import Calendar, Event
 | 
				
			|||||||
from ninja_extra import ControllerBase, api_controller, route
 | 
					from ninja_extra import ControllerBase, api_controller, route
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from com.models import NewsDate
 | 
					from com.models import NewsDate
 | 
				
			||||||
 | 
					from core.views.files import send_raw_file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@api_controller("/calendar")
 | 
					@api_controller("/calendar")
 | 
				
			||||||
class CalendarController(ControllerBase):
 | 
					class CalendarController(ControllerBase):
 | 
				
			||||||
 | 
					    CACHE_FOLDER: Path = settings.MEDIA_ROOT / "com" / "calendars"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @route.get("/external.ics")
 | 
					    @route.get("/external.ics")
 | 
				
			||||||
    def calendar_external(self):
 | 
					    def calendar_external(self):
 | 
				
			||||||
        CACHE_KEY = "external_calendar"
 | 
					        file = self.CACHE_FOLDER / "external.ics"
 | 
				
			||||||
        if cached := cache.get(CACHE_KEY):
 | 
					        # Return cached file if updated less than an our ago
 | 
				
			||||||
            return HttpResponse(
 | 
					        if (
 | 
				
			||||||
                cached,
 | 
					            file.exists()
 | 
				
			||||||
                content_type="text/calendar",
 | 
					            and timezone.make_aware(datetime.fromtimestamp(file.stat().st_mtime))
 | 
				
			||||||
                status=200,
 | 
					            + timedelta(hours=1)
 | 
				
			||||||
            )
 | 
					            > timezone.now()
 | 
				
			||||||
 | 
					        ):
 | 
				
			||||||
 | 
					            return send_raw_file(file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        calendar = urllib3.request(
 | 
					        calendar = urllib3.request(
 | 
				
			||||||
            "GET",
 | 
					            "GET",
 | 
				
			||||||
            "https://calendar.google.com/calendar/ical/ae.utbm%40gmail.com/public/basic.ics",
 | 
					            "https://calendar.google.com/calendar/ical/ae.utbm%40gmail.com/public/basic.ics",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        if calendar.status == 200:
 | 
					        if calendar.status != 200:
 | 
				
			||||||
            cache.set(CACHE_KEY, calendar.data, 3600)  # Cache for one hour
 | 
					            return HttpResponse(status=calendar.status)
 | 
				
			||||||
        return HttpResponse(
 | 
					
 | 
				
			||||||
            calendar.data,
 | 
					        self.CACHE_FOLDER.mkdir(parents=True, exist_ok=True)
 | 
				
			||||||
            content_type="text/calendar",
 | 
					        with open(file, "wb") as f:
 | 
				
			||||||
            status=calendar.status,
 | 
					            _ = f.write(calendar.data)
 | 
				
			||||||
        )
 | 
					
 | 
				
			||||||
 | 
					        return send_raw_file(file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @route.get("/internal.ics")
 | 
					    @route.get("/internal.ics")
 | 
				
			||||||
    def calendar_internal(self):
 | 
					    def calendar_internal(self):
 | 
				
			||||||
@@ -50,7 +58,9 @@ class CalendarController(ControllerBase):
 | 
				
			|||||||
            )
 | 
					            )
 | 
				
			||||||
            calendar.events.add(event)
 | 
					            calendar.events.add(event)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return HttpResponse(
 | 
					        # Create a file so we can offload the download to the reverse proxy if available
 | 
				
			||||||
            calendar.serialize().encode("utf-8"),
 | 
					        file = self.CACHE_FOLDER / "internal.ics"
 | 
				
			||||||
            content_type="text/calendar",
 | 
					        self.CACHE_FOLDER.mkdir(parents=True, exist_ok=True)
 | 
				
			||||||
        )
 | 
					        with open(file, "wb") as f:
 | 
				
			||||||
 | 
					            _ = f.write(calendar.serialize().encode("utf-8"))
 | 
				
			||||||
 | 
					        return send_raw_file(file)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user