# -*- coding: iso-8859-15 -*-


# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
#     Romain Chantereau <rchantereau@entrouvert.com>
#     Nicolas Clapiès <nclapies@easter-eggs.org>
#     Pierre-Antoine Dejace <padejace@entrouvert.be>
#     Thierry Dulieu <tdulieu@easter-eggs.com>
#     Florent Monnier <monnier@codelutin.com>
#     Cédric Musso <cmusso@easter-eggs.org>
#     Frédéric Péters <fpeters@entrouvert.be>
#     Benjamin Poussin <poussin@codelutin.com>
#     Emmanuel Raviart <eraviart@entrouvert.com>
#     Sébastien Régnier <regnier@codelutin.com>
#     Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
#     Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
#     Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
#     Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
#     Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
#     Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
#     Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.


__doc__ = """Glasnost Gpg Utilities"""

__version__ = '$Revision$'[11:-2]


import os
import urllib

import glasnost


echoPath = '/bin'
gpgPath = '/usr/bin'
gpgServer = 'pgp.mit.edu'
homeDir = '/etc/%s/gnupg' % glasnost.applicationName


class Gpg:
    email = None
    fingerprint = None
    text = None
    uid = None
    
    def __init__(self, email, uid = None, text = None, fingerprint = None):
        self.email = email
        self.uid = uid        
        self.text = text
        self.fingerprint = fingerprint
        if not os.path.exists(gpgPath + '/gpg'):
            raise Exception('GnuPG not installed')
        if not os.path.exists(homeDir):
            raise Exception('GnuPG not configured for the Glasnost user')

    def addKey(self):
        if self.getFingerprint():
            os.system('%s/gpg --homedir %s --keyserver %s --recv-keys %s' %
                      (gpgPath, homeDir, gpgServer, self.getUid()))
        else:
            try:
                data = urllib.urlopen(
                    'http://%s:11371/pks/lookup?op=get&search=%s' %
                    (gpgServer, self.email)).read()
            except IOError:
                return
            pubKey =  data[
                data.find('<pre>') + 5 : - (len(data) - data.rfind('</pre>'))]
            os.system('%s/echo "%s" | %s/gpg --homedir %s --import ' %
                      (echoPath, pubKey, gpgPath, homeDir))

    def deleteKey(self):
        os.system('%s/gpg --homedir %s --yes --batch --delete-key %s' %
                  (gpgPath, homeDir, self.email))

    def encrypt(self, text = None):
        if not text:
            varText = self.text
        else:
            varText = text
        tmpMessage = os.popen(
                '%s/echo "%s" | %s/gpg --homedir %s --yes --encrypt --armor '\
                '--textmode --always-trust  -r %s 2>&1' % (
                        echoPath, varText, gpgPath, homeDir, self.email)).read()
        if not self.isEncrypted(tmpMessage):
            return varText
        else:
            return tmpMessage

    def getFingerprint(self):
        if self.fingerprint:
            return self.fingerprint
        lines = os.popen('%s/gpg --homedir %s --fingerprint %s 2>&1' %
                         (gpgPath, homeDir, self.email)).readlines()
        if not self.isGpgError(lines[0]):
            self.fingerprint = lines[1].split('=')[1].strip()
            return self.fingerprint
        else:
            return None

    def getText(self):
        return self.text

    def getUid(self):
        if self.uid: return self.uid
        if self.fingerprint:
            self.uid = self.fingerprint[-9:].replace(' ','')
            return self.uid
        else:
            return None
        line = os.popen('%s/gpg --homedir %s --list-keys %s 2>&1' %
                        (gpgPath, homeDir, self.email)).readline()
        if not self.isGpgError(lines):
            self.uid = line.split('/')[1][:8]
            return self.uid
        else:
            return None

    def isEncrypted(self, text = None):
        if text:
            varText = text
        else:
            varText = self.text
        return varText.count('-----BEGIN PGP MESSAGE-----') \
               and varText.count('-----END PGP MESSAGE-----')

    def isGpgError(self, result):
        return result.count('gpg: ')

    def isInWallet(self):
        return self.getFingerprint()

    def setFingerprint(self, fingerprint):
        self.fingerprint = fingerprint

    def setText(self, text):
        self.text = text

    def setUid(self, uid):
        self.uid = uid

    def updateKey(self):
        os.system('%s/gpg --homedir %s --keyserver %s  --recv-keys %s' %
                  (gpgPath, homeDir, gpgServer, self.getUid()))

