= Import Custom Smileys from Emesene =

[http://emesene.org/ Emesene] is a client for the MSN protocol. It supports custom smileys, which can be imported into Pidgin using the following script (requires Python 2.5 or later).


{{{
#!/usr/bin/python
#
# Import custom smileys into Pidgin from Emesene 1.0.
# Requires Python 2.5 or later.
#
# Copyright (C) 2009, Danilo Piazzalunga <danilopiazza@gmail.com>
# This file is distributed under the same license as the Pidgin package.
#
# Usage:
# pidgin-import-emesene-smileys.py EMESENE_EMOTICON_MAP [PURPLE_USER_DIR]
#
# EMESENE_EMOTICON_MAP: the custom_emoticons/map file in your emesene
# account directory, to be used as the input file
# For example, $HOME/.config/emesene1.0/*/custom_emoticons/map.
#
# PURPLE_USER_DIR: the libpurple user directory, to be used as output
# directory. Defaults to $HOME/.purple.
#

from __future__ import with_statement

import hashlib
import os.path
import shutil
import sys
import xml.dom.minidom

def usage():
    return ("usage: %s EMESENE_EMOTICON_MAP [PURPLE_USER_DIR]" % sys.argv[0])

def purple_user_dir():
    for dir in [ "$PURPLEHOME", "%APPDATA%", "$HOME", "~" ]:
        purple_dir = os.path.join(
            os.path.expandvars(os.path.expanduser(dir)),
            ".purple")
        if os.path.isdir(purple_dir):
            return purple_dir

def open_cmdline_arg(filename, input=True):
    if filename == "-":
        if input: return sys.stdin
        else: return sys.stdout
    else:
        if input: return open(filename, "U")
        else: return open(filename, "w")

def parse_emesene_map(map):
    smileys = {}

    while True:
        shortcut = map.readline().rstrip("\n")
        if not shortcut: break

        picture_name = map.readline().rstrip("\n")
        smileys[shortcut] = picture_name

    return smileys

def sha1sum(filename):
    with open(filename, "rb") as file:
        data = file.read()

    sha1sum = hashlib.sha1()
    sha1sum.update(data)
    return sha1sum.hexdigest()

def import_smileys(smileys, purple_dir):
    purple_custom_smiley_dir = os.path.join(purple_dir, "custom_smiley")
    purple_smileys_xml = os.path.join(purple_dir, "smileys.xml")

    if not os.path.isdir(purple_custom_smiley_dir):
        os.mkdir(purple_custom_smiley_dir)

    smileys_purple = []

    for shortcut, picture_name in smileys.iteritems():
        checksum = sha1sum(picture_name)
        ext = os.path.splitext(picture_name)[1]
        filename = "".join([checksum, ext])

        shutil.copyfile(picture_name,
                        os.path.join(purple_custom_smiley_dir, filename))

        smileys_purple.append({"shortcut": shortcut,
                               "checksum": checksum,
                               "filename": filename })

    write_purple_smileys_xml(smileys_purple, purple_smileys_xml)

def write_purple_smileys_xml(smileys_purple, purple_smileys_xml):
    dom = xml.dom.minidom.getDOMImplementation()
    doc = dom.createDocument(None, "smileys", None)

    try:
        top_element = doc.documentElement
        top_element.setAttribute("version", "1.0")

        profile_element = doc.createElement("profile")
        profile_element.setAttribute("name", "Default")
        top_element.appendChild(profile_element)

        smiley_set_element = doc.createElement("smiley_set")
        profile_element.appendChild(smiley_set_element)

        for s in smileys_purple:
            smiley_element = doc.createElement("smiley")
            smiley_element.setAttribute("shortcut", s["shortcut"])
            smiley_element.setAttribute("checksum", s["checksum"])
            smiley_element.setAttribute("filename", s["filename"])
            smiley_set_element.appendChild(smiley_element)

        with open(purple_smileys_xml, "w") as writer:
            doc.writexml(writer, addindent="\t", newl="\n")
    finally:
        doc.unlink()

if __name__ == "__main__":
    if len(sys.argv) < 2 or len(sys.argv) > 3:
        sys.exit(usage())

    input_filename = sys.argv[1]
    purple_dir = sys.argv[2] if len(sys.argv) > 2 else purple_user_dir()

    with open_cmdline_arg(input_filename) as map:
        smileys = parse_emesene_map(map)

    import_smileys(smileys, purple_dir)

}}}
