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("--force", action="store_true", help="Forces update of data, no matter what.")
94 ### Fetch blocks from chaos.social ###
95 parser = subparser_command.add_parser(
97 help="Fetches blocks from chaos.social's meta sub domain.",
99 parser.set_defaults(command=commands.fetch_cs)
101 ### Fetch blocks from todon.eu wiki ###
102 parser = subparser_command.add_parser(
104 help="Fetches blocks from todon.eu's wiki.",
106 parser.set_defaults(command=commands.fetch_todon_wiki)
108 ### Fetch blocks from a FBA-specific RSS feed ###
109 parser = subparser_command.add_parser(
111 help="Fetches domains from a FBA-specific RSS feed.",
113 parser.set_defaults(command=commands.fetch_fba_rss)
114 parser.add_argument("--feed", required=True, help="RSS feed to fetch domains from (e.g. https://fba.ryoma.agency/rss?domain=foo.bar).")
116 ### Fetch blocks from FBA's bot account ###
117 parser = subparser_command.add_parser(
119 help="Fetches ATOM feed with domains from FBA's bot account.",
121 parser.set_defaults(command=commands.fetch_fbabot_atom)
122 parser.add_argument("--feed", required=True, help="RSS feed to fetch domains from (e.g. https://fba.ryoma.agency/rss?domain=foo.bar).")
124 ### Fetch blocks from oliphant's GIT repository ###
125 parser = subparser_command.add_parser(
127 help="Fetches CSV files (block recommendations) for more possible instances to disover",
129 parser.set_defaults(command=commands.fetch_oliphant)
130 parser.add_argument("--domain", help="Instance name (aka. domain) to check")
132 ### Fetch blocks from other CSV files
133 parser = subparser_command.add_parser(
135 help="Fetches CSV files (block recommendations) for more possible instances to disover",
137 parser.set_defaults(command=commands.fetch_csv)
138 parser.add_argument("--domain", help="Instance name (aka. domain) to check")
140 ### Fetch instances from given initial instance ###
141 parser = subparser_command.add_parser(
143 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.",
145 parser.set_defaults(command=commands.fetch_instances)
146 parser.add_argument("--domain", required=True, help="Instance name (aka. domain) to fetch further instances from. Start with a large instance, e.g. mastodon.social .")
147 parser.add_argument("--single", action="store_true", help="Only fetch given instance.")
149 ### Fetch blocks from static text file(s) ###
150 parser = subparser_command.add_parser(
152 help="Fetches text/plain files as simple domain lists",
154 parser.set_defaults(command=commands.fetch_txt)
156 ### Fetch blocks from joinfediverse.wiki ###
157 #parser = subparser_command.add_parser(
158 # "fetch_joinfediverse",
159 # help="Fetches FediBlock page from joinfediverse.wiki",
161 #parser.set_defaults(command=commands.fetch_joinfediverse)
163 ### Fetch instances JSON from instances.joinmobilizon.org
164 parser = subparser_command.add_parser(
165 "fetch_joinmobilizon",
166 help="Fetches instances from joinmobilizon",
168 parser.set_defaults(command=commands.fetch_joinmobilizon)
170 ### Fetch blocks from misskey.page ###
171 parser = subparser_command.add_parser(
173 help="Fetches instances.json from misskey.page",
175 parser.set_defaults(command=commands.fetch_joinmisskey)
177 ### Fetch blocks from fediverse.observer ###
178 parser = subparser_command.add_parser(
180 help="Fetches blocks from fediverse.observer.",
182 parser.set_defaults(command=commands.fetch_observer)
183 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
185 ### Fetch instances from fedipact.online ###
186 parser = subparser_command.add_parser(
188 help="Fetches blocks from fedipact.online.",
190 parser.set_defaults(command=commands.fetch_fedipact)
192 ### Fetch from pixelfed.org's API ###
193 parser = subparser_command.add_parser(
194 "fetch_pixelfed_api",
195 help="Fetches domain names from pixelfed.org's API",
197 parser.set_defaults(command=commands.fetch_pixelfed_api)
199 ### Check nodeinfo ###
200 parser = subparser_command.add_parser(
202 help="Checks if domain is part of nodeinfo.",
204 parser.set_defaults(command=commands.check_nodeinfo)
206 ### Fetch CSV from fedilist.com ###
207 parser = subparser_command.add_parser(
209 help="Fetches CSV from fedilist.com",
211 parser.set_defaults(command=commands.fetch_fedilist)
212 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
213 parser.add_argument("--force", action="store_true", help="Include also already existing instances, otherwise only new are checked")
215 ### Update nodeinfo ###
216 parser = subparser_command.add_parser(
218 help="Updates nodeinfo for all instances",
220 parser.set_defaults(command=commands.update_nodeinfo)
221 parser.add_argument("--domain", help="Instance name (aka. domain)")
222 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
223 parser.add_argument("--mode", help="Name of detection mode, e.g. 'auto_discovery'")
224 parser.add_argument("--force", action="store_true", help="Forces update of data, no matter what.")
225 parser.add_argument("--no-software", action="store_true", help="Checks only entries with no software type detected.")
226 parser.add_argument("--no-auto", action="store_true", help="Checks only entries with other than AUTO_DISCOVERY as detection mode.")
227 parser.add_argument("--no-detection", action="store_true", help="Checks only entries with no detection mode set.")
229 ### Fetch instances from instances.social ###
230 parser = subparser_command.add_parser(
231 "fetch_instances_social",
232 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!",
234 parser.set_defaults(command=commands.fetch_instances_social)
236 ### Convert international domain names to punycode domains ###
237 parser = subparser_command.add_parser(
239 help="Convertes UTF-8 encoded international domain names into punycode (IDNA) domain names.",
241 parser.set_defaults(command=commands.convert_idna)
243 ### Fetch instances from ActivityPub relays ###
244 parser = subparser_command.add_parser(
246 help="Fetches instances from ActivityPub relays",
248 parser.set_defaults(command=commands.fetch_relays)
249 parser.add_argument("--domain", help="Instance name (aka. 'relay')")
250 parser.add_argument("--software", help="Name of software, e.g. 'lemmy'")
251 parser.add_argument("--force", action="store_true", help="Forces update of data, no matter what.")
253 ### Remove invalid domains ###
254 parser = subparser_command.add_parser(
256 help="Removes invalid domains.",
258 parser.set_defaults(command=commands.remove_invalid)
260 logger.debug("EXIT!")
263 logger.debug("CALLED!")
264 args = _PARSER.parse_args()
266 if args.log_level is not None:
267 loggers = [logging.getLogger(name) for name in logging.root.manager.loggerDict]
268 for _logger in loggers:
269 _logger.setLevel(args.log_level)
271 logger.debug("args[%s]='%s'", type(args), args)
272 status = args.command(args)
274 logger.debug("status=%d - EXIT!", status)
278 logger.debug("Closing database connection ...")
279 database.connection.close()
281 logger.debug("Shutdown completed.")