aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/blimp/__init__.py14
-rw-r--r--src/blimp/bl_process.py54
-rw-r--r--src/blimp/cli.py16
-rw-r--r--src/blimp/main.py115
-rw-r--r--src/blimp/misc.py17
5 files changed, 216 insertions, 0 deletions
diff --git a/src/blimp/__init__.py b/src/blimp/__init__.py
new file mode 100644
index 0000000..5486de7
--- /dev/null
+++ b/src/blimp/__init__.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# version
+__version__ = "0.1"
+
+# main
+from .main import BlacklistImporter
+
+# modules
+from .bl_process import ProcessBlocklist
+
+# utils
+from .misc import *
diff --git a/src/blimp/bl_process.py b/src/blimp/bl_process.py
new file mode 100644
index 0000000..e1d8c93
--- /dev/null
+++ b/src/blimp/bl_process.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import sys
+
+from ruamel.yaml import YAML, scalarstring
+
+from .misc import *
+
+class ProcessBlocklist:
+ def process(self, blacklist, outfile, dryrun: bool):
+ """
+ function to build and compare the local yaml file to the remote file
+ if the remote file is different, the local file gets overwritten
+ """
+ # cheeky none catch
+ try:
+ # load local blacklist outfile
+ if local_file_present(outfile):
+ with open(outfile, "r", encoding="utf-8") as local_file:
+ local_blacklist = local_file.read()
+
+ print("step local file")
+
+ except TypeError:
+ # no local copy use empty one instead
+ local_blacklist = YAML(typ="safe")
+
+ # blacklist frame
+ remote_file = {"acl": {"spamblacklist": {"server": []}}}
+
+ # build the blacklist with the given frame to compare to local blacklist
+ for entry in blacklist.split():
+ entry = scalarstring.DoubleQuotedScalarString(entry)
+ remote_file["acl"]["spamblacklist"]["server"].append(entry)
+
+ yml = YAML()
+ yml.indent(offset=2)
+ yml.default_flow_style = False
+
+ # if dry-run true print expected content
+ if dryrun:
+ yml.dump(remote_file, sys.stdout)
+ return
+
+ if local_blacklist == remote_file:
+ return
+
+ if outfile is None:
+ print("no outfile assigned", file=sys.stderr)
+ sys.exit(2)
+
+ # proceed to update the defined outfile
+ with open(outfile, "w", encoding="utf-8") as new_local_file:
+ yml.dump(remote_file, new_local_file)
diff --git a/src/blimp/cli.py b/src/blimp/cli.py
new file mode 100644
index 0000000..b462918
--- /dev/null
+++ b/src/blimp/cli.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+import argparse
+
+from .main import BlacklistImporter
+
+
+def cli():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-out", "--outfile", help="set path to output file", action="store", default=None)
+ parser.add_argument("-dr", "--dry-run", help="perform a dry run", action="store_true", default=False)
+ args = parser.parse_args()
+
+ # run
+ BlacklistImporter(args).main()
diff --git a/src/blimp/main.py b/src/blimp/main.py
new file mode 100644
index 0000000..5d4c3ac
--- /dev/null
+++ b/src/blimp/main.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+import argparse
+
+import requests
+from appdirs import *
+
+from .bl_process import ProcessBlocklist
+from .misc import *
+
+
+class BlacklistImporter:
+ def __init__(self, args):
+ self.outfile = args.outfile
+ self.dryrun = args.dry_run
+ self.path = Path(user_cache_dir("blimp"))
+ self.url = "https://raw.githubusercontent.com/JabberSPAM/blacklist/master/blacklist.txt"
+ self.blacklist = ""
+ self.apply_changes = False
+
+ self.etag_path = self.path.joinpath(".etag")
+ self.blacklist_path = self.path.joinpath("blacklist.txt")
+
+ def cache_dir_check(self):
+ if not self.path.is_dir():
+ Path(self.path).mkdir(parents=True, exist_ok=True)
+
+ def download_required(self, etag) -> bool:
+ """
+ method to determine if a new download should be initiated
+ :param etag: requests etag object
+ :return: true if download is required
+ """
+ # always trigger download if any local cache file is missing
+ if not local_file_present(self.blacklist_path):
+ return True
+
+ if not local_file_present(self.etag_path):
+ return True
+
+ # etag file is present but outdated
+ else:
+ with open(self.etag_path, "r") as local_file:
+ local_etag = local_file.read()
+
+ if local_etag != etag:
+ return True
+
+ return False
+
+ def start_request(self):
+ """
+ determine if the download is required
+ """
+ with requests.Session() as s:
+ # head request to check etag
+ head = s.head(self.url)
+ etag = head.headers["etag"]
+
+ if head.status_code != requests.codes.ok:
+ return
+
+ if not self.download_required(etag):
+ with open(self.blacklist_path, "r", encoding="utf-8") as local_file:
+ self.blacklist = local_file.read()
+
+ else:
+ r = s.get(self.url)
+ r.encoding = "utf-8"
+ local_etag = head.headers["etag"]
+ self.blacklist = r.content.decode()
+
+ with open(self.blacklist_path, "w", encoding="utf-8") as local_file:
+ local_file.write(self.blacklist)
+
+ with open(self.etag_path, "w", encoding="utf-8") as local_file:
+ local_file.write(local_etag)
+
+ def main(self):
+ # check the cache dir first
+ self.cache_dir_check()
+
+ # only output the selected outfile
+ if self.dryrun:
+ print("outfile selected: %s" % self.outfile)
+
+ # go
+ self.start_request()
+
+ # blacklist processing
+ ProcessBlocklist().process(self.blacklist, self.outfile, self.dryrun)
+
+ """# reload config if changes have been applied
+ if self.change:
+ # catch ejabberdctl missing
+ if Path("/usr/sbin/ejabberdctl").is_file():
+ subprocess.call(["/usr/sbin/ejabberdctl", "reload_config"], shell=False)
+
+ # report missing ejabberdctl reload_config
+ else:
+ print("/usr/sbin/ejabberdctl was not found", file=sys.stderr)
+ print("blacklist changes have been applied\nejabberd config was not reloaded", file=sys.stderr)
+ sys.exit(1)
+"""
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-out", "--outfile", help="set path to output file", action="store", default=None)
+ parser.add_argument("-dr", "--dry-run", help="perform a dry run", action="store_true", default=False)
+ args = parser.parse_args()
+
+ # run
+ BlacklistImporter(args).main()
diff --git a/src/blimp/misc.py b/src/blimp/misc.py
new file mode 100644
index 0000000..d25c8d7
--- /dev/null
+++ b/src/blimp/misc.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+from pathlib import Path
+
+
+def local_file_present(somepath) -> bool:
+ """
+ check local etag copy
+ :return: true if present
+ """
+ if not Path(somepath).is_file():
+ return False
+
+ return True
+
+def asd():
+ print("yo")