1 # Fedi API Block - An aggregator for fetching blocking data from fediverse nodes
2 # Copyright (C) 2023 Free Software Foundation
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published
6 # by the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU Affero General Public License for more details.
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <https://www.gnu.org/licenses/>.
22 # Found info from node, such as nodeinfo URL, detection mode that needs to be
23 # written to database. Both arrays must be filled at the same time or else
24 # update_instance_data() will fail
26 # Detection mode: 'AUTO_DISCOVERY', 'STATIC_CHECKS' or 'GENERATOR'
27 # NULL means all detection methods have failed (maybe still reachable instance)
28 "detection_mode" : {},
33 # Last fetched instances
34 "last_instance_fetch": {},
39 # Last nodeinfo (fetched)
42 "last_status_code" : {},
44 "last_error_details" : {},
47 def set(key: str, domain: str, value: any):
48 # DEBUG: print(f"DEBUG: key='{key}',domain='{domain}',value[]='{type(value)}' - CALLED!")
50 raise ValueError("Parameter key[]='{type(key)}' is not 'str'")
52 raise ValueError(f"Parameter 'key' cannot be empty")
53 elif type(domain) != str:
54 raise ValueError("Parameter domain[]='{type(domain)}' is not 'str'")
56 raise ValueError(f"Parameter 'domain' cannot be empty")
57 elif not key in _pending:
58 raise ValueError(f"key='{key}' not found in _pending")
59 elif not fba.is_primitive(value):
60 raise ValueError(f"value[]='{type(value)}' is not a primitive type")
63 _pending[key][domain] = value
65 # DEBUG: # DEBUG: print("DEBUG: EXIT!")
67 def has_pending_instance_data(domain: str) -> bool:
68 # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!")
69 if type(domain) != str:
70 raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'")
72 raise ValueError(f"Parameter 'domain' cannot be empty")
76 # DEBUG: print(f"DEBUG: key='{key}',domain='{domain}',_pending[key]()='{len(_pending[key])}'")
77 if domain in _pending[key]:
81 # DEBUG: print(f"DEBUG: has_pending='{has_pending}' - EXIT!")
84 def update_instance_data(domain: str):
85 # DEBUG: print(f"DEBUG: domain={domain} - CALLED!")
86 if type(domain) != str:
87 raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'")
89 raise ValueError(f"Parameter 'domain' cannot be empty")
90 elif not has_pending_instance_data(domain):
91 raise Exception(f"Domain '{domain}' has no pending instance data, but function invoked")
93 # DEBUG: print(f"DEBUG: Updating instance data for domain='{domain}' ...")
97 # DEBUG: print("DEBUG: key:", key)
98 if domain in _pending[key]:
99 # DEBUG: print(f"DEBUG: Adding '{_pending[key][domain]}' for key='{key}' ...")
100 fields.append(_pending[key][domain])
101 sql_string += f" {key} = ?,"
103 fields.append(time.time())
104 fields.append(domain)
107 raise ValueError(f"No fields have been set, but method invoked, domain='{domain}'")
109 # DEBUG: print(f"DEBUG: sql_string='{sql_string}',fields()={len(fields)}")
110 sql_string = "UPDATE instances SET" + sql_string + " last_updated = ? WHERE domain = ? LIMIT 1"
111 # DEBUG: print("DEBUG: sql_string:", sql_string)
114 # DEBUG: print("DEBUG: Executing SQL:", sql_string)
115 fba.cursor.execute(sql_string, fields)
117 # DEBUG: print(f"DEBUG: Success! (rowcount={fba.cursor.rowcount })")
118 if fba.cursor.rowcount == 0:
119 # DEBUG: print(f"DEBUG: Did not update any rows: domain='{domain}',fields()={len(fields)} - EXIT!")
122 # DEBUG: print("DEBUG: Committing changes ...")
123 fba.connection.commit()
125 # DEBUG: print("DEBUG: Deleting _pending for domain:", domain)
128 # DEBUG: print("DEBUG: Deleting key:", key)
129 del _pending[key][domain]
133 except BaseException as e:
134 print(f"ERROR: failed SQL query: domain='{domain}',sql_string='{sql_string}',exception[{type(e)}]:'{str(e)}'")
137 # DEBUG: print("DEBUG: EXIT!")