
#5|jÄ  ã               @   sù   d  Z  d d l Z d d l Z d d l Z d d l m Z d d „  Z e ƒ  Z e j j	 d d ƒ Z
 e j j	 d d ƒ Z e j j	 d	 d ƒ Z d
 d „  Z d d „  Z d d „  Z	 d d „  Z d d „  Z d d „  Z d d „  Z e d k rõ e ƒ  d S)aÔ  
Sonda de la API de ISPGestion.

Sirve para descubrir que columnas devuelve realmente /api/clientes, ya que el
manual "API ISPGESTION BASICA" solo documenta los parametros de ENTRADA de
alta/modificacion, no la salida de las consultas.

Uso: rellena HOST / USER / PASS aqui abajo y lanza:

    python ispgestion_probe.py campos            # lista las columnas de un cliente
    python ispgestion_probe.py todos             # cuenta clientes y muestra 1 de ejemplo
    python ispgestion_probe.py codigo 000001     # cliente por codigo
    python ispgestion_probe.py fiscal 00000000T  # cliente por NIF
    python ispgestion_probe.py nombre jose perez # busqueda por nombre

Nada de esto escribe en ISPGestion: solo hace GET.
é    N)ÚHTTPBasicAuthc              C   s  t  j j t  j j t  j j t ƒ ƒ d ƒ t  j j t  j ƒ  d ƒ g }  xÏ |  D]Ç } y© t | ƒ �’ } xˆ | D]€ } | j ƒ  } | sn | j	 d ƒ sn d | k r¥ qn | j
 d d ƒ \ } } t  j j | j ƒ  | j ƒ  j d ƒ j d ƒ ƒ qn WWd QRX| SWqO t k
 rwO YqO XqO Wd S)zoMismo cargador que usa bot.py. Busca .env junto al script y, si no,
    en el directorio desde el que se lanza.z.envú#ú=é   ú"ú'N)ÚosÚpathÚjoinÚdirnameÚabspathÚ__file__ÚgetcwdÚopenÚstripÚ
startswithÚsplitÚenvironÚ
setdefaultÚIOError)Z
candidatosZrutaÚfZlineaÚkÚv© r   ú0/home/gor/snmp/smartolt/ispgestion_probe_py35.pyÚ_cargar_dotenv'   s    *"<r   Ú	ISPG_HOSTÚ Ú	ISPG_USERÚ	ISPG_PASSc              C   s~   d d „  d t  f d t f d t f f Dƒ }  |  r` t j d d j |  ƒ d t t ƒ d	 ƒ t d
 t t pr d ƒ ƒ d  S)Nc             S   s"   g  |  ] \ } } | s | ‘ q Sr   r   )Ú.0Únr   r   r   r   ú
<listcomp>D   s   	 z check_config.<locals>.<listcomp>r   r   r   zFaltan estas claves: z, z

.env leido: z}

Anadelas al .env (sin espacios alrededor del =):
    ISPG_HOST=xxxxx.ispgestion.com
    ISPG_USER=xxxxx
    ISPG_PASS=xxxxxzCredenciales leidas de: Zentorno)	ÚHOSTÚUSERÚPASSÚsysÚexitr
   ÚstrÚ
_ENV_USADOÚprint)Zfaltanr   r   r   Úcheck_configC   s
    .&r+   c             K   s·   t  j |  d d | �} t d j | j t | j ƒ ƒ ƒ | j d k rt | j j d ƒ } | rt t d j | ƒ ƒ | j j	 ƒ  } | r© t d j | d  d … ƒ ƒ n
 t d	 ƒ | S)
NZtimeouté   zHTTP {}  ({} bytes)i‘  zWWW-AuthenticatezWWW-Authenticate: {}zCuerpo: {!r}iô  zCuerpo vacio)
ÚrequestsÚgetr*   ÚformatÚstatus_codeÚlenZcontentZheadersÚtextr   )ÚurlZkwÚrZcabZcuerpor   r   r   Ú	_peticionQ   s    " 
r5   c             C   s  d j  t |  ƒ } t d j  t |  ƒ ƒ t | d t t t ƒ ƒ} | j d k r† t d j  t |  ƒ ƒ t | d d t d t i ƒ} | j d k rË t d	 ƒ t d
 ƒ t d ƒ t d ƒ t d ƒ d S| j sØ d Sy | j	 ƒ  SWn  t
 k
 rt d ƒ d SYn Xd S)zRPrueba primero Basic auth; si da 401, reintenta con username/password en la query.zhttps://{}/api/{}z*
[1] Basic auth  ->  GET https://{}/api/{}Zauthi‘  zR
[2] Credenciales en la query  ->  GET https://{}/api/{}?username=...&password=...ZparamsZusernameZpasswordz
Los dos modos dan 401. Revisa:zB  - que el usuario/clave sean los de la API, no los del acceso webzC  - que ese usuario tenga permiso de API dado de alta en ISPGestionzJ  - si ISPGestion filtra por IP de origen (habria que dar de alta la tuya)zN  - NO repitas el intento muchas veces seguidas, no vayas a bloquear la cuentaNz,La respuesta no es JSON (ver cuerpo arriba).)r/   r#   r*   r5   r   r$   r%   r0   ÚokZjsonÚ
ValueError)r	   r3   r4   r   r   r   r.   b   s(    




	
r.   c             C   sh   t  |  t ƒ r |  r |  d St  |  t ƒ rd x1 |  j ƒ  D]# } t  | t ƒ r9 | r9 | d Sq9 W|  Sd S)z@La API devuelve un array bidimensional; saca el primer elemento.r   N)Ú
isinstanceÚlistÚdictÚvalues)Údatar   r   r   r   Úprimer_registro€   s    r=   c             C   sæ   |  d k r d St  |  t ƒ r# d St  |  t t f ƒ r] d j t |  ƒ j t t |  ƒ ƒ ƒ St  |  t ƒ r• |  j	 ƒ  d k r‚ d Sd j t |  ƒ ƒ St  |  t
 ƒ r· d j t |  ƒ ƒ St  |  t ƒ rÙ d	 j t |  ƒ ƒ St |  ƒ j S)
zDDescribe un valor SIN revelarlo: tipo, si viene vacio y su longitud.NZnullÚboolz{} ({} digitos)r   z	str VACIOzstr ({} chars)zlist ({} elementos)zdict ({} claves))r8   r>   ÚintÚfloatr/   ÚtypeÚ__name__r1   r(   r   r9   r:   )r   r   r   r   Ú	_describeŒ   s    %rC   c                s  t  |  t ƒ s/ t d j t |  ƒ j ƒ ƒ d St d j t |  ƒ ƒ ƒ t d d „  |  Dƒ ƒ } x? |  j ƒ  D]1 \ } } t d j | j	 | ƒ t
 | ƒ ƒ ƒ qn Wd ‰  ‡  f d d †  |  Dƒ } | rt d ƒ x. | D]& } t d j | t
 |  | ƒ ƒ ƒ qÙ Wd S)z9Imprime SOLO nombres de campo y tipo. Nunca el contenido.z:Registro inesperado (tipo {}). No se muestra el contenido.Nz.
{} campos (solo nombre y tipo, sin valores):
c             s   s   |  ] } t  | ƒ Vq d  S)N)r1   )r    r   r   r   r   ú	<genexpr>¥   s    z!mostrar_campos.<locals>.<genexpr>z  {}  :  {}ÚtelefonoÚmovilÚprefijoÚmailÚnombreÚapellidoÚcodigoÚ	clienteidÚfiscalÚnifÚ	domicilioc                s5   g  |  ]+ ‰  t  ‡  f d  d †  ˆ Dƒ ƒ r ˆ  ‘ q S)c             3   s!   |  ] } | ˆ  j  ƒ  k Vq d  S)N)Úlower)r    Úc)r   r   r   rD   ¬   s    z,mostrar_campos.<locals>.<listcomp>.<genexpr>)Úany)r    )Úclaves)r   r   r"   ¬   s   	 z"mostrar_campos.<locals>.<listcomp>z
Campos utiles para el bot:)rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   )r8   r:   r*   r/   rA   rB   r1   ÚmaxÚitemsÚljustrC   )ÚregZanchor   r   Zhitsr   )rS   r   Úmostrar_camposŸ   s    ) 
rX   c              C   s-  t  ƒ  t j d d  … }  |  s- t j t ƒ |  d j ƒ  } | d k r¦ t d ƒ } | d  k re d  St | t ƒ r� t	 d j
 t | ƒ ƒ ƒ t | ƒ } t | ƒ nƒ| d k r	t |  ƒ d k  rÑ t j d	 ƒ t d
 j
 |  d ƒ ƒ } | d  k	 r)t t | ƒ ƒ n | d k rlt |  ƒ d k  r4t j d ƒ t d j
 |  d ƒ ƒ } | d  k	 r)t t | ƒ ƒ n½ | d k rt |  ƒ d k  r—t j d ƒ d j |  d d  … ƒ } t d j
 | ƒ ƒ } | d  k rÕd  St | t ƒ rýt	 d j
 t | ƒ ƒ ƒ t t | ƒ ƒ n t j d j
 | t ƒ ƒ d  S)Nr   r   ÚcamposÚtodosZclienteszClientes devueltos: {}rK   é   z=Falta el codigo. Ej: python ispgestion_probe.py codigo 000001zclientes/{}rM   z=Falta el NIF. Ej: python ispgestion_probe.py fiscal 00000000Tzclientesfiscal/{}rI   zAFalta el nombre. Ej: python ispgestion_probe.py nombre jose perezÚ_zclientesnombre/p/{}zCoincidencias: {}zComando desconocido: {}
{})rY   rZ   )r+   r&   Úargvr'   Ú__doc__rP   r.   r8   r9   r*   r/   r1   r=   rX   r
   )ÚargsÚcmdr<   rW   rI   r   r   r   Úmain³   sH    ra   Z__main__)r^   r   r&   r-   Zrequests.authr   r   r)   r   r.   r#   r$   r%   r+   r5   r=   rC   rX   ra   rB   r   r   r   r   Ú<module>   s$   	/