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/>.
21 from fba import commands
22 from fba import database
24 from fba.helpers import locking
26 logging.basicConfig(level=logging.INFO)
27 logger = logging.getLogger(__name__)
33 logger.debug("CALLED!")
36 logger.debug("Initializing parser ...")
37 _PARSER = argparse.ArgumentParser(
38 description="Fetches block reasons from the fediverse",
39 epilog="Please note that some commands have optional arguments, you may want to try fba.py <command> --help to find them out. Please DO NOT overdose requests that are not limited by themselves. Typically parameters like --domain, --software and --force are unlimited. \"Unlimited\" here means that there is no \"is recently accessed?\" limitation.",
48 help="Full debug output"
52 subparser_command = _PARSER.add_subparsers(
54 title="Commands to execute",
56 help="Command to perform",
59 ### Check instance ###
60 parser = subparser_command.add_parser(
62 help="Checks given instance if it exists and returns proper exit code"
64 parser.set_defaults(command=commands.check_instance)
65 parser.add_argument("--domain", required=True, help="Instance name (aka. domain) to check")
67 ### Fetch from bka.li ###
68 parser = subparser_command.add_parser(
70 help="Fetches domain names from bka.li API",
72 parser.set_defaults(command=commands.fetch_bkali)
74 ### Recheck instance's obfuscated peers ###
75 parser = subparser_command.add_parser(
76 "recheck_obfuscation",
77 help="Checks all instance's obfuscated peers if they can be de-obfuscated now.",
79 parser.set_defaults(command=commands.recheck_obfuscation)
80 parser.add_argument("--domain", help="Instance name (aka. domain)")
81 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
82 parser.add_argument("--force", action="store_true", help="Include also already existing instances, otherwise only new are checked")
83 parser.add_argument("--delete-unwanted", action="store_true", help="Whether delete or keep (default) unwanted domains")
85 ### Fetch blocks from registered instances or given ###
86 parser = subparser_command.add_parser(
88 help="Fetches blocks from registered instances (run command fetch_instances first!).",
90 parser.set_defaults(command=commands.fetch_blocks)
91 parser.add_argument("--domain", help="Instance name (aka. domain)")
92 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
93 parser.add_argument("--only-none", action="store_true", help="Checks only entries which has never been checked.")
94 parser.add_argument("--force", action="store_true", help="Forces update of data, no matter what.")
96 ### Fetch blocks from chaos.social ###
97 parser = subparser_command.add_parser(
99 help="Fetches blocks from chaos.social's meta sub domain.",
101 parser.set_defaults(command=commands.fetch_cs)
103 ### Fetch blocks from todon.eu wiki ###
104 parser = subparser_command.add_parser(
106 help="Fetches blocks from todon.eu's wiki.",
108 parser.set_defaults(command=commands.fetch_todon_wiki)
110 ### Fetch blocks from a FBA-specific RSS feed ###
111 parser = subparser_command.add_parser(
113 help="Fetches domains from a FBA-specific RSS feed.",
115 parser.set_defaults(command=commands.fetch_fba_rss)
116 parser.add_argument("--feed", required=True, help="RSS feed to fetch domains from (e.g. https://fba.ryoma.agency/rss?domain=foo.bar).")
118 ### Fetch blocks from FBA's bot account ###
119 parser = subparser_command.add_parser(
121 help="Fetches ATOM feed with domains from FBA's bot account.",
123 parser.set_defaults(command=commands.fetch_fbabot_atom)
124 parser.add_argument("--feed", required=True, help="RSS feed to fetch domains from (e.g. https://fba.ryoma.agency/rss?domain=foo.bar).")
126 ### Fetch blocks from oliphant's GIT repository ###
127 parser = subparser_command.add_parser(
129 help="Fetches CSV files from GIT generated by Oliphant 'member instances'.",
131 parser.set_defaults(command=commands.fetch_oliphant)
132 parser.add_argument("--domain", help="Instance name (aka. domain) to check")
134 ### Fetch blocks from other CSV files
135 parser = subparser_command.add_parser(
137 help="Fetches CSV files (block recommendations) for more possible instances to disover",
139 parser.set_defaults(command=commands.fetch_csv)
140 parser.add_argument("--domain", help="Instance name (aka. domain) to check")
142 ### Fetch instances from given initial instance ###
143 parser = subparser_command.add_parser(
145 help="Fetches instances (aka. \"domains\") from an initial instance. You may want to re-run this command several times (at least 3 with big instances) to have a decent amount of valid instances.",
147 parser.set_defaults(command=commands.fetch_instances)
148 parser.add_argument("--domain", help="Instance name (aka. domain) to fetch further instances from. Start with a large instance, e.g. mastodon.social .")
149 parser.add_argument("--force", action="store_true", help="Include also already existing instances, otherwise only new are checked")
150 parser.add_argument("--single", action="store_true", help="Only fetch given instance.")
151 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
153 ### Fetch blocks from static text file(s) ###
154 parser = subparser_command.add_parser(
156 help="Fetches text/plain files as simple domain lists",
158 parser.set_defaults(command=commands.fetch_txt)
159 parser.add_argument("--force", action="store_true", help="Forces update of data, no matter what.")
161 ### Fetch blocks from joinfediverse.wiki ###
162 #parser = subparser_command.add_parser(
163 # "fetch_joinfediverse",
164 # help="Fetches FediBlock page from joinfediverse.wiki",
166 #parser.set_defaults(command=commands.fetch_joinfediverse)
168 ### Fetch instances JSON from instances.joinmobilizon.org
169 parser = subparser_command.add_parser(
170 "fetch_joinmobilizon",
171 help="Fetches instances from joinmobilizon",
173 parser.set_defaults(command=commands.fetch_joinmobilizon)
175 ### Fetch blocks from misskey.page ###
176 parser = subparser_command.add_parser(
178 help="Fetches instances.json from misskey.page",
180 parser.set_defaults(command=commands.fetch_joinmisskey)
182 ### Fetch blocks from fediverse.observer ###
183 parser = subparser_command.add_parser(
185 help="Fetches blocks from fediverse.observer.",
187 parser.set_defaults(command=commands.fetch_observer)
188 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
190 ### Fetch instances from fedipact.online ###
191 parser = subparser_command.add_parser(
193 help="Fetches blocks from fedipact.online.",
195 parser.set_defaults(command=commands.fetch_fedipact)
197 ### Fetch from pixelfed.org's API ###
198 parser = subparser_command.add_parser(
199 "fetch_pixelfed_api",
200 help="Fetches domain names from pixelfed.org's API",
202 parser.set_defaults(command=commands.fetch_pixelfed_api)
204 ### Check nodeinfo ###
205 parser = subparser_command.add_parser(
207 help="Checks if domain is part of nodeinfo.",
209 parser.set_defaults(command=commands.check_nodeinfo)
211 ### Fetch CSV from fedilist.com ###
212 parser = subparser_command.add_parser(
214 help="Fetches CSV from fedilist.com",
216 parser.set_defaults(command=commands.fetch_fedilist)
217 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
218 parser.add_argument("--force", action="store_true", help="Include also already existing instances, otherwise only new are checked")
220 ### Update nodeinfo ###
221 parser = subparser_command.add_parser(
223 help="Updates nodeinfo for all instances",
225 parser.set_defaults(command=commands.update_nodeinfo)
226 parser.add_argument("--domain", help="Instance name (aka. domain)")
227 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
228 parser.add_argument("--mode", help="Name of detection mode, e.g. 'auto_discovery'")
229 parser.add_argument("--force", action="store_true", help="Forces update of data, no matter what.")
230 parser.add_argument("--no-software", action="store_true", help="Checks only entries with no software type detected.")
231 parser.add_argument("--no-auto", action="store_true", help="Checks only entries with other than AUTO_DISCOVERY as detection mode.")
232 parser.add_argument("--no-detection", action="store_true", help="Checks only entries with no detection mode set.")
233 parser.add_argument("--with-software", action="store_true", help="Checks only entries with any software type detected.")
234 parser.add_argument("--same", action="store_true", help="Checks only entries with domain and software being the same.")
236 ### Fetch instances from instances.social ###
237 parser = subparser_command.add_parser(
238 "fetch_instances_social",
239 help="Fetch instances from instances.social, you need an API key to access the API. Please consider donating to them when you want to more frequent use their API!",
241 parser.set_defaults(command=commands.fetch_instances_social)
243 ### Convert international domain names to punycode domains ###
244 parser = subparser_command.add_parser(
246 help="Convertes UTF-8 encoded international domain names into punycode (IDNA) domain names.",
248 parser.set_defaults(command=commands.convert_idna)
250 ### Fetch instances from ActivityPub relays ###
251 parser = subparser_command.add_parser(
253 help="Fetches instances from ActivityPub relays",
255 parser.set_defaults(command=commands.fetch_relays)
256 parser.add_argument("--domain", help="Instance name (aka. 'relay')")
257 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
258 parser.add_argument("--force", action="store_true", help="Forces update of data, no matter what.")
260 ### Fetches relay list from relaylist.com
261 parser = subparser_command.add_parser(
263 help="Fetches relay list from relaylist.com",
265 parser.set_defaults(command=commands.fetch_relaylist)
267 ### Remove invalid domains ###
268 parser = subparser_command.add_parser(
270 help="Removes invalid domains.",
272 parser.set_defaults(command=commands.remove_invalid)
274 logger.debug("EXIT!")
277 logger.debug("CALLED!")
278 args = _PARSER.parse_args()
280 if args.log_level is not None:
281 loggers = [logging.getLogger(name) for name in logging.root.manager.loggerDict]
282 for _logger in loggers:
283 _logger.setLevel(args.log_level)
285 logger.debug("args[%s]='%s'", type(args), args)
286 status = args.command(args)
288 logger.debug("status=%d - EXIT!", status)
292 logger.debug("Closing database connection ...")
293 database.connection.close()
295 logger.debug("Shutdown completed.")