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