Select Git revision
-
Andrej Ramašeuski authoredAndrej Ramašeuski authored
icaldownload.py 2.86 KiB
"""
Downloads an iCal url or reads an iCal file.
"""
import logging
from httplib2 import Http
def apple_data_fix(content):
"""
Fix Apple tzdata bug.
:param content: content to fix
:return: fixed content
"""
return content.replace("TZOFFSETFROM:+5328", "TZOFFSETFROM:+0053")
def apple_url_fix(url):
"""
Fix Apple URL.
:param url: URL to fix
:return: fixed URL
"""
if url.startswith("webcal://"):
url = url.replace("webcal://", "http://", 1)
return url
class ICalDownload:
"""
Downloads or reads and decodes iCal sources.
"""
def __init__(self, http=None, encoding="utf-8"):
# Get logger
logger = logging.getLogger()
# default http connection to use
if http is None:
try:
http = Http(".cache")
except (PermissionError, OSError) as e:
# Cache disabled if no write permission in working directory
logger.warning(
(
"Caching is disabled due to a read-only working directory: {}"
).format(e)
)
http = Http()
self.http = http
self.encoding = encoding
def data_from_url(self, url, apple_fix=False):
"""
Download iCal data from URL.
:param url: URL to download
:param apple_fix: fix Apple bugs (protocol type and tzdata in iCal)
:return: decoded (and fixed) iCal data
"""
if apple_fix:
url = apple_url_fix(url)
_, content = self.http.request(url)
if not content:
raise ConnectionError("Could not get data from %s!" % url)
return self.decode(content, apple_fix=apple_fix)
def data_from_file(self, file, apple_fix=False):
"""
Read iCal data from file.
:param file: file to read
:param apple_fix: fix wrong Apple tzdata in iCal
:return: decoded (and fixed) iCal data
"""
with open(file, mode="rb") as f:
content = f.read()
if not content:
raise IOError("File %s is not readable or is empty!" % file)
return self.decode(content, apple_fix=apple_fix)
def data_from_string(self, string_content, apple_fix=False):
if not string_content:
raise IOError("String content is not readable or is empty!")
return self.decode(string_content, apple_fix=apple_fix)
def decode(self, content, apple_fix=False):
"""
Decode content using the set charset.
:param content: content do decode
:param apple_fix: fix Apple txdata bug
:return: decoded (and fixed) content
"""
content = content.decode(self.encoding)
content = content.replace("\r", "")
if apple_fix:
content = apple_data_fix(content)
return content