176 lines
5.9 KiB
Python
Executable File
176 lines
5.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# encoding: utf-8
|
|
#
|
|
# Automarcaje para timenet.gpisoftware.com
|
|
# usage: autoficher.py -u USER -p PIN -t TYPE [-f] [-h]
|
|
#
|
|
# Argumentos obligatorios:
|
|
# -u USER, --user USER Usuario
|
|
# -p PIN, --pin PIN Contraseña
|
|
# -t TYPE, --type TYPE Tipo marcado. 0 = Entrada, 1 = Salida (Si no se utiliza -bt)
|
|
#
|
|
#
|
|
# Creado: Omar Sánchez 04-05-2019
|
|
|
|
# Importamos librerias
|
|
import json
|
|
from datetime import datetime
|
|
|
|
import pytz
|
|
import requests
|
|
import argparse
|
|
|
|
import telegram
|
|
|
|
# Introducimos los argumentos obligatorios y opcionales
|
|
parser = argparse.ArgumentParser(add_help=False)
|
|
parser._action_groups.pop()
|
|
|
|
obligatoryArgs = parser.add_argument_group("Argumentos obligatorios")
|
|
obligatoryArgs.add_argument('-p', '--pin', help="Contraseña", type=int, required=True)
|
|
obligatoryArgs.add_argument('-t', '--type', help="Tipo marcado. 0 = Entrada, 1 = Salida", type=int)
|
|
|
|
optionalArgs = parser.add_argument_group("Argumentos opcionales")
|
|
optionalArgs.add_argument('-bt', '--basedtime', help="Hacer check o descheck según la hora del dia",
|
|
action="store_true")
|
|
optionalArgs.add_argument('-h', '--help', action="help", help="Esta ayuda")
|
|
optionalArgs.add_argument('-d', '--debug', action='store_true')
|
|
|
|
optionalArgs.add_argument('-c', '--config', help="Rúta al archivo de configuración")
|
|
optionalArgs.add_argument('-u', '--user', help="Usuario")
|
|
optionalArgs.add_argument('-glo', '--geoLongitude', help="GEO Longitud", type=float)
|
|
optionalArgs.add_argument('-gla', '--geoLatitude', help="GEO Latitud", type=float)
|
|
optionalArgs.add_argument('-ga', '--geoAccuracy', help="GEO Accuracy", type=float)
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
class AutoFicher():
|
|
# URL de la api
|
|
headers = {
|
|
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
"tn-v": "3.0.9",
|
|
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36"
|
|
}
|
|
config = None
|
|
|
|
def __init__(self):
|
|
try:
|
|
self.loadConfig()
|
|
except:
|
|
print("No se ha podido cargar el archivo de configuración")
|
|
exit(20)
|
|
|
|
def loadConfig(self):
|
|
path = 'config.json'
|
|
|
|
if args.config:
|
|
path = args.config
|
|
|
|
with open(path, 'r') as f:
|
|
self.config = json.load(f)
|
|
|
|
if args.geoLatitude:
|
|
self.config['geo']['latitude'] = args.geoLatitude
|
|
if args.geoLongitude:
|
|
self.config['geo']['longitude'] = args.geoLongitude
|
|
if args.user:
|
|
self.config['user'] = args.user
|
|
if args.geoAccuracy:
|
|
self.config['geo']['accuracy'] = args.geoAccuracy
|
|
|
|
print(self.config)
|
|
|
|
def sendReport(self, message):
|
|
bot = telegram.Bot(token=self.config['telegram']['token'])
|
|
bot.sendMessage(chat_id=self.config['telegram']['chat_id'], text=str(message))
|
|
|
|
def get(self, url, data={}, headers={}):
|
|
furl = self.config['api_url'] + url
|
|
if url != "version":
|
|
furl = self.config['api_url'] + "v1/" + url
|
|
return requests.get(furl, data=data, headers=headers)
|
|
|
|
def post(self, url, data={}, headers={}):
|
|
furl = self.config['api_url'] + url
|
|
if url != "version":
|
|
furl = self.config['api_url'] + "v1/" + url
|
|
return requests.post(furl, data=data, headers=headers)
|
|
|
|
def updateTime(self):
|
|
self.headers["tn-d"] = "\"" + datetime.now().astimezone(pytz.UTC).strftime("%Y-%m-%dT%H:%M:%SZ") + "\""
|
|
|
|
def getVersion(self):
|
|
self.updateTime()
|
|
return self.get('version', self.headers)
|
|
|
|
def getInfo(self):
|
|
return self.get('check/info', {"guid": args.user})
|
|
|
|
def sendUpdate(self):
|
|
self.updateTime()
|
|
|
|
typ = 0
|
|
if args.basedtime and not args.type:
|
|
hour = datetime.now().strftime("%H")
|
|
|
|
hIN = self.config['in_hours']
|
|
|
|
hOUT = self.config['out_hours']
|
|
|
|
if hour in hIN:
|
|
typ = 0
|
|
elif hour in hOUT:
|
|
typ = 1
|
|
else:
|
|
print(
|
|
"No se ha fichado ni desfichado ya que estamos en horario laboral, fuerze el estado con el parametro --type <0 = Entrada, 1 = Salida>")
|
|
else:
|
|
typ = args.type
|
|
|
|
data = {
|
|
"cp": self.config['user'],
|
|
"pin": args.pin,
|
|
"typ": typ,
|
|
"date": self.headers['tn-d'],
|
|
"geoLatitude": self.config['geo']['latitude'],
|
|
"geoLongitude": self.config['geo']['longitude'],
|
|
"geoError": "",
|
|
"c": 1,
|
|
"geoAccuracy": self.config['geo']['accuracy']
|
|
}
|
|
|
|
response = None
|
|
if not args.debug:
|
|
print("####HACIENDO CHECK####")
|
|
response = self.post("check", data, self.headers)
|
|
|
|
try:
|
|
rj = json.loads(response.text)
|
|
except:
|
|
print("La respuesta al hacer check no es correcta... algo ha pasado :/")
|
|
exit(20)
|
|
|
|
if args.debug:
|
|
self.sendReport('Corriendo en modo debug. No se realizará ninguna acción')
|
|
if response.status_code == 200:
|
|
if rj['Repeated']:
|
|
time = datetime.strptime(rj['RepeatedTime'], "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=pytz.utc).astimezone(
|
|
pytz.timezone("Europe/Madrid")).strftime("%H:%M")
|
|
self.sendReport("Se ha realizado un marcaje antes a las %s" % time)
|
|
else:
|
|
time = datetime.strptime(self.headers["tn-d"], "'%Y-%m-%dT%H:%M:%SZ'").replace(
|
|
tzinfo=pytz.utc).astimezone(pytz.timezone("Europe/Madrid")).strftime("%H:%M")
|
|
|
|
rtext = 'fichado'
|
|
if typ:
|
|
rtext = 'desfichado'
|
|
self.sendReport('Has %s correctamente a las %s' % (rtext, time))
|
|
else:
|
|
self.sendReport("No se ha podido fichar, la web no ha devuelto 200 OK")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
af = AutoFicher()
|
|
af.sendUpdate()
|