sharing/bday/template: implementation of placeholder replacement
This commit is contained in:
@@ -136,9 +136,9 @@ class ApplicationPartGet(ApplicationBase):
|
||||
if share and share['Conversion'] == "bday":
|
||||
if isinstance(item, storage.BaseCollection):
|
||||
# convert VCF to ICS
|
||||
answer = item.serialize(vcf_to_ics=True)
|
||||
answer = item.serialize(vcf_to_ics=True, ShareActions=share['Actions'])
|
||||
else:
|
||||
item_converted = item.convert_vcf_to_ics()
|
||||
item_converted = item.convert_vcf_to_ics(ShareActions=share['Actions'])
|
||||
if item_converted is not None:
|
||||
answer = item_converted.serialize()
|
||||
else:
|
||||
|
||||
@@ -504,7 +504,37 @@ class Item:
|
||||
self.component_name
|
||||
self._vobject_item = orig_vobject_item
|
||||
|
||||
def convert_vcf_to_ics(self) -> Union["Item", None]:
|
||||
def replace_placeholders(self, text: str, placeholder_mapping: dict) -> str:
|
||||
for placeholder in placeholder_mapping:
|
||||
text = text.replace(placeholder, placeholder_mapping[placeholder])
|
||||
|
||||
# resolve {..|..} recursive
|
||||
pattern = re.compile('(.*)({)([^|]+)\\|(.+)(})(.*)')
|
||||
logger.trace("item/convert_vcf_to_ics: resolve {..|..} starting with: %r", text)
|
||||
while True:
|
||||
match = pattern.match(text)
|
||||
if not match:
|
||||
# nothing more todo
|
||||
break
|
||||
else:
|
||||
if match[3].startswith('!') and match[3].endswith('!'):
|
||||
# not resolved variable
|
||||
if '|' in match[4]:
|
||||
# further recursion required
|
||||
text = match[1] + match[2] + match[4] + match[5] + match[6]
|
||||
logger.trace("item/convert_vcf_to_ics: resolve {..|..} match/replace/continue result: %r", text)
|
||||
else:
|
||||
text = match[1] + match[4] + match[6]
|
||||
logger.trace("item/convert_vcf_to_ics: resolve {..|..} match/replace/final result: %r", text)
|
||||
break
|
||||
else:
|
||||
# resolved variable
|
||||
text = match[1] + match[3] + match[6]
|
||||
logger.trace("item/convert_vcf_to_ics: resolve {..|..} match/replace(resolved) result: %r", text)
|
||||
return text
|
||||
|
||||
def convert_vcf_to_ics(self, ShareActions: dict = {}) -> Union["Item", None]:
|
||||
logger.trace("item/convert_vcf_to_ics: ShareActions: %r", ShareActions)
|
||||
logger.trace("item/convert_vcf_to_ics: convert VCF to ICS (href): %r", self.href)
|
||||
logger.trace("item/convert_vcf_to_ics: convert VCF to ICS (vobject): %r", self.vobject_item)
|
||||
if self.vobject_item.name != "VCARD":
|
||||
@@ -529,23 +559,55 @@ class Item:
|
||||
else:
|
||||
pass
|
||||
|
||||
placeholder_mapping: dict = {}
|
||||
|
||||
bdayS = match[1] + match[2] + match[3]
|
||||
bdaySdesc = match[1] + "-" + match[2] + "-" + match[3]
|
||||
bdayY = int(match[1])
|
||||
bdayM = int(match[2])
|
||||
bdayD = int(match[3])
|
||||
|
||||
placeholder_mapping['{year}'] = match[1]
|
||||
placeholder_mapping['{month}'] = match[2]
|
||||
placeholder_mapping['{day}'] = match[3]
|
||||
|
||||
# create ICS
|
||||
if hasattr(self.vobject_item, "fn"):
|
||||
name = self.vobject_item.fn.value
|
||||
elif hasattr(self.vobject_item, "n"):
|
||||
name = self.vobject_item.n.value
|
||||
name = self.vobject_item.n.value.family + " " + self.vobject_item.n.value.given
|
||||
elif hasattr(self.vobject_item, "nickname"):
|
||||
name = self.vobject_item.nickname.value
|
||||
else:
|
||||
logger.trace("item/convert_vcf_to_ics: has bday but neither FN or N or NICKNAME (skip): %r", self.href)
|
||||
return None
|
||||
|
||||
if hasattr(self.vobject_item, "nickname") and self.vobject_item.nickname.value != "":
|
||||
placeholder_mapping['{nickname}'] = self.vobject_item.nickname.value
|
||||
else:
|
||||
placeholder_mapping['{nickname}'] = '!nickname!'
|
||||
|
||||
if hasattr(self.vobject_item, "fn") and self.vobject_item.fn.value != "":
|
||||
placeholder_mapping['{fn}'] = self.vobject_item.fn.value
|
||||
else:
|
||||
placeholder_mapping['{nickname}'] = '!fn!'
|
||||
|
||||
# rfc6350#6.2 FamilyName;GivenName;AdditionalNames;HonorificPrefixes;HonorificSuffixes
|
||||
if hasattr(self.vobject_item, "n") and self.vobject_item.n.value.family != "":
|
||||
placeholder_mapping['{n:f}'] = self.vobject_item.n.value.family
|
||||
else:
|
||||
placeholder_mapping['{n:f}'] = '!n:f!'
|
||||
|
||||
if hasattr(self.vobject_item, "n") and self.vobject_item.n.value.given != "":
|
||||
placeholder_mapping['{n:g}'] = self.vobject_item.n.value.given
|
||||
else:
|
||||
placeholder_mapping['{n:g}'] = '!n:g!'
|
||||
|
||||
if hasattr(self.vobject_item, "n") and self.vobject_item.n.value.additional != "":
|
||||
placeholder_mapping['{n:a}'] = self.vobject_item.n.value.additional
|
||||
else:
|
||||
placeholder_mapping['{n:a}'] = '!n:a!'
|
||||
|
||||
# create VCALENDAR
|
||||
item_ics = vobject.newFromBehavior('vcalendar')
|
||||
|
||||
@@ -579,7 +641,14 @@ class Item:
|
||||
item_ics.vevent.add('uid').value = match[1] + match[2] + match[3] + "@" + name.replace(" ", "-") + UID_SUFFIX
|
||||
|
||||
# set SUMMARY
|
||||
item_ics.vevent.add('summary').value = name + " (BDAY)"
|
||||
summary = name + " (BDAY)" # default
|
||||
if ShareActions is not None and 'template' in ShareActions:
|
||||
if 'conversion_bday_summary_template' in ShareActions['template']:
|
||||
summary = ShareActions['template']['conversion_bday_summary_template']
|
||||
summary = self.replace_placeholders(summary, placeholder_mapping)
|
||||
else:
|
||||
summary = name + " (BDAY)"
|
||||
item_ics.vevent.add('summary').value = summary
|
||||
|
||||
# set RRULE
|
||||
item_ics.vevent.add('rrule').value = "FREQ=YEARLY"
|
||||
@@ -588,7 +657,12 @@ class Item:
|
||||
item_ics.vevent.add('transp').value = "TRANSPARENT"
|
||||
|
||||
# add description
|
||||
item_ics.vevent.add('description').value = "BDAY=" + bdaySdesc
|
||||
description = "BDAY=" + bdaySdesc # default
|
||||
if ShareActions is not None and 'template' in ShareActions:
|
||||
if 'conversion_bday_description_template' in ShareActions['template']:
|
||||
description = ShareActions['template']['conversion_bday_description_template']
|
||||
description = self.replace_placeholders(description, placeholder_mapping)
|
||||
item_ics.vevent.add('description').value = description
|
||||
|
||||
href = self.href
|
||||
if href is not None:
|
||||
|
||||
@@ -223,7 +223,7 @@ class BaseCollection:
|
||||
"""Get the HTTP-datetime of when the collection was modified."""
|
||||
raise NotImplementedError
|
||||
|
||||
def serialize(self, vcf_to_ics: bool = False) -> str:
|
||||
def serialize(self, vcf_to_ics: bool = False, ShareActions: dict = {}) -> str:
|
||||
"""Get the unicode string representing the whole collection."""
|
||||
if self.tag == "VCALENDAR":
|
||||
in_vcalendar = False
|
||||
@@ -288,7 +288,7 @@ class BaseCollection:
|
||||
items = []
|
||||
for item in self.get_all():
|
||||
logger.trace("storage/convert VCF to ICS: %r:", item)
|
||||
item_ics = item.convert_vcf_to_ics()
|
||||
item_ics = item.convert_vcf_to_ics(ShareActions=ShareActions)
|
||||
if item_ics is None:
|
||||
continue
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user