[docs]defcheck_emerg():"""Fetch from FCPS emergency announcement pages. URLs defined in settings.FCPS_EMERGENCY_PAGE Request timeout defined in settings.FCPS_EMERGENCY_TIMEOUT """fcps_page=settings.FCPS_EMERGENCY_PAGEannouncements=[]ifsettings.EMERGENCY_MESSAGE:returnTrue,settings.EMERGENCY_MESSAGEifnotfcps_page:returnNone,Nonetimeout=settings.EMERGENCY_TIMEOUTtry:r=requests.get(f"{fcps_page}?{int(time.time()//60)}",timeout=timeout)exceptrequests.exceptions.Timeout:returnFalse,Noneres=r.text# Keep this list up to date with whatever wording FCPS decides to use each time...bad_strings=["There are no emergency announcements at this time","There are no emergency messages at this time","There are no emeregency annoncements at this time",# codespell: ignore"There are no major announcements at this time.","There are no major emergency announcements at this time.","There are no emergencies at this time.","Site under maintenance",# We don't want to get people's attention like this just to tell them that fcps.edu is under maintenance"502 Bad Gateway",]status=Trueforbinbad_strings:ifbinres:status=Falsebreaksoup=BeautifulSoup(res,"xml")ifsoup.titleandstatus:title=soup.title.textbody=soup.find("content").texttitle=safe_fcps_emerg_html(title,fcps_page)body=safe_fcps_emerg_html(body,fcps_page)announcements.append({"title":f"<a target='_blank' href=\"{get_domain_name(fcps_page)}\">{title}</a>","body":body})message="".join([f"<h3><i class='fas fa-exclamation-triangle'></i> {announcement['title']}</h3><hr />{announcement['body']}\n"forannouncementinannouncements])returnstatus,message
[docs]defget_emerg_result(*,custom_logger=None):"""Run the fetch command from FCPS."""ifcustom_loggerisNone:custom_logger=loggerstatus,message=check_emerg()custom_logger.debug("Fetched emergency info from FCPS")return{"status":status,"message":message}
[docs]defget_emerg():"""Get the cached FCPS emergency page, or check it again. Timeout defined in settings.CACHE_AGE["emerg"] """key=f"emerg:{timezone.localdate()}"cached=cache.get(key)ifcached:returncachedelse:# We have a Celery task updating the cache periodically, so this normally won't run.# However, if Celery stops working, we still want it to update, so we fall back on# updating it here.result=get_emerg_result()cache.set(key,result,timeout=settings.CACHE_AGE["emerg"])returnresult
[docs]defupdate_emerg_cache(*,custom_logger=None)->None:"""Updates the cached contents of FCPS emergency page. This forces a cache update, regardless of whether or not the cache has expired. However, it does set the cache entry to expire in ``settings.CACHE_AGE["emerg"]`` seconds. Args: custom_logger: A custom ``logging.Logger`` instance to use for log messages relating to the cache update. """key=f"emerg:{timezone.localdate()}"result=get_emerg_result(custom_logger=custom_logger)cache.set(key,result,timeout=settings.CACHE_AGE["emerg"])
[docs]defget_csl_status()->Tuple[str,bool]:"""Get the cached status of the TJCSL status page. Returns: Tuple with a string consisting of the aggregate status of the TJ computer systems lab and a bool indicating whether the status cache was updated The string of the tuple will be one of the following: "error" (parse error), "operational", "downtime", "degraded", "maintenance" """status=cache.get("emerg:csl_status")updated=Falseifnotstatus:response=requests.get(settings.CSL_STATUS_PAGE)ifresponse.status_code!=200:status="error"logger.error("Could not fetch status page")else:try:status=response.json()["data"]["attributes"]["aggregate_state"]updated=TrueexceptKeyErrorase:status="error"logger.error("Unexpected status page JSON format. %s",e)cache.set("emerg:csl_status",status,settings.CACHE_AGE["csl_status"])returnstatus,updated