#!/usr/bin/python

import re
import sys
import os

from twill import commands, browser
from getpass import getpass
from cStringIO import StringIO

LOGIN = '0479378279'
URL_SUBSCRIBE = 'http://subscribe.free.fr/login/'
URL_PHONE_PANEL = 'http://adsl.free.fr/admin/tel/adminservice.pl?%s'
PASSWORD_FILENAME = '~/.freesip'

class FreeShitSIPWorkaround(object):
    def __init__(self, login, password, target_phone_number):
        self.__login = login
        self.__password = password
        self.__target_phone_number = target_phone_number
        self.__session_infos = None

        # Get rid of twill verbose output...
        self.verbose_output = StringIO()
        commands.OUT = browser.OUT = self.verbose_output

    def login(self, target_url=None):
        commands.go(URL_SUBSCRIBE)
        commands.formvalue(1, 'login', self.__login)
        commands.formvalue(1, 'pass', self.__password)
        commands.submit()
        commands.code(200)

	current_url = commands.browser.get_url()
	if current_url.startswith(URL_SUBSCRIBE):
	    raise RuntimeError, 'Invalid password given!'

        # Once  logged in,  store the  informations needed  to perform
        # further requests
	try:
	    self.__session_infos = re.match('http://[^?]*\?(id=\w*&idt=\w*)', current_url).group(1)
	except AttributeError:
	    raise RuntimeError, 'Unable to log in, current URL was: %s' % current_url

        if target_url is not None:
            commands.go(target_url % self.__session_infos)

    def submit_request(func):
        def inner(self, *args, **kwargs):
            if self.__session_infos is None:
                self.login(URL_PHONE_PANEL)
            else:
                commands.go(URL_PHONE_PANEL % self.__session_infos)

            # Check  for timeout,  login again  if necessary  and load
            # phone panel page
            if commands.browser.get_url().startswith(URL_SUBSCRIBE):
                self.login(URL_PHONE_PANEL)

            func(self)
            commands.submit()
            commands.code(200)                                      

        return inner

    @submit_request
    def set_target_phone_number(self):
        commands.formvalue(1, 'transrep', 'true')
        commands.formvalue(1, 'nonrep', self.__target_phone_number)

    @submit_request
    def unset_target_phone_number(self):
        commands.formvalue(1, 'transrep', 'false')

def get_password():
    """
    Try to  get the password from  the file, otherwise  prompt for the
    password
    """
    password_filename = os.path.expanduser(PASSWORD_FILENAME)
    password = None

    if os.path.exists(password_filename):
        try:
            password_file = open(password_filename)
            password = password_file.readline().strip(' \n')
            password_file.close()
        except IOError:
            print >>sys.stderr, 'Unable to get password from %s' % password_filename

    if password is None:
        try:
            password = getpass('Please enter the SIP password: ')
        except KeyboardInterrupt:
            sys.exit(0)

    return password

def main():
    try:
        target_phone_number = sys.argv[1].strip()
    except IndexError:
        print >>sys.stderr, '[ERROR]: Need a target phone number!'
        sys.exit(1)

    free_sip = FreeShitSIPWorkaround(LOGIN, get_password(), target_phone_number)

    try:
	free_sip.set_target_phone_number()
	raw_input('Press enter to unset target phone number.')
	free_sip.unset_target_phone_number()
    except RuntimeError, e:
	print >>sys.stderr, '[ERROR]: %s' % e
        print free_sip.verbose_output.readlines()
	sys.exit(2)

if __name__ == '__main__':
    main()

