collect blocklists and merge them with weights per source

This commit is contained in:
Tobias Diekershoff 2023-01-07 16:37:42 +01:00
parent bbb67e9d7e
commit 6eb4ceb7d2
1 changed files with 83 additions and 1 deletions

View File

@ -1,4 +1,86 @@
#!env python3
# SPDX-FileCopyrightText: 2023 Tobias Diekershoff
#
# SPDX-License-Identifier: CC0-1.0
# SPDX-License-Identifier: GPL-3.0-or-later
"""
This script can be used to create server block lists by compining the blocklists
of any number of other Friendica instances.
"""
import argparse
import configparser
import sys
from os.path import exists
import requests
class BrewBlocklist():
"""
This is the cauldron that is used to
* collect the blocklists from other servers
* rank the blocklists by their trustworthyness
* compile a the resulting blocklist
"""
def __init__(self, configfile, outputfile):
"""
Initialise the cauldron with the filenames of the config file
and the outputfilename.
"""
self.sources = []
config = configparser.RawConfigParser()
config.read(configfile)
for section in config.sections():
section_values = dict(config.items(section))
self.sources.append({'url': section, 'trust': int(section_values['trust'])})
self.outputfile = outputfile
self.blocklist = {}
self.reasons = {}
def collect_ingrediens(self):
"""
Use request.get to collect the blocklists from the Friendica nodes provided
in the config file. Collect the reasons why to block the servers (the first
mention of the server wins) and sum the trust levels of the blocks.
"""
for source in self.sources:
requ = requests.get('https://{}/blocklist/domain/download'.format(source['url']))
for line in requ.text.split('\n'):
try:
pattern, reason = line.split(',')
except ValueError:
break
self.blocklist[pattern] = self.blocklist.get(pattern, 0) + source['trust']
self.reasons[pattern] = self.reasons.get(pattern, reason)
def serve_meal(self):
"""
Print the CSV list of the collected blocklist into either STDOUT or
the output file that was defined as command line parameter.
"""
print(self.outputfile, not self.outputfile)
if self.outputfile:
out_file = open(self.outputfile, 'w')
orig_stdout = sys.stdout
sys.stdout = out_file
for key, value in self.blocklist.items():
print('{}, {}, {}'.format(key, self.reasons[key], value))
if self.outputfile:
sys.stdout = orig_stdout
out_file.close()
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-c', '--config',
dest='configfile',
required=True,
help='specify the configuration file')
parser.add_argument('-o', '--output',
dest='outputfile',
default=None,
help='specify the output file. STDOUT if none given')
args = parser.parse_args()
if not exists(args.configfile):
print('The config file {} was not found.'.format(args.configfile))
sys.exit()
brew = BrewBlocklist(args.configfile, args.outputfile)
brew.collect_ingrediens()
brew.serve_meal()