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

"""Modulo para identificar dispositivos conectados"""

try:
    from pymetrick.version import __author__, __version__, __license__, __copyright__
except ImportError:
    raise ImportError(
        'Failed to find (autogenerated) version.py '
    )

__date__ = '2012-09-21'
__credits__ = ''
__text__ = 'Identificacion de dispositivos conectados'
__file__ = 'device.py'

#--- CHANGES ------------------------------------------------------------------
# 2012-09-21 v0.01 PL: - First version


import sys
import os
import time
import logging
from pymetrick.sqldb import *
from pymetrick.common import OS_LIST,BROWSER_LIST,ENGINE_LIST,DEVICE_LIST,LANGUAGE_LIST,COUNTRY_CODES,COUNTRY_CODES3,COUNTRY_NAMES

# Version PY
PY2 = True if sys.version[:1] == '2' else False;
PY3 = True if sys.version[:1] == '3' else False;

# En Python 3  long = int
if PY3:
    long = int

# is mobile (agent string)
def real_device(_environ_):
    '''Detectar varios parametros de un dispositivo remoto conectado como son:
       Motor, Navegador, Sistema Operativo, tipo de dispositivo: Desktop,Tablet o Movil
       Tipo de pantalla ( mediante javascript en la primera pantalla )
       Idioma, direccion IP y hora de la zona
    '''
    device = {}
    device = {'os':'','browser':'','engine':'','device':'Desktop','language':'es','screen':'','ipaddr':'','iso_code2':'','country':''}
    i = _environ_['HTTP_USER_AGENT']
    for m in sorted(OS_LIST.iterkeys()):
        if i.lower().find(m.lower()[3:])>-1:
            device['os']=OS_LIST[m]
            break
    for m in sorted(BROWSER_LIST.iterkeys()):
        if i.lower().find(m.lower()[3:])>-1:
            device['browser']=BROWSER_LIST[m]
            break
    for m in sorted(ENGINE_LIST.iterkeys()):
        if i.lower().find(m.lower()[3:])>-1:
            device['engine']=ENGINE_LIST[m]
            break
    for m in sorted(DEVICE_LIST.iterkeys()):
        if i.lower().find(m.lower()[3:])>-1:
            device['device']=DEVICE_LIST[m]
            break
    _lng = Detect_language(_environ_)
    if _lng:
        device['language'] = _lng
    _ip = Detect_IP(_environ_)
    if _ip:
        device['ipaddr'] = _ip
        ipaddr_country = IP_From(device['ipaddr'])
        device['iso_code2']=ipaddr_country
    return device

def Detect_language(_environ_):
    '''Detectar el idioma de un dispositivo remoto conectado'''
    _language_accept_ = _environ_['HTTP_ACCEPT_LANGUAGE']
    _user_agent_ = _environ_['HTTP_USER_AGENT']
    if _language_accept_:
        _comma_ = _language_accept_.find(',')
        if _comma_>=0:
            for n,o in LANGUAGE_LIST.iteritems():
                if _language_accept_[:_comma_].strip(' \t\n\r').lower() == n:
                    return n
    if _user_agent_:
        _cut_ = _user_agent_.split(';')
        for m in _cut_:
            for n,o in LANGUAGE_LIST.iteritems():
                if m.strip(' \t\n\r').lower() == n:
                    return n
    return ''

def Detect_IP(_environ_):
    '''Detectar la direccion IP de un dispositivo remoto conectado'''
    if 'HTTP_CLIENT_IP' in _environ_:
        return _environ_['HTTP_CLIENT_IP']
    elif 'HTTP_X_FORWARDED_FOR' in _environ_:
        return _environ_['HTTP_X_FORWARDED_FOR']
    elif 'REMOTE_ADDR' in _environ_:
        return _environ_['REMOTE_ADDR']
    else:
        return None

def IP_From(_ipaddr_):
    try:
        if _ipaddr_:
            con = Db_MySQL('localhost','pymetrick','root','headcracker_sql',3306)
            ipaddr_aton = INET_ATON(_ipaddr_)
            if ipaddr_aton:
                ipaddr_country = con.exeSQL("SELECT CONCAT(geoip.iso_code_2,'|',countries.name) FROM geoip,countries WHERE %s>=ipaddr_top and %s<=ipaddr_bottom and geoip.iso_code_2=countries.iso_code_2 LIMIT 1" % (ipaddr_aton,ipaddr_aton))
                return ipaddr_country
            else:
                return None
        else:
            return None
    except ValueError:
        return None


def INET_ATON(_ipaddr_):
    '''Para comparar direcciones IP o comprobar su inclusion en un rango,
       es necesario convertir la direccion en un numero. Que tambien
       se puede almacenar en MySQL
    '''
    try:
        ipaddr = _ipaddr_.split('.')
        if len(ipaddr) == 4:
            integer_ip =(16777216*int(ipaddr[0]))+(65536*int(ipaddr[1]))+(256*int(ipaddr[2]))+int(ipaddr[3])
            return integer_ip
        else:
            return None
    except ValueError:
        return None


def INET_NTOA(_integer_ip_):
    '''Para comparar direcciones IP o comprobar su inclusion en un rango,
       es necesario convertir la direccion en un numero. Una vez convertida
       a un numero, es necesario poder hacer la conversion nuevamente a una
       IPv4
    '''
    try:
        integer_ip = _integer_ip_
        ipaddr_1 = int(integer_ip/16777216)%256
        ipaddr_2 = int(integer_ip/65536)%256;
        ipaddr_3 = int(integer_ip/256)%256;
        ipaddr_4 = int(integer_ip)%256;
        ipaddr = ('%s.%s.%s.%s' % (ipaddr_1,ipaddr_2,ipaddr_3,ipaddr_4))
        return ipaddr
    except ValueError:
        return None


if __name__ == "__main__":
    print ('''copyright {0}'''.format( __copyright__))
    print ('''license {0}'''.format( __license__))
    print ('''version {0}'''.format( __version__))
    if len(sys.argv) < 2:
        sys.stderr.write("for help use -h o --help")
    elif sys.argv[1]=='-h' or sys.argv[1]=='--help':
        print (u'''Identificacion la tipología de dispositivos conectados''')


