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")
84 ### Fetch blocks from registered instances or given ###
85 parser = subparser_command.add_parser(
87 help="Fetches blocks from registered instances (run command fetch_instances first!).",
89 parser.set_defaults(command=commands.fetch_blocks)
90 parser.add_argument("--domain", help="Instance name (aka. domain)")
91 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
92 parser.add_argument("--only-none", action="store_true", help="Checks only entries which has never been checked.")
93 parser.add_argument("--force", action="store_true", help="Forces update of data, no matter what.")
95 ### Fetch blocks from chaos.social ###
96 parser = subparser_command.add_parser(
98 help="Fetches blocks from chaos.social's meta sub domain.",
100 parser.set_defaults(command=commands.fetch_cs)
102 ### Fetch blocks from todon.eu wiki ###
103 parser = subparser_command.add_parser(
105 help="Fetches blocks from todon.eu's wiki.",
107 parser.set_defaults(command=commands.fetch_todon_wiki)
109 ### Fetch blocks from a FBA-specific RSS feed ###
110 parser = subparser_command.add_parser(
112 help="Fetches domains from a FBA-specific RSS feed.",
114 parser.set_defaults(command=commands.fetch_fba_rss)
115 parser.add_argument("--feed", required=True, help="RSS feed to fetch domains from (e.g. https://fba.ryoma.agency/rss?domain=foo.bar).")
117 ### Fetch blocks from FBA's bot account ###
118 parser = subparser_command.add_parser(
120 help="Fetches ATOM feed with domains from FBA's bot account.",
122 parser.set_defaults(command=commands.fetch_fbabot_atom)
123 parser.add_argument("--feed", required=True, help="RSS feed to fetch domains from (e.g. https://fba.ryoma.agency/rss?domain=foo.bar).")
125 ### Fetch blocks from oliphant's GIT repository ###
126 parser = subparser_command.add_parser(
128 help="Fetches CSV files from GIT generated by Oliphant 'member instances'.",
130 parser.set_defaults(command=commands.fetch_oliphant)
131 parser.add_argument("--domain", help="Instance name (aka. domain) to check")
133 ### Fetch blocks from other CSV files
134 parser = subparser_command.add_parser(
136 help="Fetches CSV files (block recommendations) for more possible instances to disover",
138 parser.set_defaults(command=commands.fetch_csv)
139 parser.add_argument("--domain", help="Instance name (aka. domain) to check")
141 ### Fetch instances from given initial instance ###
142 parser = subparser_command.add_parser(
144 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.",
146 parser.set_defaults(command=commands.fetch_instances)
147 parser.add_argument("--domain", help="Instance name (aka. domain) to fetch further instances from. Start with a large instance, e.g. mastodon.social .")
148 parser.add_argument("--force", action="store_true", help="Include also already existing instances, otherwise only new are checked")
149 parser.add_argument("--single", action="store_true", help="Only fetch given instance.")
150 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
152 ### Fetch blocks from static text file(s) ###
153 parser = subparser_command.add_parser(
155 help="Fetches text/plain files as simple domain lists",
157 parser.set_defaults(command=commands.fetch_txt)
158 parser.add_argument("--force", action="store_true", help="Forces update of data, no matter what.")
160 ### Fetch blocks from joinfediverse.wiki ###
161 #parser = subparser_command.add_parser(
162 # "fetch_joinfediverse",
163 # help="Fetches FediBlock page from joinfediverse.wiki",
165 #parser.set_defaults(command=commands.fetch_joinfediverse)
167 ### Fetch instances JSON from instances.joinmobilizon.org
168 parser = subparser_command.add_parser(
169 "fetch_joinmobilizon",
170 help="Fetches instances from joinmobilizon",
172 parser.set_defaults(command=commands.fetch_joinmobilizon)
174 ### Fetch blocks from misskey.page ###
175 parser = subparser_command.add_parser(
177 help="Fetches instances.json from misskey.page",
179 parser.set_defaults(command=commands.fetch_joinmisskey)
181 ### Fetch blocks from fediverse.observer ###
182 parser = subparser_command.add_parser(
184 help="Fetches blocks from fediverse.observer.",
186 parser.set_defaults(command=commands.fetch_observer)
187 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
189 ### Fetch instances from fedipact.online ###
190 parser = subparser_command.add_parser(
192 help="Fetches blocks from fedipact.online.",
194 parser.set_defaults(command=commands.fetch_fedipact)
196 ### Fetch from pixelfed.org's API ###
197 parser = subparser_command.add_parser(
198 "fetch_pixelfed_api",
199 help="Fetches domain names from pixelfed.org's API",
201 parser.set_defaults(command=commands.fetch_pixelfed_api)
203 ### Check nodeinfo ###
204 parser = subparser_command.add_parser(
206 help="Checks if domain is part of nodeinfo.",
208 parser.set_defaults(command=commands.check_nodeinfo)
210 ### Fetch CSV from fedilist.com ###
211 parser = subparser_command.add_parser(
213 help="Fetches CSV from fedilist.com",
215 parser.set_defaults(command=commands.fetch_fedilist)
216 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
217 parser.add_argument("--force", action="store_true", help="Include also already existing instances, otherwise only new are checked")
219 ### Update nodeinfo ###
220 parser = subparser_command.add_parser(
222 help="Updates nodeinfo for all instances",
224 parser.set_defaults(command=commands.update_nodeinfo)
225 parser.add_argument("--domain", help="Instance name (aka. domain)")
226 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
227 parser.add_argument("--mode", help="Name of detection mode, e.g. 'auto_discovery'")
228 parser.add_argument("--force", action="store_true", help="Forces update of data, no matter what.")
229 parser.add_argument("--no-software", action="store_true", help="Checks only entries with no software type detected.")
230 parser.add_argument("--no-auto", action="store_true", help="Checks only entries with other than AUTO_DISCOVERY as detection mode.")
231 parser.add_argument("--no-detection", action="store_true", help="Checks only entries with no detection mode set.")
232 parser.add_argument("--with-software", action="store_true", help="Checks only entries with any software type detected.")
233 parser.add_argument("--same", action="store_true", help="Checks only entries with domain and software being the same.")
235 ### Fetch instances from instances.social ###
236 parser = subparser_command.add_parser(
237 "fetch_instances_social",
238 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!",
240 parser.set_defaults(command=commands.fetch_instances_social)
242 ### Convert international domain names to punycode domains ###
243 parser = subparser_command.add_parser(
245 help="Convertes UTF-8 encoded international domain names into punycode (IDNA) domain names.",
247 parser.set_defaults(command=commands.convert_idna)
249 ### Fetch instances from ActivityPub relays ###
250 parser = subparser_command.add_parser(
252 help="Fetches instances from ActivityPub relays",
254 parser.set_defaults(command=commands.fetch_relays)
255 parser.add_argument("--domain", help="Instance name (aka. 'relay')")
256 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
257 parser.add_argument("--force", action="store_true", help="Forces update of data, no matter what.")
259 ### Fetches relay list from relaylist.com
260 parser = subparser_command.add_parser(
262 help="Fetches relay list from relaylist.com",
264 parser.set_defaults(command=commands.fetch_relaylist)
266 ### Remove invalid domains ###
267 parser = subparser_command.add_parser(
269 help="Removes invalid domains.",
271 parser.set_defaults(command=commands.remove_invalid)
273 logger.debug("EXIT!")
276 logger.debug("CALLED!")
277 args = _PARSER.parse_args()
279 if args.log_level is not None:
280 loggers = [logging.getLogger(name) for name in logging.root.manager.loggerDict]
281 for _logger in loggers:
282 _logger.setLevel(args.log_level)
284 logger.debug("args[%s]='%s'", type(args), args)
285 status = args.command(args)
287 logger.debug("status=%d - EXIT!", status)
291 logger.debug("Closing database connection ...")
292 database.connection.close()
294 logger.debug("Shutdown completed.")