diff --git a/src/daemon_get.py b/src/daemon_get.py index 7fb536376..b84a5c308 100644 --- a/src/daemon_get.py +++ b/src/daemon_get.py @@ -2715,7 +2715,8 @@ def daemon_http_get(self) -> None: # image on login screen or qrcode if is_image_file(self.path) and \ (string_starts_with(self.path, - ('/login.', '/qrcode.png', '/qrcode_lxmf.png'))): + ('/login.', '/qrcode.png', '/qrcode_lxmf.png', + '/qrcode_ricochet.png', '/qrcode_enigma.png'))): icon_filename = data_dir(self.server.base_dir) + self.path if is_a_file(icon_filename): if etag_exists(self, icon_filename): @@ -2754,7 +2755,9 @@ def daemon_http_get(self) -> None: # QR code for account handle if (users_in_path and (self.path.endswith('/qrcode.png') or - self.path.endswith('/qrcode_lxmf.png'))): + self.path.endswith('/qrcode_lxmf.png') or + self.path.endswith('/qrcode_ricochet.png') or + self.path.endswith('/qrcode_enigma.png'))): if show_qrcode(self, calling_domain, self.path, self.server.base_dir, self.server.domain, diff --git a/src/daemon_get_images.py b/src/daemon_get_images.py index b2745fbca..75aad044b 100644 --- a/src/daemon_get_images.py +++ b/src/daemon_get_images.py @@ -29,6 +29,8 @@ from src.daemon_utils import etag_exists from src.fitnessFunctions import fitness_performance from src.person import save_person_qrcode from src.lxmf import save_lxmf_qrcode +from src.ricochet import save_ricochet_qrcode +from src.enigma import save_enigma_qrcode from src.data import load_string from src.data import load_binary from src.data import is_a_file @@ -476,6 +478,16 @@ def show_qrcode(self, calling_domain: str, path: str, acct_dir(base_dir, nickname, domain) + '/qrcode_lxmf.png' qrcode_scale = 6 save_lxmf_qrcode(base_dir, nickname, domain, qrcode_scale) + elif path.endswith('_ricochet.png'): + qr_filename = \ + acct_dir(base_dir, nickname, domain) + '/qrcode_ricochet.png' + qrcode_scale = 6 + save_ricochet_qrcode(base_dir, nickname, domain, qrcode_scale) + elif path.endswith('_enigma.png'): + qr_filename = \ + acct_dir(base_dir, nickname, domain) + '/qrcode_enigma.png' + qrcode_scale = 6 + save_enigma_qrcode(base_dir, nickname, domain, qrcode_scale) else: if onion_domain: qrcode_domain = onion_domain diff --git a/src/daemon_post_profile.py b/src/daemon_post_profile.py index 87a09e13e..037009259 100644 --- a/src/daemon_post_profile.py +++ b/src/daemon_post_profile.py @@ -1709,19 +1709,24 @@ def _profile_post_pgp_pubkey(actor_json: {}, fields: {}, return actor_changed -def _profile_post_enigma_pubkey(actor_json: {}, fields: {}, +def _profile_post_enigma_pubkey(base_dir: str, nickname: str, domain: str, + actor_json: {}, fields: {}, actor_changed: bool) -> bool: """ HTTP POST change Enigma public key """ - currentenigma_pub_key = get_enigma_pub_key(actor_json) + qrcode_scale = 6 + current_enigma_pub_key = get_enigma_pub_key(actor_json) if fields.get('enigmapubkey'): - if fields['enigmapubkey'] != currentenigma_pub_key: - set_enigma_pub_key(actor_json, - fields['enigmapubkey']) + if fields['enigmapubkey'] != current_enigma_pub_key: + set_enigma_pub_key(base_dir, nickname, domain, + actor_json, + fields['enigmapubkey'], + qrcode_scale) actor_changed = True else: - if currentenigma_pub_key: - set_enigma_pub_key(actor_json, '') + if current_enigma_pub_key: + set_enigma_pub_key(base_dir, nickname, domain, actor_json, + '', qrcode_scale) actor_changed = True return actor_changed @@ -1782,19 +1787,24 @@ def _profile_post_briar_address(fields: {}, actor_json: {}, return actor_changed -def _profile_post_ricochet_address(fields: {}, actor_json: {}, +def _profile_post_ricochet_address(base_dir: str, nickname: str, domain: str, + fields: {}, actor_json: {}, actor_changed: bool) -> bool: """ HTTP POST change ricochet address """ + qrcode_scale = 6 current_ricochet_address = get_ricochet_address(actor_json) if fields.get('ricochetAddress'): if fields['ricochetAddress'] != current_ricochet_address: - set_ricochet_address(actor_json, - fields['ricochetAddress']) + set_ricochet_address(base_dir, nickname, domain, + actor_json, + fields['ricochetAddress'], + qrcode_scale) actor_changed = True else: if current_ricochet_address: - set_ricochet_address(actor_json, '') + set_ricochet_address(base_dir, nickname, domain, + actor_json, '', qrcode_scale) actor_changed = True return actor_changed @@ -3095,7 +3105,8 @@ def profile_edit(self, calling_domain: str, cookie: str, actor_changed) actor_changed = \ - _profile_post_ricochet_address(fields, actor_json, + _profile_post_ricochet_address(base_dir, nickname, domain, + fields, actor_json, actor_changed) actor_changed = \ @@ -3107,7 +3118,8 @@ def profile_edit(self, calling_domain: str, cookie: str, _profile_post_ntfy_topic(base_dir, nickname, domain, fields) actor_changed = \ - _profile_post_enigma_pubkey(actor_json, fields, + _profile_post_enigma_pubkey(base_dir, nickname, domain, + actor_json, fields, actor_changed) actor_changed = \ diff --git a/src/enigma.py b/src/enigma.py index 23895c4a8..010b6e600 100644 --- a/src/enigma.py +++ b/src/enigma.py @@ -8,8 +8,13 @@ __status__ = "Production" __module_group__ = "Profile Metadata" +import pyqrcode +from src.utils import acct_dir +from src.utils import load_json from src.utils import get_attachment_property_value from src.utils import remove_html +from src.data import is_a_file +from src.data import erase_file def get_enigma_pub_key(actor_json: {}) -> str: @@ -48,9 +53,47 @@ def get_enigma_pub_key(actor_json: {}) -> str: return '' -def set_enigma_pub_key(actor_json: {}, enigma_pub_key: str) -> None: +def save_enigma_qrcode(base_dir: str, + nickname: str, domain: str, + scale: int = 6) -> bool: + """Saves a qrcode image for the enigma public key + This helps to transfer onion or i2p handles to a mobile device + """ + qrcode_filename = \ + acct_dir(base_dir, nickname, domain) + '/qrcode_enigma.png' + if is_a_file(qrcode_filename): + return False + actor_filename = \ + acct_dir(base_dir, nickname, domain) + '.json' + if not is_a_file(actor_filename): + return False + actor_json = load_json(actor_filename) + if not actor_json: + return False + enigma_address = get_enigma_pub_key(actor_json) + if not enigma_address: + return False + url = pyqrcode.create(enigma_address) + try: + url.png(qrcode_filename, scale) + return True + except ModuleNotFoundError: + print('EX: save_enigma_qrcode pyqrcode png module not found') + return False + + +def set_enigma_pub_key(base_dir: str, nickname: str, domain: str, + actor_json: {}, enigma_pub_key: str, + qrcode_scale: int) -> None: """Sets a Enigma public key for the given actor """ + if not enigma_pub_key: + qrcode_filename = \ + acct_dir(base_dir, nickname, domain) + '/qrcode_enigma.png' + if is_a_file(qrcode_filename): + erase_file(qrcode_filename, + 'EX: cannot remove enigma qrcode ' + qrcode_filename) + remove_key: bool = False if not enigma_pub_key: remove_key = True @@ -118,3 +161,4 @@ def set_enigma_pub_key(actor_json: {}, enigma_pub_key: str) -> None: "value": enigma_pub_key } actor_json['attachment'].append(new_enigma_pub_key) + save_enigma_qrcode(base_dir, nickname, domain, qrcode_scale) diff --git a/src/lxmf.py b/src/lxmf.py index 2e93f5435..54cdb3092 100644 --- a/src/lxmf.py +++ b/src/lxmf.py @@ -34,7 +34,7 @@ def _is_valid_lxmf_address(lxmf_address: str) -> bool: def save_lxmf_qrcode(base_dir: str, nickname: str, domain: str, scale: int = 6) -> bool: - """Saves a qrcode image for the handle of the person + """Saves a qrcode image for the lxmf address of the person This helps to transfer onion or i2p handles to a mobile device """ qrcode_filename = acct_dir(base_dir, nickname, domain) + '/qrcode_lxmf.png' diff --git a/src/ricochet.py b/src/ricochet.py index 93a274e3a..97136c711 100644 --- a/src/ricochet.py +++ b/src/ricochet.py @@ -8,8 +8,13 @@ __status__ = "Production" __module_group__ = "Profile Metadata" +import pyqrcode +from src.utils import load_json +from src.utils import acct_dir from src.utils import get_attachment_property_value from src.utils import remove_html +from src.data import is_a_file +from src.data import erase_file def get_ricochet_address(actor_json: {}) -> str: @@ -64,9 +69,47 @@ def get_ricochet_address(actor_json: {}) -> str: return '' -def set_ricochet_address(actor_json: {}, ricochet_address: str) -> None: +def save_ricochet_qrcode(base_dir: str, + nickname: str, domain: str, + scale: int = 6) -> bool: + """Saves a qrcode image for the ricochet address of the person + This helps to transfer onion or i2p handles to a mobile device + """ + qrcode_filename = \ + acct_dir(base_dir, nickname, domain) + '/qrcode_ricochet.png' + if is_a_file(qrcode_filename): + return False + actor_filename = \ + acct_dir(base_dir, nickname, domain) + '.json' + if not is_a_file(actor_filename): + return False + actor_json = load_json(actor_filename) + if not actor_json: + return False + ricochet_address = get_ricochet_address(actor_json) + if not ricochet_address: + return False + url = pyqrcode.create(ricochet_address) + try: + url.png(qrcode_filename, scale) + return True + except ModuleNotFoundError: + print('EX: save_ricochet_qrcode pyqrcode png module not found') + return False + + +def set_ricochet_address(base_dir: str, nickname: str, domain: str, + actor_json: {}, ricochet_address: str, + qrcode_scale: int) -> None: """Sets an ricochet address for the given actor """ + if not ricochet_address: + qrcode_filename = \ + acct_dir(base_dir, nickname, domain) + '/qrcode_ricochet.png' + if is_a_file(qrcode_filename): + erase_file(qrcode_filename, + 'EX: cannot remove ricochet qrcode ' + qrcode_filename) + not_ricochet_address: bool = False if len(ricochet_address) < 60: @@ -149,3 +192,4 @@ def set_ricochet_address(actor_json: {}, ricochet_address: str) -> None: "value": ricochet_address } actor_json['attachment'].append(new_ricochet_address) + save_ricochet_qrcode(base_dir, nickname, domain, qrcode_scale) diff --git a/src/webapp_person_options.py b/src/webapp_person_options.py index e990b28de..7dfcb8eb6 100644 --- a/src/webapp_person_options.py +++ b/src/webapp_person_options.py @@ -524,11 +524,17 @@ def html_person_options(default_timeline: str, if ricochet_address.startswith('ricochet:'): options_str += \ '

' + \ - remove_html(ricochet_address) + '

\n' + remove_html(ricochet_address) else: options_str += \ '

ricochet:' + \ - remove_html(ricochet_address) + '

\n' + remove_html(ricochet_address) + options_str += \ + ' ' + \ + '' + translate['QR Code'] + \
+            '

\n' if cwtch_address: options_str += \ '

Cwtch: ' + \ @@ -536,7 +542,13 @@ def html_person_options(default_timeline: str, if enigma_pub_key: options_str += \ '

Enigma: ' + \ - remove_html(enigma_pub_key) + '

\n' + remove_html(enigma_pub_key) + options_str += \ + ' ' + \ + '' + translate['QR Code'] + \
+            '

\n' if pgp_fingerprint: options_str += '

' + \ translate['PGP Fingerprint'] + ': ' + \ diff --git a/src/webapp_profile.py b/src/webapp_profile.py index 89bff1a70..7ec1210ec 100644 --- a/src/webapp_profile.py +++ b/src/webapp_profile.py @@ -1511,11 +1511,18 @@ def html_profile(signing_priv_key_pem: str, if ricochet_address.startswith('ricochet:'): donate_section += \ '

\n' + ricochet_address + '' else: donate_section += \ '

ricochet:

\n' + ricochet_address + '' + donate_section += \ + ' ' + \ + '' + translate['QR Code'] + \
+                '

\n' if cwtch_address: donate_section += \ '

Cwtch:

Enigma:

\n' + enigma_pub_key + '' + donate_section += \ + ' ' + \ + '' + translate['QR Code'] + \
+                '

\n' if pgp_fingerprint: donate_section += \ '

' + translate['PGP Fingerprint'] + ': ' + \