Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
scrapper-portabilidad
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
2
Issues
2
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Javier
scrapper-portabilidad
Commits
15b848e5
Commit
15b848e5
authored
Mar 30, 2022
by
Javier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Métodos GET/POST de Account
parent
c9a51610
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
234 additions
and
20 deletions
+234
-20
main.py
main.py
+135
-14
.env
mbilling/.env
+3
-0
add_balance.php
mbilling/add_balance.php
+4
-5
functions.py
mbilling/functions.py
+70
-1
get_user.php
mbilling/get_user.php
+22
-0
requirements.txt
requirements.txt
+0
-0
No files found.
main.py
View file @
15b848e5
from
enum
import
Enum
import
imp
from
lib2to3.pytree
import
Base
from
pydoc
import
resolve
from
tkinter.tix
import
Form
from
turtle
import
title
from
unicodedata
import
name
from
urllib
import
response
from
fastapi
import
Body
,
Depends
,
FastAPI
from
fastapi
import
Body
,
Depends
,
FastAPI
,
Query
,
Response
from
fastapi.responses
import
JSONResponse
from
typing
import
Optional
from
typing
import
Optional
,
Tuple
from
pydantic
import
BaseModel
import
mbilling.functions
...
...
@@ -19,6 +22,16 @@ class Rate(str, Enum):
PLANA_1000
=
"Tarifa Plana 1000 Minutos"
PLANA_2000
=
"Tarifa Plana 2000 Minutos"
class
Tax
(
float
,
Enum
):
GENERAL
=
0.21
LIBRE
=
0.0
class
Refill
(
str
,
Enum
):
AUTOMATICA
=
'Recarga Automática'
LIQUIDACION
=
'Liquidación Mensual de consumos Postpago'
MANUAL
=
'Recarga solicitada por el Cliente'
TRASPASO
=
'Traspaso de Fondos desde A2Billing'
INICIAL
=
'Recarga Inicial'
class
Account
(
BaseModel
):
"""_summary_
...
...
@@ -46,6 +59,39 @@ class Account(BaseModel):
default
=
None
,
example
=
'192.168.2.71'
,
title
=
'Centralita'
,
description
=
'Dirección IP de la Centralita.'
)
class
AccountDetails
(
BaseModel
):
number
:
str
=
Body
(
...
,
regex
=
r'[89][1-9]\d{7}'
,
example
=
'856135158'
,
title
=
'Número'
,
description
=
'Identificador de entrada y salidas de Llamadas'
)
password
:
str
=
Body
(
...
,
title
=
'Contraseña'
,
description
=
'Credencial Cuenta SIP para host dinámico.'
)
host
:
str
=
Body
(
...
,
title
=
'Host'
,
description
=
'Dirección desde la que se conecta el usuario.'
)
credit
:
float
=
Body
(
...
,
title
=
'Saldo Disponible'
,
description
=
'Adeudo o activo que tiene el cliente.'
)
rate
:
Rate
=
Body
(
default
=
Rate
.
ESTANDAR
,
title
=
'Tarifa'
,
description
=
'Plan de Precios de la Línea'
)
class
Config
:
schema_extra
=
{
"example"
:
{
"number"
:
"856135158"
,
"password"
:
"rentel58"
,
"host"
:
"192.168.2.71"
,
"credit"
:
32.45
,
"rate"
:
Rate
.
PLANA_2000
}
}
class
ConnectionData
(
BaseModel
):
"""Datos de Conexión
...
...
@@ -79,29 +125,42 @@ class ConnectionData(BaseModel):
}
@app.post
(
'/account'
,
response_model
=
ConnectionData
,
name
=
'Añadir Cuenta SIP'
,
description
=
'Genera una nueva cuenta en el Tarificador'
)
def
create_account
(
account
:
Account
=
Depends
()):
"""Genera una nueva cuenta SIP con los datos proporcionados.
Args:
account (Account, optional): Modelo de Cuenta. Defaults to Depends().
"""
def
encode_rate
(
rate
:
Rate
=
Rate
.
ESTANDAR
)
->
Tuple
[
int
,
int
]:
# Tarifa por Defecto
plan_id
=
1
offer_id
=
0
# Selección de Tarifa
if
account
.
rate
==
Rate
.
PLANA_1000
:
if
rate
==
Rate
.
PLANA_1000
:
plan_id
=
4
offer_id
=
4
elif
account
.
rate
==
Rate
.
PLANA_2000
:
elif
rate
==
Rate
.
PLANA_2000
:
plan_id
=
4
offer_id
=
5
elif
account
.
rate
==
Rate
.
EMPRESAS
:
elif
rate
==
Rate
.
EMPRESAS
:
plan_id
=
2
return
plan_id
,
offer_id
def
decode_rate
(
plan_id
:
int
,
offer_id
:
int
=
0
)
->
Rate
:
if
plan_id
==
1
:
return
Rate
.
ESTANDAR
elif
plan_id
==
2
:
return
Rate
.
EMPRESAS
elif
plan_id
==
4
:
return
Rate
.
PLANA_1000
if
offer_id
==
4
else
Rate
.
PLANA_2000
@app.post
(
'/account'
,
response_model
=
ConnectionData
,
name
=
'Añadir Cuenta SIP'
,
description
=
'Genera una nueva cuenta en el Tarificador'
)
def
create_account
(
account
:
Account
=
Depends
()):
"""Genera una nueva cuenta SIP con los datos proporcionados.
Args:
account (Account, optional): Modelo de Cuenta. Defaults to Depends().
"""
plan_id
,
offer_id
=
encode_rate
(
account
.
rate
)
# Generación de la Cuenta
try
:
...
...
@@ -135,3 +194,65 @@ def create_account( account: Account = Depends()):
return
response
@app.get
(
'/account/{account_name}'
,
response_model
=
AccountDetails
)
def
get_account
(
account_name
:
str
=
Query
(
...
,
regex
=
r'[89][1-9]\d{7}'
,
name
=
'Número'
,
description
=
'Cuenta SIP a recargar'
)):
user_data
=
mbilling
.
functions
.
get_user
(
account_name
)
if
user_data
:
response
=
AccountDetails
(
number
=
account_name
,
password
=
user_data
[
'password'
],
host
=
user_data
[
'host'
],
credit
=
user_data
[
'credit'
],
rate
=
decode_rate
(
user_data
[
'plan'
],
user_data
[
'offer'
])
)
else
:
response
=
JSONResponse
(
content
=
{
'result'
:
'ERROR'
,
'description'
:
'No existe ningún usuario con la identificación solicitada.'
},
status_code
=
404
)
return
response
@app.post
(
'/account/{account_name}/balance'
,
name
=
'Añade saldo a una cuenta SIP'
,
description
=
'Realiza una recarga en nombre del cliente.'
)
def
add_balance
(
account_name
:
str
=
Query
(
...
,
regex
=
r'[89][1-9]\d{7}'
,
name
=
'Número'
,
description
=
'Cuenta SIP a recargar'
),
quantity
:
float
=
Query
(
default
=
10.00
,
name
=
'Cantidad'
,
description
=
'Total a ingresar incluyendo impuestos'
),
tax
:
Tax
=
Query
(
default
=
Tax
.
GENERAL
,
name
=
'Impuesto'
,
description
=
'Tasa impositiva a reducir del monto.'
),
description
:
Refill
=
Query
(
default
=
Refill
.
AUTOMATICA
,
name
=
'Tipo'
,
description
=
'Clase de Recarga'
)
):
if
quantity
>=
0
and
tax
>=
0
:
try
:
mbilling
.
functions
.
add_balance
(
account_name
,
quantity
,
tax
if
description
!=
Refill
.
TRASPASO
else
0.0
,
description
)
response
=
JSONResponse
(
content
=
{
'result'
:
'OK'
,
'description'
:
'Se ha realizado una recarga de {quantity} al usuario {account}.'
.
format
(
quantity
=
quantity
,
account
=
account_name
)
},
status_code
=
201
)
except
mbilling
.
functions
.
MagnusCommandError
as
e
:
response
=
JSONResponse
(
content
=
{
'result'
:
'ERROR'
,
'description'
:
f
'El usuario no ha sido localizado, {str(e)}'
},
status_code
=
500
)
else
:
response
=
JSONResponse
(
content
=
{
'result'
:
'ERROR'
,
'description'
:
'La cantidad y tasa impositiva han de ser mayores que 0.'
},
status_code
=
400
)
return
response
mbilling/.env
View file @
15b848e5
MAGNUS_HOST = 'http://192.168.2.56/mbilling'
API_KEY = 'FxMqVFWMztbigCeZlFupGULLh6LRaLs8'
API_SECRET = 'rguvK0sNZMki5yWtv4RKONMJo1Hd9jiX'
DB_USER = 'magnusupdater'
DB_PASSWORD = 'magnusupdater'
\ No newline at end of file
mbilling/add_balance.php
View file @
15b848e5
...
...
@@ -2,23 +2,22 @@
include
'api.php'
;
// ARGUMENTOS: USUARIO SALDO
// ARGUMENTOS: USUARIO SALDO
DESCRIPCIÓN
if
(
isset
(
$argv
[
1
])
&&
isset
(
$argv
[
2
]))
{
$result
=
$magnusBilling
->
create
(
'refill'
,
[
'id_user'
=>
$magnusBilling
->
getId
(
'user'
,
'username'
,
$argv
[
1
]),
'credit'
=>
floatval
(
$argv
[
2
]),
'payment'
=>
1
,
'description'
=>
'Recarga Saldo'
'description'
=>
$argv
[
3
]
]);
if
(
$result
[
'success'
]
==
1
)
{
print
(
"[201] OK id="
.
$result
[
'rows'
][
0
][
'id'
]);
}
else
{
print
(
"[409] ERROR Ya existe una cuenta con mismo usuario."
);
$error
=
print_r
((
$result
));
print
(
"[400] "
.
$error
);
}
}
else
{
print
(
"[404] ERROR No se han introducido todos los parámetros necesarios."
);
}
mbilling/functions.py
View file @
15b848e5
...
...
@@ -2,10 +2,25 @@ import subprocess
import
pathlib
import
re
from
random
import
randint
import
mariadb
from
dotenv
import
dotenv_values
# Path de MBILLING
mbapi_path
=
pathlib
.
Path
(
pathlib
.
Path
()
.
resolve
(),
'mbilling'
)
# Petición Correcta
succesful
=
re
.
compile
(
r'^\[20\d\]'
)
# Carga de Variables ENV
values
=
dotenv_values
(
pathlib
.
Path
(
mbapi_path
,
'.env'
))
DB_CREDENTIALS
=
{
'host'
:
re
.
match
(
r'.*http://([0-9\.]+).*'
,
values
[
'MAGNUS_HOST'
],
flags
=
re
.
DOTALL
)
.
group
(
1
),
'user'
:
values
[
'DB_USER'
],
'password'
:
values
[
'DB_PASSWORD'
],
'port'
:
3306
,
'database'
:
'mbilling'
}
class
MagnusCommandError
(
Exception
):
...
...
@@ -27,7 +42,8 @@ def _create_user(phone_number: str, password: str, name: str, surname: str, plan
if
not
re
.
match
(
succesful
,
result
.
decode
(
encoding
=
'utf-8'
)):
exception_cmd
=
' '
.
join
([
'php'
,
str
(
pathlib
.
Path
(
mbapi_path
,
'create_user.php'
)),
phone_number
,
password
,
f
'
\"
{name}
\"
'
,
f
'
\"
{surname}
\"
'
,
str
(
plan_id
),
str
(
offer_id
)])
raise
MagnusCommandError
(
f
'Command: {exception_cmd} Exception: {result.decode(encoding="utf-8")}'
)
raise
MagnusCommandError
(
f
'Command: {exception_cmd} Exception: {result.decode(encoding="utf-8")}'
)
def
_create_sip
(
phone_number
:
str
,
password
:
str
,
pbx
:
str
=
None
):
...
...
@@ -77,3 +93,56 @@ def create_user(phone_number: str, name: str, surname: str, password: str = None
_create_did
(
phone_number
)
return
password
def
add_balance
(
phone_number
:
str
,
quantity
:
float
,
tax
:
float
=
0.21
,
description
:
str
=
'Recarga Automática'
):
"""Añade saldo a una cuenta SIP
Args:
phone_number (str): Cuenta SIP
quantity (float): Cantidad Bruta a Ingresar, incluyendo impuestos.
tax (float): Impuestos. Default 0.21
description (str, optional): Tipo de Recarga. Defaults to 'Recarga Automática'.
Raises:
MagnusCommandError: Error en Procesamiento
"""
quantity
=
round
(
quantity
*
(
1
-
tax
),
2
)
result
=
subprocess
.
check_output
(
[
'php'
,
pathlib
.
Path
(
mbapi_path
,
'add_balance.php'
),
phone_number
,
quantity
,
f
'
\"
{description}
\"
'
]
)
if
not
re
.
match
(
succesful
,
result
.
decode
(
'utf-8'
)):
raise
MagnusCommandError
(
result
.
decode
(
'utf-8'
))
def
get_user
(
phone_number
:
str
)
->
dict
:
"""Obtiene los datos de un usuario SIP
Args:
phone_number (str): Número
Returns:
dict: Diccionario con todos los datos.
"""
with
mariadb
.
connect
(
**
DB_CREDENTIALS
)
as
cnx
:
with
cnx
.
cursor
()
as
cursor
:
headers
=
[
'username'
,
'password'
,
'host'
,
'credit'
,
'firstname'
,
'lastname'
,
'plan'
,
'offer'
]
cursor
.
execute
(
"""SELECT u.username, s.secret password, s.host, u.credit, u.firstname, u.lastname, p.id plan, o.id offer FROM mbilling.pkg_user u
INNER JOIN mbilling.pkg_plan p ON u.id_plan=p.id
LEFT JOIN mbilling.pkg_offer o ON u.id_offer=o.id
INNER JOIN mbilling.pkg_sip s ON u.username=s.name
WHERE username=?"""
,
(
phone_number
,)
)
query
=
cursor
.
fetchone
()
return
dict
(
zip
(
headers
,
query
))
if
query
else
None
mbilling/get_user.php
0 → 100644
View file @
15b848e5
<?php
include
'api.php'
;
// ARGUMENTOS : USUARIO
if
(
isset
(
$argv
[
1
]))
{
# Datos del Usuario
$user_id
=
$magnusBilling
->
getId
(
'user'
,
'username'
,
$argv
[
1
]);
$magnusBilling
->
setFilter
(
'id'
,
$user_id
,
'eq'
,
'numeric'
);
$user_data
=
$magnusBilling
->
read
(
'user'
);
# Datos SIP
$sip_id
=
$magnusBilling
->
getId
(
'sip'
,
'name'
,
$argv
[
1
]);
print
(
'SIP'
);
print_r
(
$sip_id
);
$magnusBilling
->
setFilter
(
'name'
,
$sip_id
,
'eq'
,
'numeric'
);
$sip_data
=
$magnusBilling
->
read
(
'sip'
);
print
(
'DATA'
);
print_r
(
$sip_data
);
}
else
{
print
(
"[404] ERROR No se han introducido todos los parámetros necesarios."
);
}
requirements.txt
0 → 100644
View file @
15b848e5
File added
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment