diff --git a/utils.py b/utils.py index f18462d91..e5799a161 100644 --- a/utils.py +++ b/utils.py @@ -4852,3 +4852,33 @@ def get_reply_to(post_json_object: {}) -> str: if post_json_object.get('inReplyToBook'): return post_json_object['inReplyToBook'] return '' + + +def is_valid_date(date_str: str) -> bool: + """is the given date valid? + """ + if not isinstance(date_str, str): + return False + if '-' not in date_str: + return False + date_sections = date_str.split('-') + if len(date_sections) != 3: + return False + date_sect_ctr = 0 + for section_str in date_sections: + if not section_str.isdigit(): + return False + if date_sect_ctr == 0: + date_year = int(section_str) + if date_year < 1920 or date_year > 3000: + return False + elif date_sect_ctr == 1: + date_month = int(section_str) + if date_month < 1 or date_month > 12: + return False + elif date_sect_ctr == 2: + date_day = int(section_str) + if date_day < 1 or date_day > 31: + return False + date_sect_ctr += 1 + return True diff --git a/webapp_profile.py b/webapp_profile.py index c53a12ade..fa1802800 100644 --- a/webapp_profile.py +++ b/webapp_profile.py @@ -38,6 +38,7 @@ from utils import local_actor_url from utils import get_reply_interval_hours from utils import get_account_timezone from utils import remove_eol +from utils import is_valid_date from languages import get_actor_languages from skills import get_skills from theme import get_themes_list @@ -382,6 +383,10 @@ def html_profile_after_search(authorized: bool, send_block_filename, False): send_blocks_str = translate['FollowWarning'] + birth_date = '' + if profile_json.get('vcard:bday'): + birth_date = profile_json['vcard:bday'] + profile_str = \ _get_profile_header_after_search(base_dir, nickname, domain, default_timeline, @@ -400,7 +405,8 @@ def html_profile_after_search(authorized: bool, website_url, repo_url, send_blocks_str, authorized, - person_url, no_of_books) + person_url, no_of_books, + birth_date) domain_full = get_full_domain(domain, port) @@ -586,7 +592,8 @@ def _get_profile_header(base_dir: str, http_prefix: str, nickname: str, actor_proxied: str, person_url: str, no_of_books: int, - authorized: bool) -> str: + authorized: bool, + birth_date: str) -> str: """The header of the profile screen, containing background image and avatar """ @@ -686,6 +693,11 @@ def _get_profile_header(base_dir: str, http_prefix: str, nickname: str, other_accounts_html += '

\n' if ctr > 0: html_str += other_accounts_html + if is_valid_date(birth_date): + birth_date = remove_html(birth_date) + html_str += \ + '

' + translate['Birthday'] + ': ' + \ + birth_date + '

\n' if featured_hashtags: featured_hashtags += '\n' html_str += \ @@ -745,7 +757,8 @@ def _get_profile_header_after_search(base_dir: str, send_blocks_str: str, authorized: bool, person_url: str, - no_of_books: str) -> str: + no_of_books: str, + birth_date: str) -> str: """The header of a searched for handle, containing background image and avatar """ @@ -841,7 +854,11 @@ def _get_profile_header_after_search(base_dir: str, other_accounts_html += '

\n' if ctr > 0: html_str += other_accounts_html - + if is_valid_date(birth_date): + birth_date = remove_html(birth_date) + html_str += \ + '

' + translate['Birthday'] + ': ' + \ + birth_date + '

\n' if featured_hashtags: featured_hashtags += '\n' if website_url: @@ -1253,6 +1270,10 @@ def html_profile(signing_priv_key_pem: str, attached_shared_items = \ actor_attached_shares_as_html(profile_json, max_shares_on_profile) + birth_date = '' + if profile_json.get('vcard:bday'): + birth_date = profile_json['vcard:bday'] + profile_header_str = \ _get_profile_header(base_dir, http_prefix, nickname, @@ -1267,7 +1288,8 @@ def html_profile(signing_priv_key_pem: str, access_keys, joined_date, occupation_name, actor_proxied, actor, - no_of_books, authorized) + no_of_books, authorized, + birth_date) # keyboard navigation user_path_str = '/users/' + nickname