diff --git a/src/vm_contacts.py b/src/vm_contacts.py
index 0ddafeb..1b04c43 100644
--- a/src/vm_contacts.py
+++ b/src/vm_contacts.py
@@ -2,11 +2,9 @@
"""
Caller-ID -> contact name resolution for Asterisk voicemail notifications.
-Backends (tried in the order given by contacts.conf 'backends='):
+Backends (contacts are resolved exclusively from the MySQL `contacts` table
+on the asterisk DB):
mysql - MySQL contacts table on the asterisk DB (primary, fast, offline).
- file - local vCard (.vcf) or CSV export; no auth, offline, fast.
- google - Google People API via the Hermes OAuth token.
- carddav - generic CardDAV with username + app password.
Everything here is best-effort: a lookup failure returns None and the caller
falls back to the raw caller-ID string. Results (hits AND misses) are cached
@@ -393,7 +391,7 @@ def lookup_carddav(cfg, num_digits, n, log):
# ---------------------------------------------------------------- entrypoint
-_BACKENDS = {"mysql": lookup_mysql, "file": lookup_file, "google": lookup_google, "carddav": lookup_carddav}
+_BACKENDS = {"mysql": lookup_mysql}
def resolve(caller_id, log=print):
diff --git a/src/vm_web.py b/src/vm_web.py
index 89ea30f..d6b092f 100644
--- a/src/vm_web.py
+++ b/src/vm_web.py
@@ -178,8 +178,9 @@ td{padding:6px 0;vertical-align:top}
def page(title, body, mailbox=None, name=None):
nav = ""
if mailbox:
- nav = ('MessagesSettings'
- 'Log out' % (BASE, BASE, BASE))
+ nav = ('MessagesContacts'
+ 'Settings'
+ 'Log out' % (BASE, BASE, BASE, BASE))
return HTMLResponse("""
' % escape(msg) if msg else ""
+ name = escape((c["name"] if c else ""))
+ num = escape((vm_contacts.normalize_uk(vm_contacts.digits_of(c["number_e164"]))
+ if c and c.get("number_e164") else ""))
+ email_val = escape((c["email"] or "") if c else "")
+ if action == "edit":
+ title = "Edit contact"
+ submit = "Save"
+ extra = ('' % c["id"])
+ else:
+ title = "New contact"
+ submit = "Create"
+ extra = ""
+ return """%s
+
""" % (banner, BASE, extra, name, num, email_val, BASE, submit)
+
+
+@app.get("/contacts", response_class=HTMLResponse)
+def contacts_list(vm_session: str = Cookie(default=None), msg: str = ""):
+ mb = require(vm_session)
+ con = vm_store.connect()
+ total = con.execute("SELECT COUNT(*) c FROM contacts").fetchone()["c"]
+ rows = con.execute(
+ "SELECT id, number_e164, name, email, updated_at FROM contacts "
+ "ORDER BY name ASC, id DESC"
+ ).fetchall()
+ con.close()
+
+ banner = '
%s
' % escape(msg) if msg else ""
+ if not rows:
+ return page("Contacts", banner + '
'
+ 'No contacts yet. Use the button below to import from your '
+ 'address book, or add them one by one.
']
+
+ for r in rows:
+ num = escape(r.get("number_e164") or "")
+ who = escape(r["name"] or "Unnamed")
+ em = escape(r.get("email") or "")
+ out.append("