diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..73f69e0
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/autoficher.iml b/.idea/autoficher.iml
new file mode 100644
index 0000000..d0876a7
--- /dev/null
+++ b/.idea/autoficher.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..6ad0d1a
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..d4fc832
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..dfc3532
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..78fae8d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,25 @@
+Autoficher para Timenet
+==============================
+
+Que es esto?
+-------------
+
+Aplicación simple para fichar y desfichar automáticamente
+
+Como se usa?
+---------------
+
+1. Ejecutamos `pip3 install -r requirements.txt` para instalar los componentes
+2. Ejecutamos `python3 ./autofitcher.py -u -p [-t <0 = Entrada, 1 = Salida>| -bt]`
+3. Opcionalmente podemos ponerlo en un Crontab de linux para que se ejecute cada X tiempo y se realize el fichado automatico
+
+Parametros obligatorios
+---------------
+
+-u > Usuario de timenet (Pista Cero = 4c26cc59-ee52-4c47-b7fe-1065a5e5bf84)
+-p > Pin de usuario
+
+Tendremos que escojer también entre --basedtime o --type
+
+-bt > No requiere argumento. Esto ficha y desficha basado en la configuración de horas a seguir
+-t <0 = Entrada, 1 = Salida> > Forzamos estado al entrar/salir
\ No newline at end of file
diff --git a/autoficher.py b/autoficher.py
index aca0f36..f941f19 100755
--- a/autoficher.py
+++ b/autoficher.py
@@ -17,75 +17,108 @@
# Creado: Omar Sánchez 04-05-2019
# Importamos librerias
-import os
import json
-import sys
-from datetime import datetime, timedelta
+from datetime import datetime
+
+import pytz
import requests
-import urllib.parse
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('-u', '--user', help="Usuario", required=True)
-obligatoryArgs.add_argument('-p', '--pin', help="Contraseña", required=True)
-obligatoryArgs.add_argument('-t', '--type', help="Tipo marcado. 0 = Entrada, 1 = Salida", required=True)
+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('-f', '--festive', action="store_false", help="Comprobar festivo")
+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")
args = parser.parse_args()
class AutoFicher():
# URL de la api
- url = "https://timenet.gpisoftware.com/api/v1/cp/"
- # Definimos las variables de tiempo
- date = datetime.now().strftime("%d/%m/%Y+%H:%M:%S")
- #calendar = (datetime.now() + timedelta(days=3)).strftime("%d/%m/%Y")
- calendar = datetime.now().strftime("%d/%m/%Y")
+ 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
- token = ""
+ def __init__(self):
+ self.loadConfig()
- def __init__(self, task = ''):
- # Iniciamos Sesión y obtenemos el token
- headers = {'user': args.user, 'pass': args.pin}
- response = requests.get(self.url+'login', headers=headers)
- self.token = response.text.replace('"','')
+ def loadConfig(self):
+ with open('config.json', 'r') as f:
+ self.config = json.load(f)
- def isFestive(self):
- # Comprobamos si esta habilitado el comprobar festivo (Por defecto es True)
- if args.festive:
- # Revisamos el dia en el calendario y comprobamos si es festivo o no
- headers = {'token': self.token}
- response = requests.get(self.url+"calendar?start="+self.calendar+"&end="+self.calendar, headers=headers)
- dayType = json.loads(response.text)["DayTypes"][0]["dayMode"]
+ 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={}):
+ if url != "version":
+ self.url = self.url + "v1/"
+ return requests.get(self.config['api_url']+url, data=data, headers=headers)
+
+ def post(self, url, data={}, headers={}):
+ if url != "version":
+ self.url = self.url + "v1/"
+ return requests.post(self.config['api_url']+url, data=data, headers=headers)
+
+ def updateTime(self):
+ self.headers["tn-d"] = "\""+datetime.now().astimezone(pytz.UTC).strftime(self.config['time_format'])+"\""
+
+ def getVersion(self):
+ self.updateTime()
+ return self.get('version', self.headers)
+
+ def getInfo(self):
+ return self.get('check/info', {"guid": args.user})
- if dayType == "NO_WORK":
- return True
- else:
- return False
- else:
- return False
-
def sendUpdate(self):
- # Si no es festivo..
- if not self.isFestive():
- # Hacemos la llamada a la api para marcar o desmarcar
- print("Dia de curro")
- headers = {"Content-type": "application/x-www-form-urlencoded", "token": self.token}
- data = {"typ": args.type, "date": urllib.parse.quote(self.date), "geoLatitude": "41.3908992", "geoLongitude": "2.154496", "geoErrors": ""}
-
- response = requests.post(self.url+"checks", data=data, headers=headers)
- if response.status_code != 200:
- print("Error "+str(response.status_code)+" al realizar el envio: "+ response.request.body)
+ 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(response.text)
+ 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:
- print("Hoy no se trabaja")
+ typ = args.type
+
+ data = {
+ "cp": args.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 = self.post("check", data, self.headers)
+
+ if response.status_code != 200:
+ self.sendReport('Has fichado correctamente a las ' + str(datetime.strptime(self.headers["tn-d"]).strftime("%H:%M")))
+ else:
+ self.sendReport("No se ha podido fichar, la web no ha devuelto 200 OK")
if __name__ == '__main__':
- AutoFicher().sendUpdate()
+ af = AutoFicher()
diff --git a/config.json b/config.json
new file mode 100644
index 0000000..68bac22
--- /dev/null
+++ b/config.json
@@ -0,0 +1,28 @@
+{
+ "in_hours": [
+ "07",
+ "08",
+ "09",
+ "10",
+ "11",
+ "15"
+ ],
+ "out_hours": [
+ "13",
+ "14",
+ "15",
+ "17",
+ "18"
+ ],
+ "api_url": "https://timenet.gpisoftware.com/api/",
+ "telegram": {
+ "token": "1502426217:AAEBG7XF6dZqJ6cRmPQk_YykGS5mJFeUEto",
+ "chat_id": 12878473
+ },
+ "geo": {
+ "latitude": 41.3908992,
+ "longitude": 2.154496,
+ "accuracy": 98.31
+ },
+ "time_format": "%Y-%m-%dT%H:%M:%SZ"
+}
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..b856f1d
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+python-telegram
\ No newline at end of file