adding initial version
commit
79dac3aa1a
|
@ -0,0 +1,19 @@
|
||||||
|
hsldap2vcard
|
||||||
|
============
|
||||||
|
|
||||||
|
hsldap2vcard is a script for creating vCard_ contact files from
|
||||||
|
`Warsaw Hackerspace`_ LDAP membership database.
|
||||||
|
|
||||||
|
.. _vCard: https://tools.ietf.org/html/rfc6350
|
||||||
|
.. _Warsaw Hackerspace: https://hackerspace.pl
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
.. code:: bash
|
||||||
|
|
||||||
|
# create output directory
|
||||||
|
mkdir -p ~/.contacts/hs/
|
||||||
|
|
||||||
|
# create vCard files:
|
||||||
|
hsldap2vcard ~/.contacts/hs/
|
|
@ -0,0 +1,11 @@
|
||||||
|
{ pkgs ? import <nixpkgs> {} }:
|
||||||
|
|
||||||
|
pkgs.python3Packages.buildPythonPackage {
|
||||||
|
pname = "hsldap2vcard";
|
||||||
|
version = "1.0";
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
propagatedBuildInputs = with pkgs; [ python3Packages.ldap ];
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
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}")
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
|
@ -0,0 +1,21 @@
|
||||||
|
from setuptools import setup
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name="hsldap2vcard",
|
||||||
|
version="1.0",
|
||||||
|
description="create vCard's from Warsaw Hackerspace LDAP",
|
||||||
|
author="Jan Wiśniewski",
|
||||||
|
author_email="vuko@hackerspace.pl",
|
||||||
|
classifiers=[
|
||||||
|
"License :: OSI Approved :: zlib/libpng License",
|
||||||
|
"Programming Language :: Python :: 3.7",
|
||||||
|
],
|
||||||
|
packages=["hsldap2vcard"],
|
||||||
|
python_requires=">=3.6,",
|
||||||
|
install_requires=["python-ldap"],
|
||||||
|
entry_points={
|
||||||
|
"console_scripts": [
|
||||||
|
"hsldap2vcard=hsldap2vcard:run",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
)
|
Loading…
Reference in New Issue