modules/mod_iq_vcard.py
# coding: utf-8
# This file is a part of VK4XMPP transport
# © simpleApps, 2014 — 2016.
from __main__ import *
from __main__ import _
VCARD_SEMAPHORE = threading.Semaphore()
DESCRIPTION = "VK4XMPP Transport\n© simpleApps, 2013 — 2016."
GITHUB_URL = "https://github.com/mrDoctorWho/vk4xmpp"
BIRTHDAY = "30.08.2013"
KEY_NICKNAME = "NICKNAME"
KEY_NAME = "FN"
KEY_DESC = "DESC"
KEY_PHOTO = "PHOTO"
KEY_BINVAL = "BINVAL"
KEY_URL = "URL"
KEY_ADR = "ADR"
KEY_HOME = "HOME"
KEY_BDAY = "BDAY"
KEY_CTRY = "CTRY"
KEY_PHONE_HOME = "HOME"
KEY_PHONE_MOBILE = "MOBILE"
KEY_TEL = "TEL"
KEY_NUMBER = "NUMBER"
KEY_VOICE = "VOICE"
KEY_LOCALITY = "LOCALITY"
if AdditionalAbout:
DESCRIPTION = "%s\n%s" % (DESCRIPTION, AdditionalAbout)
# Vcard defaults
VCARD_TEMPLATE = {KEY_NICKNAME: IDENTIFIER["short"],
KEY_NAME: IDENTIFIER["name"],
KEY_DESC: DESCRIPTION,
KEY_PHOTO: URL_VCARD_NO_IMAGE,
KEY_URL: GITHUB_URL,
KEY_BDAY: BIRTHDAY,
KEY_CTRY: "United States", # database.getCountriesById and database.getCitiesById
KEY_PHONE_HOME: None,
KEY_PHONE_MOBILE: None,
KEY_LOCALITY: {"title": "Los Angeles"} # you'd love it here (yeah, here...)
}
VCARD_FIELDS = {KEY_NICKNAME: "screen_name",
KEY_NAME: "name",
KEY_URL: "https://vk.com/id%(id)s",
KEY_BDAY: "bdate",
KEY_CTRY: "country",
KEY_LOCALITY: "city",
KEY_PHONE_HOME: "home_phone",
KEY_PHONE_MOBILE: "mobile_phone",
KEY_URL: "site",
KEY_PHOTO: PhotoSize,
KEY_DESC: None,
}
def buildVcard(data, template=VCARD_TEMPLATE, fields=VCARD_FIELDS, user=None):
"""
Builds a vcard.
Uses VCARD_TEMPLATE as the base, then adds values from data.
Values from data are get with the help of the VCARD_FIELDS dict.
Args:
data: users.get result
user: the user object
Returns:
The user's VCARD.
"""
vcard = xmpp.Node("vCard", {"xmlns": xmpp.NS_VCARD})
for key, value in template.iteritems():
value = data.get(fields[key], value)
if key == KEY_PHOTO:
photo = vcard.setTag(KEY_PHOTO)
photo.setTagData(KEY_BINVAL, utils.getLinkData(value))
elif key in (KEY_CTRY, KEY_LOCALITY) and value:
adr = vcard.getTag(KEY_ADR) or vcard.setTag(KEY_ADR)
adr.setTagData(key, value.get("title"))
elif key == KEY_PHONE_MOBILE and value:
tel = vcard.getTag(KEY_TEL) or vcard.setTag(KEY_TEL)
tel.setTagData(KEY_NUMBER, value)
elif key == KEY_PHONE_HOME and value:
tel = vcard.getTag(KEY_TEL) or vcard.setTag(KEY_TEL)
tel.setTagData(KEY_PHONE_HOME, value)
elif key == KEY_BDAY and value:
if value.count(".") == 1:
value += time.strftime(".%Y")
value = time.strftime("%Y-%m-%d", time.strptime(value, "%d.%m.%Y"))
vcard.setTagData(key, value)
elif value and value != "None":
vcard.setTagData(key, value)
return vcard
@utils.threaded
def vcard_handler(cl, iq):
# Vcard feature makes transport hang (especially the photo part)
# Many clients love to query vcards so much, so the solution was in adding a semaphore here and sleep() at the bottom
# This is probably not a good idea, but for now this is the best one
with VCARD_SEMAPHORE:
jidFrom = iq.getFrom()
jidTo = iq.getTo()
source = jidFrom.getStripped()
destination = jidTo.getStripped()
result = iq.buildReply("result")
logger.debug("got vcard request to %s (jid: %s)", destination, source)
if destination == TransportID:
template = VCARD_TEMPLATE.copy()
vcard = buildVcard(template, template, template)
result.setPayload([vcard])
elif source in Users:
user = Users[source]
if user.friends:
id = vk2xmpp(destination)
args = ("screen_name", "bdate", "city", "country", "contacts", "home_town", "site", PhotoSize) # todo: a feature to show the user's site instead of their URL?
data = user.vk.getData(id, args)
data["id"] = id
if not user.settings.use_nicknames:
data["screen_name"] = data["name"]
vCard = buildVcard(data, VCARD_TEMPLATE, VCARD_FIELDS, user)
result.setPayload([vCard])
else:
result = utils.buildIQError(iq, xmpp.ERR_BAD_REQUEST, _("Your friend-list is empty."))
else:
result = utils.buildIQError(iq, xmpp.ERR_REGISTRATION_REQUIRED, _("You're not registered for this action."))
sender(cl, result)
MOD_TYPE = "iq"
MOD_HANDLERS = ((vcard_handler, "get", xmpp.NS_VCARD, False),)
MOD_FEATURES = [xmpp.NS_VCARD]