#!/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") optionalArgs.add_argument('-gla', '--geoLatitude', help="GEO Latitud") optionalArgs.add_argument('-ga', '--geoAccuracy', help="GEO Accuracy") 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()