#/usr/bin/python
# -*- coding: utf-8 -*-

# Script permettant d'envoyer des SMS grâce à Google Agenda.
# Créez un compte google, un nouvel agenda, et configurez-le pour que la notification se fasse par SMS 5 minutes avant l'événement.
# L'idée vient de http://macsim.labolinux.net/index.php/post/2008/02/15/137-smsalert-envoyer-des-sms-gratuitement-depuis-ses-serveurs

# Copyright (C) 2008 Jean-Philippe Brucker — Tous droits réservés.
#
#   Ce programme est un logiciel libre. Vous pouvez le redistribuer ou le
#   modifier suivant les termes de la "GNU General Public License" version 3,
#   telle que publiée par la Free Software Foundation.
#
#   Ce programme est distribué dans l’espoir qu’il vous sera utile, mais SANS
#   AUCUNE GARANTIE : sans même la garantie implicite de COMMERCIALISABILITÉ
#   ni d’ADÉQUATION À UN OBJECTIF PARTICULIER. Consultez la Licence Générale
#   Publique GNU pour plus de détails.
#
#   Ce programme doit être distribué avec une copie de la
#   License Générale Publique GNU (fichier license.html).
#   Si ce n’est pas le cas, consultez: <http://www.gnu.org/licenses/gpl.html>.

import urllib, urllib2
import time
import re
import sys, getopt

# Modifiez ces champs pour vous logger automatiquement.
USER='MyEmail@gmail.com'
PASSWD='MyPassword'
# Ajoutez /private/full à la fin d'une adresse personalisée.
ADRESSE="http://www.google.com/calendar/feeds/default/private/full"

AIDE="""Aide :
Usage : %s [-h] [-e email] [-p pass] [titre [message]]
  -h ou --help : Afficher l'aide.
  -e ou --email : spécifier un compte.
  -p ou --password : spécifier un mot de passe
Et c'est tout.
""" % sys.argv[0]

def parserLdc():
    global title,where, USER, PASSWD
    opts, args=None, None
    try:
        opts, args=getopt.getopt(sys.argv[1:], "he:p:",['help', 'email=', 'password='])
    except getopt.GetoptError, e:
        raise 'Argument «%s» inconnu.' % e.opt
    for option, value in opts:
        if option in ('-h', '--help'):
            print AIDE
            sys.exit(0)
        elif option in ('-e', '--email'):
            USER = value
        elif option in ('-p', '--password'):
            PASSWD = value
    if len(args)==2:
        title = args[0].replace('\'', ' ')
        where = args[1].replace('\'', ' ')
    elif len(args)==1:
        title = args[0].replace('\'', ' ')

class googleCalendar:
    """ Cette classe permet de créer un nouvel événement dans un agenda google."""
    def __init__(self, user, passwd, adress):
        self.user = user
        self.passwd = passwd
        self.adress = adress
        self.auth = ""

    def connect(self):
        url={}
        url['accountType']='GOOGLE'
        url['Email']=self.user
        url['Passwd']=self.passwd
        url['service']='cl'
        url['source']='exampleCo-exampleApp-1'
        page = urllib.urlopen("https://www.google.com/accounts/ClientLogin", urllib.urlencode(url))
        for line in page.readlines():
            if line.find("Auth=")>-1:
                self.auth = line[5:-1]
                return 0
        return 1
    def send(self,settings):
        """ send prend un tuple en argument :
        Settings={}
        Settings['title'] => Affiché dans un SMS
        Settings['content']
        Settings['where'] => Affiché dans un SMS
        Settings['start'] => Le SMS est envoyé 5min avant
        Settings['end']
        """
        if self.connect():
            print "Connexion impossible !"
            return
        Data = """<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'>
        <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event'></category>
        <title type='text'>%s</title>
        <content type='text'>%s</content>
        <author>
          <name>%s</name>
          <email>%s</email>
        </author>
        <gd:transparency value='http://schemas.google.com/g/2005#event.opaque'></gd:transparency>
        <gd:eventStatus value='http://schemas.google.com/g/2005#event.confirmed'></gd:eventStatus>
        <gd:where valueString='%s'></gd:where>
        <gd:when startTime='%s' endTime='%s'><gd:reminder minutes='5' /></gd:when>
        </entry>""" % (settings['title'], settings['content'], self.user, self.user, settings['where'], settings['start'], settings['end'])
        Headers={}
        Headers['Host']='www.google.com'
        Headers['MIME-Version']='1.0'
        Headers['Accept']='text/xml'
        Headers['Authorization']='GoogleLogin auth='+self.auth
        Headers['Content-length']=str(len(Data))
        Headers['Content-type']='application/atom+xml'
        Headers['Cache-Control']='no-cache'
        Headers['Connection']='close \r\n'
        try:
            req = urllib2.Request(self.adress, Data, Headers)
            handler = urllib2.HTTPHandler()#debuglevel=2)
            opener = urllib2.OpenerDirector()
            opener.add_handler(handler)
            page = opener.open(req)

            # Pas joli-joli, tout ça. À améliorer
            lien = re.compile(r'HREF=["\'](.+)["\']').findall(page.read())
            if len(lien)>0:
                req=urllib2.Request(lien[0],Data,Headers)
            else:
                print "Impossible de récupérer l'adresse de redirection."
                return
            opener.open(req)
            print "Événement envoyé."
        except IOError, e:
            print e
            return

def RFC3339(date):
    d=[]
    for i in date:
        d.append(str(i))
    for i in xrange(1,6):
        if len(d[i])<2: d[i]="0"+d[i]
    return d[0]+'-'+d[1]+'-'+d[2]+'T'+d[3]+':'+d[4]+':'+d[5]+'.000Z'

def main():
    global title,where,USER,PASSWD
    title=""
    where=""
    parserLdc()
    while not USER  : USER=raw_input("Entrez votre nom d'utilisateur : ")
    while not PASSWD: PASSWD=raw_input("Entrez votre mot de passe : ")
    while not title : title = raw_input("Entrez un titre : ")
    if not where : where = raw_input("Entrez un message ou tapez [Entrée] pour laisser vide: ")

    event = {'title':title, 'content': "SMS", 'where':where, 'start':RFC3339(time.gmtime(time.time()+60*5+30)), 'end':RFC3339(time.gmtime(time.time()+60*5+45))}

    cal = googleCalendar(USER, PASSWD, ADRESSE)
    cal.send(event)
if __name__=="__main__": main()
