Coverage for silkaj/wot/tools.py: 85%
59 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-20 12:29 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-20 12:29 +0000
1# Copyright 2016-2025 Maël Azimi <m.a@moul.re>
2#
3# Silkaj is free software: you can redistribute it and/or modify
4# it under the terms of the GNU Affero General Public License as published by
5# the Free Software Foundation, either version 3 of the License, or
6# (at your option) any later version.
7#
8# Silkaj is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU Affero General Public License for more details.
12#
13# You should have received a copy of the GNU Affero General Public License
14# along with Silkaj. If not, see <https://www.gnu.org/licenses/>.
16import contextlib
17import time
18import urllib
19from typing import Optional
20from urllib.error import HTTPError
22import rich_click as click
23from duniterpy.api.bma import wot
25from silkaj.constants import BMA_SLEEP
26from silkaj.network import client_instance, exit_on_http_error
27from silkaj.public_key import gen_pubkey_checksum
28from silkaj.tui import Table
31def identity_of(pubkey_uid: str) -> dict:
32 """
33 Only works for members
34 Not able to get corresponding uid from a non-member identity
35 Able to know if an identity is member or not
36 """
37 client = client_instance()
38 return client(wot.identity_of, pubkey_uid)
41def is_member(pubkey_uid: str) -> Optional[dict]:
42 """
43 Check identity is member
44 If member, return corresponding identity, else: False
45 """
46 try:
47 return identity_of(pubkey_uid)
48 except HTTPError:
49 return None
52def wot_lookup(identifier: str) -> list:
53 """
54 :identifier: identity or pubkey in part or whole
55 Return received and sent certifications lists of matching identities
56 if one identity found
57 """
58 client = client_instance()
59 return (client(wot.lookup, identifier))["results"]
62def identities_from_pubkeys(pubkeys: list[str], uids: bool) -> list:
63 """
64 Make list of pubkeys unique, and remove empty strings
65 Request identities
66 """
67 if not uids:
68 return []
70 uniq_pubkeys = list(filter(None, set(pubkeys)))
71 identities = []
72 for pubkey in uniq_pubkeys:
73 time.sleep(BMA_SLEEP)
74 with contextlib.suppress(HTTPError):
75 identities.append(identity_of(pubkey))
76 return identities
79def choose_identity(pubkey_uid: str) -> tuple[dict, str, list]:
80 """
81 Get lookup from a pubkey or an uid
82 Loop over the double lists: pubkeys, then uids
83 If there is one uid, returns it
84 If there is multiple uids, prompt a selector
85 """
87 try:
88 lookups = wot_lookup(pubkey_uid)
89 except urllib.error.HTTPError as e:
90 exit_on_http_error(e, 404, f"No identity found for {pubkey_uid}")
92 # Generate table containing the choices
93 identities_choices = {
94 "id": [],
95 "uid": [],
96 "pubkey": [],
97 "timestamp": [],
98 } # type: dict
99 for pubkey_index, lookup in enumerate(lookups):
100 for uid_index, identity in enumerate(lookup["uids"]):
101 identities_choices["id"].append(str(pubkey_index) + str(uid_index))
102 identities_choices["pubkey"].append(gen_pubkey_checksum(lookup["pubkey"]))
103 identities_choices["uid"].append(identity["uid"])
104 identities_choices["timestamp"].append(
105 identity["meta"]["timestamp"][:20] + "…",
106 )
108 identities = len(identities_choices["uid"])
109 if identities == 1:
110 pubkey_index = 0
111 uid_index = 0
112 elif identities > 1:
113 table = Table().set_cols_dtype(["t", "t", "t", "t"])
114 table.fill_from_dict(identities_choices)
115 click.echo(table.draw())
116 # Loop till the passed value is in identities_choices
117 message = "Which identity would you like to select (id)?"
118 selected_id = None
119 while selected_id not in identities_choices["id"]:
120 selected_id = click.prompt(message)
122 pubkey_index = int(str(selected_id)[:-1])
123 uid_index = int(str(selected_id)[-1:])
125 return (
126 lookups[pubkey_index]["uids"][uid_index],
127 lookups[pubkey_index]["pubkey"],
128 lookups[pubkey_index]["signed"],
129 )