122 lines
3.4 KiB
Python
122 lines
3.4 KiB
Python
import argparse
|
|
import re
|
|
import datetime
|
|
import getpass
|
|
import subprocess
|
|
import ldap
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def normalize_mobile(mobile):
|
|
mobile = mobile.replace(" ", "").replace("-", "")
|
|
if re.fullmatch("^[0-9]{9}$", mobile):
|
|
mobile = f"+48{mobile}"
|
|
elif re.fullmatch("^[0-9]{11}$", mobile):
|
|
mobile = f"+{mobile}"
|
|
elif re.fullmatch("^\+[0-9]*$", mobile):
|
|
pass
|
|
elif uid == "daz":
|
|
pass
|
|
else:
|
|
raise ValueError("invalid moble: {mobile}")
|
|
return mobile
|
|
|
|
class HsLdap:
|
|
def __init__(self, uid, password):
|
|
if password is None:
|
|
pw = getpass.getpass(prompt="LDAP password:")
|
|
else:
|
|
pw = str(password)
|
|
|
|
me = "uid={:s},ou=People,dc=hackerspace,dc=pl".format(str(uid))
|
|
|
|
self.l = ldap.initialize("ldap://hackerspace.pl")
|
|
self.l.simple_bind_s(me, pw)
|
|
|
|
def get_vcards(self):
|
|
members = []
|
|
filterstr = "(objectClass=hsMember)"
|
|
space = self.l.search_s(
|
|
"ou=People,dc=hackerspace,dc=pl",
|
|
ldap.SCOPE_ONELEVEL,
|
|
filterstr=filterstr,
|
|
attrlist=["givenName", "sn", "uid", "mobile"],
|
|
)
|
|
|
|
for ui, s in space:
|
|
|
|
def get(name, default=None):
|
|
if name in s:
|
|
return s[name][0].decode()
|
|
else:
|
|
return default
|
|
|
|
uid = get("uid")
|
|
name = get("givenName", "")
|
|
sn = get("sn", "")
|
|
mobile = get("mobile")
|
|
rev = datetime.datetime.now().strftime("%Y%d%mT%H%M%SZ")
|
|
|
|
vcard = []
|
|
vcard.extend(
|
|
[
|
|
"BEGIN:VCARD",
|
|
"VERSION:4.0",
|
|
f"UID:mailto:{uid}@hackerspace.pl",
|
|
"CATEGORIES:hswaw",
|
|
f"FN:{uid}",
|
|
f"NICK:{uid}",
|
|
f"N:{uid};{name};{sn}",
|
|
f"REV:{rev}",
|
|
]
|
|
)
|
|
|
|
if "mobile" in s and uid != "daz":
|
|
assert len(s["mobile"]) == 1
|
|
mobile = get("mobile")
|
|
mobile = normalize_mobile(get("mobile"))
|
|
vcard.append(f"TEL;TYPE=cell:{mobile}")
|
|
|
|
vcard.extend(["END:VCARD"])
|
|
yield uid, "\n".join(vcard)
|
|
|
|
|
|
def run():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("output", type=Path, help="vcards output directory")
|
|
parser.add_argument(
|
|
"--ldap-user", default=getpass.getuser(), help="hs ldap username"
|
|
)
|
|
parser.add_argument("--ldap-pass", default=None, help="hs ldap password")
|
|
|
|
args = parser.parse_args()
|
|
|
|
if not args.output.exists():
|
|
print("ERROR: output directory does not exist", file=sys.stderr)
|
|
exit(1)
|
|
|
|
if not args.output.is_dir():
|
|
print("ERROR: output argument must be a directory", file=sys.stderr)
|
|
exit(1)
|
|
|
|
try:
|
|
l = HsLdap(
|
|
args.ldap_user,
|
|
args.ldap_pass or getpass.getpass(f"LDAP password for {args.ldap_user}: "),
|
|
)
|
|
except ldap.INVALID_CREDENTIALS:
|
|
print("ERROR: authorization error", file=sys.stderr)
|
|
exit(1)
|
|
|
|
written = 0
|
|
for uid, vcard in l.get_vcards():
|
|
args.output.joinpath(f"{uid}.vcf").write_text(vcard)
|
|
written += 1
|
|
|
|
print(f'Written {written} vcards files into "{args.output}"', file=sys.stderr)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
run()
|