__filename__ = "availability.py" __author__ = "Bob Mottram" __license__ = "AGPL3+" __version__ = "1.3.0" __maintainer__ = "Bob Mottram" __email__ = "bob@libreserver.org" __status__ = "Production" __module_group__ = "Profile Metadata" import os from webfinger import webfinger_handle from auth import create_basic_auth_header from posts import get_person_box from session import post_json from utils import has_object_string from utils import get_full_domain from utils import get_nickname_from_actor from utils import get_domain_from_actor from utils import load_json from utils import save_json from utils import acct_dir from utils import local_actor_url from utils import has_actor def set_availability(base_dir: str, nickname: str, domain: str, status: str) -> bool: """Set an availability status """ # avoid giant strings if len(status) > 128: return False actor_filename = acct_dir(base_dir, nickname, domain) + '.json' if not os.path.isfile(actor_filename): return False actor_json = load_json(actor_filename) if actor_json: actor_json['availability'] = status save_json(actor_json, actor_filename) return True def get_availability(base_dir: str, nickname: str, domain: str) -> str: """Returns the availability for a given person """ actor_filename = acct_dir(base_dir, nickname, domain) + '.json' if not os.path.isfile(actor_filename): return False actor_json = load_json(actor_filename) if actor_json: if not actor_json.get('availability'): return None return actor_json['availability'] return None def outbox_availability(base_dir: str, nickname: str, message_json: {}, debug: bool) -> bool: """Handles receiving an availability update """ if not message_json.get('type'): return False if not message_json['type'] == 'Availability': return False if not has_actor(message_json, debug): return False if not has_object_string(message_json, debug): return False actor_nickname = get_nickname_from_actor(message_json['actor']) if not actor_nickname: return False if actor_nickname != nickname: return False domain, _ = get_domain_from_actor(message_json['actor']) status = message_json['object'].replace('"', '') return set_availability(base_dir, nickname, domain, status) def send_availability_via_server(base_dir: str, session, nickname: str, password: str, domain: str, port: int, http_prefix: str, status: str, cached_webfingers: {}, person_cache: {}, debug: bool, project_version: str, signing_priv_key_pem: str) -> {}: """Sets the availability for a person via c2s """ if not session: print('WARN: No session for send_availability_via_server') return 6 domain_full = get_full_domain(domain, port) to_url = local_actor_url(http_prefix, nickname, domain_full) cc_url = to_url + '/followers' new_availability_json = { 'type': 'Availability', 'actor': to_url, 'object': '"' + status + '"', 'to': [to_url], 'cc': [cc_url] } handle = http_prefix + '://' + domain_full + '/@' + nickname # lookup the inbox for the To handle wf_request = webfinger_handle(session, handle, http_prefix, cached_webfingers, domain, project_version, debug, False, signing_priv_key_pem) if not wf_request: if debug: print('DEBUG: availability webfinger failed for ' + handle) return 1 if not isinstance(wf_request, dict): print('WARN: availability webfinger for ' + handle + ' did not return a dict. ' + str(wf_request)) return 1 post_to_box = 'outbox' # get the actor inbox for the To handle origin_domain = domain (inbox_url, _, _, from_person_id, _, _, _, _) = get_person_box(signing_priv_key_pem, origin_domain, base_dir, session, wf_request, person_cache, project_version, http_prefix, nickname, domain, post_to_box, 57262) if not inbox_url: if debug: print('DEBUG: availability no ' + post_to_box + ' was found for ' + handle) return 3 if not from_person_id: if debug: print('DEBUG: availability no actor was found for ' + handle) return 4 auth_header = create_basic_auth_header(nickname, password) headers = { 'host': domain, 'Content-type': 'application/json', 'Authorization': auth_header } post_result = post_json(http_prefix, domain_full, session, new_availability_json, [], inbox_url, headers, 30, True) if not post_result: print('WARN: availability failed to post') if debug: print('DEBUG: c2s POST availability success') return new_availability_json