diff --git a/README.MD b/README.MD index 44b2990..53b91ac 100644 --- a/README.MD +++ b/README.MD @@ -9,11 +9,11 @@ You only have to write simple _cooks_ that are small yaml text files, create gro I'm using this program in the company I work with 12 computers with Windows 8.1/10 with various software (MSI,EXE,...) and tweaking services, and it works right -It's not super-stable and error proof, then, I don't have any responsability if something crashes, but you can open a Issue and will see it +It's not error proof, then, I don't have any responsability if something crashes, but you can open a Issue and will see it # Roadmap -- English (Its all in Spanish now). Create a way to translate it +- Complete translation English and Spanish - Security (API 1) - Stabilize all - If anyone wants to create a better gui in Python it will be awesome. I used easygui to create a fast usable gui but maybe is not very proffesional.. Anyone? @@ -40,14 +40,15 @@ For server you can use Linux or Windows, and in theory any environment that can - Linux: - Not supported yet, but when Windows be stable, I will try to do it in some way - + +- Clients may have to be queried by DNS requests. If you don't have a domain (Samba or Windows AD), you may have to have a DNS server with local machines # Instalation. Example installing Server and using a GPO of Active Directory/Task Schedule to make it work in clients - Copy this folder to a folder in your server - Install dependencies - Open sysopt.py file and change values if needed - Use bat file if you are in Windows to run the python server, or sh file if you are in Linux environment -- Go to Client folder and copy "configpcm_example.ini" to "configpcm.ini" and change their values to yours. +- Go to Client folder and copy "configpcm_example.ini" to "configpcm.ini" and change their values to yours. Change lang value for having client gui translated to your lang - For clients to work, they have to run "client\client.ps1" every 30 mins/1 hour or so, I did using Active Directory and a Task Scheduled GPO (Copying client.ps1 and configpcm.ini files from Client to SysVol\DomainName\Scripts\) - User: SYSTEM (Or NT\SYSTEM) - Command: powershell.exe diff --git a/api.py b/api.py index f9f4a6b..2e12517 100644 --- a/api.py +++ b/api.py @@ -1,5 +1,5 @@ #!/usr/bin/python3 -BUILD = 12 +BUILD = 16 API_VER = 0 #Its beta, API 1 will have password checks enabled ##It can be run directly with "waitress-serve --port=3333 api:api" import falcon @@ -21,6 +21,18 @@ def logit(text): file.write(text) file.write('\n') +def retPassword(): + try: + return sql.select("SELECT Value FROM OPTIONS WHERE Option='Password'")[0]['Value'] + except: + return "" + +## +# getComputerExists: Know if computer exists and matches UUID +# /get/computerexists? +# @param ComputerName -> Computer to deploy it +# @param UUID: Check UUID validation of this computer +## class getComputerExists(object): def on_get(self, request, response): logit(request) @@ -32,26 +44,33 @@ class getComputerExists(object): UUID = value if ComputerName is None: - response.media = {'RESULT': 'ERROR'} + response.media = {'TEXT':'No params','RESULT': 'ERROR'} else: result = sql.select("SELECT COUNT(*) 'RESULT' FROM COMPUTERS WHERE Name='"+ComputerName+"' AND UUID='"+UUID+"'") if result[0]['RESULT'] == 0: # 0 or 1 - if sql.select("SELECT COUNT(*) 'RESULT' FROM COMPUTERS WHERE Name='"+ComputerName+"' AND UUID IS NULL")[0]['RESULT'] != 0: + if sql.select("SELECT COUNT(*) 'RESULT' FROM COMPUTERS WHERE Name='"+ComputerName+"' AND UUID IS NULL")[0]['RESULT'] != 0: #UUID doesn't in database, insert it sql.insert("UPDATE COMPUTERS SET UUID='"+UUID+"' WHERE Name='"+ComputerName+"'") response.media = {'RESULT': '1'} return - elif sql.select("SELECT COUNT(*) 'RESULT' FROM COMPUTERS WHERE Name='"+ComputerName+"'")[0]['RESULT'] != 0: - response.media = {'RESULT': 'ERROR'} + elif sql.select("SELECT COUNT(*) 'RESULT' FROM COMPUTERS WHERE Name='"+ComputerName+"'")[0]['RESULT'] != 0: #Not UUID match, but computer exists + response.media = {'TEXT': 'Error, computer and UUID doesn\'t match in database', 'RESULT': 'ERROR','EXITCODE':'2'} return - if sysopt.addComputers == True: + if sysopt.addComputers == True: #Computer doesn't exist, but you have enabled add all computers sql.insert("INSERT INTO COMPUTERS (`Name`,`UUID`) VALUES('"+ComputerName+"','"+UUID+"')") response.media = {'RESULT': '1'} - else: - response.media = {'RESULT': 'ERROR'} + else: #Computer doesn't exist and you don't want to be added + response.media = {'TEXT':'Error: Computer not exists in database', 'RESULT': 'ERROR','EXITCODE':'1'} + else: #Exists response.media = {'RESULT': '1'} + +## +# getGroups: Know all groups or groups of a computer +# /get/groups? +# @param ComputerName/ComputerID -> Computer to see groups (Not neccesary) +## class getGroups(object): #Get local groups of a Computer def on_get(self,request, response): logit(request) @@ -180,6 +199,12 @@ class addCookGrp(object): #Assign Cook to group result = sql.insert("INSERT INTO COOKS_IDG (`ID_G`,`CookName`) VALUES ('"+GroupID+"','"+CookName+"')") response.media = {'TEXT': 'OK'} +## +# delCookGrp: Delete cook from a group +# /del/cookgrp? +# @param GroupName/GroupID -> Group to show cooks +# @param CookName -> Cook to assign +## class delCookGrp(object): #Delete cook from a group def on_get(self,request,response): logit(request) @@ -196,10 +221,15 @@ class delCookGrp(object): #Delete cook from a group if GroupID is not None and CookName is not None: result = sql.insert("DELETE FROM COOKS_IDG WHERE ID_G='"+GroupID+"' AND CookName='"+CookName+"'") - #response.media = result + response.media = result else: response.media = {'TEXT': 'Error, no Group, or CookName does\'t exists','RESULT':'ERROR'} +## +# delEmptyPcsGroup: Delete all computers from from a group +# /del/emptypcsgroup? +# @param GroupName/GroupID -> Group to delete computers +## class delEmptyPcsGroup(object): #Delete all computers from a group def on_get(self,request,response): logit(request) @@ -319,6 +349,11 @@ class addComputer(object): result = sql.insert("INSERT INTO COMPUTERS (Name) VALUES ('"+ComputerName+"')") response.media = result +## +# addGroup: Add a new group +# /add/group? +# @param GroupName -> Name of group to add +## class addGroup(object): def on_get(self, request, response): logit(request) @@ -334,6 +369,11 @@ class addGroup(object): result = sql.insert("INSERT INTO GROUPS (Name) VALUES ('"+GroupName+"')") response.media = result +## +# delGroup: Delete a group and all tables that has it. +# /del/group? +# @param GroupName/GroupID -> Name of group to delete +## class delGroup(object): #Delete group def on_get(self, request, response): logit(request) @@ -351,6 +391,73 @@ class delGroup(object): #Delete group sql.insert("DELETE FROM COOKS_IDG WHERE ID_G='"+GroupID+"'") result = sql.insert("DELETE FROM GROUPS WHERE ID_G='"+GroupID+"'") response.media = result + + +## +# delCook: Delete a cook and all tables that has it. It doesn't delete files +# /del/cook? +# @param CookName -> Name of cook to disappear +## +class delCook(object): + def on_get(self,request,response): + logit(request) + CookName = None, None # Initialize + for key, value in request.params.items(): + if key == "CookName": + exists = os.path.isfile('cooks/'+value+'.yaml') + if exists: + CookName = value + + if CookName is not None: + sql.insert("DELETE FROM COOKS_ONETIME WHERE CookName='"+CookName+"'") + sql.insert("DELETE FROM COOKS_STATUS WHERE CookName='"+CookName+"'") + result = sql.insert("DELETE FROM COOKS_IDG WHERE CookName='"+CookName+"'") + response.media = result + else: + response.media = {'TEXT': 'Error, CookName don\'t exists','RESULT':'ERROR'} + +## +# delGroupsCook: Delete groups of a cook +# /del/groupscook? +# @param CookName -> Name of cook to make his groups disappear +## +class delGroupsCook(object): + def on_get(self,request,response): + logit(request) + CookName = None, None # Initialize + for key, value in request.params.items(): + if key == "CookName": + exists = os.path.isfile('cooks/'+value+'.yaml') + if exists: + CookName = value + + if CookName is not None: + result = sql.insert("DELETE FROM COOKS_IDG WHERE CookName='"+CookName+"'") + response.media = result + else: + response.media = {'TEXT': 'Error, CookName don\'t exists','RESULT':'ERROR'} + +## +# delCleanCook: Delete groups of a cook +# /del/cleancook? +# @param CookName -> Clean status of a cook (Restart it) +## +class delCleanCook(object): + def on_get(self,request,response): + logit(request) + CookName = None, None # Initialize + for key, value in request.params.items(): + if key == "CookName": + exists = os.path.isfile('cooks/'+value+'.yaml') + if exists: + CookName = value + + if CookName is not None: + result = sql.insert("DELETE FROM COOKS_STATUS WHERE CookName='"+CookName+"'") + response.media = result + else: + response.media = {'TEXT': 'Error, CookName don\'t exists','RESULT':'ERROR'} + class updGroup(object): #Delete group def on_get(self, request, response): @@ -445,7 +552,7 @@ class updComputer(object): try: ComputerID = str(sql.select("SELECT ID_C FROM COMPUTERS WHERE Name='"+value+"'")[0]['ID_C']) except: - response.media = {'TEXT': 'Error: Computer not exists in database','RESULT':'ERROR'} + response.media = {'TEXT': 'Error: Computer not exists in database','RESULT':'ERROR','EXITCODE':'1'} break if key == "ComputerID": ComputerID = value @@ -456,7 +563,7 @@ class updComputer(object): elif response.media is None and ComputerID is not None and UUID is not None: Count = str(sql.select("SELECT COUNT(*) 'Count' FROM COMPUTERS WHERE UUID='"+UUID+"' AND ID_C='"+ComputerID+"'")[0]['Count']) if Count == "0": - response.media = {'TEXT': 'Error, computer doesn\'t exists in database','RESULT':'ERROR'} + response.media = {'TEXT': 'Error, computer and UUID doesn\'t match in database','RESULT':'ERROR','EXITCODE':'2'} else: for key, value in request.params.items(): if key == "SOVersion": @@ -570,10 +677,70 @@ class setCookStatus(object): response.media = sql.insert("UPDATE COOKS_STATUS SET Revision='"+Revision+"',`Error`='"+Error+"',`ErrorDesc`='"+ErrorDesc+"' WHERE ID_C='"+ComputerID+"' AND CookName='"+CookName+"'") else: response.media = {'TEXT': 'Error in parameters...','RESULT':'ERROR'} - logit(response.media) +## +# checkPassword: Check password +# /check/password? +# @param Password -> SHA-256 of password +## +class checkPassword(object): #Check password (ERROR if password not valid or no password and 1 if valid) + def on_get(self, request, response): + logit(request) + Password= None + for key, value in request.params.items(): + if key == "Password": + Password = value + + if Password is None: + response.media = {'TEXT': 'Error, you need to supply a password','RESULT':'ERROR'} + else: + pass + res = sql.select("SELECT COUNT(*) 'RESULT' FROM OPTIONS WHERE Option='Password' AND Value='"+Password+"'")[0]['RESULT'] + if res == 1: + response.media = {'RESULT':'1','TEXT':'OK'} + else: + res = sql.select("SELECT COUNT(*) 'RESULT' FROM OPTIONS WHERE Option='Password'")[0]['RESULT'] + if res == 0: #Password doesn't exists in database + response.media = {'RESULT':'ERROR','TEXT':'No password set. Please set it'} + else: + response.media = {'RESULT':'ERROR','TEXT':'Password incorrect'} + +## +# updPassword: Update password +# /upd/password? +# @param OldPassword -> SHA-256 of password (Old) +# @param NewPassword -> SHA-256 of password (New) +## +class updPassword(object): #Update password (ERROR if password not valid or no password and 1 if changed) + def on_get(self, request, response): + logit(request) + OldPassword,NewPassword= None, None + for key, value in request.params.items(): + if key == "NewPassword": + NewPassword = value + if key == "OldPassword": + OldPassword = value + + res = sql.select("SELECT COUNT(*) 'RESULT' FROM OPTIONS WHERE Option='Password'")[0]['RESULT'] + if res == 0 and NewPassword is not None: #Password doesn't exists in database + response.media = sql.insert("INSERT INTO COMMENTS VALUES('Password','"+NewPassword+"')") + elif res == 0 and NewPassword is None: #No password supplied + response.media = {'RESULT':'ERROR','TEXT':'Error, you need to supply a password'} + elif res == 1 and OldPassword is not None: # Password exists in database (And you supplied OldPassword) + res = sql.select("SELECT COUNT(*) 'RESULT' FROM OPTIONS WHERE Option='Password' AND Value='"+OldPassword+"'")[0]['RESULT'] + if res == 0: # Old password incorrect + response.media = {'RESULT':'ERROR','TEXT':'Old password incorrect'} + elif res == 1 and NewPassword is not None: # All is supplied + response.media = sql.insert("UPDATE OPTIONS SET Value='"+NewPassword+"' WHERE Option='Password'") + else: + response.media = {'RESULT':'ERROR', 'TEXT':'No password supplied or bad args'} + else: + response.media = {'RESULT':'ERROR', 'TEXT':'No password supplied or bad args'} + + + api = falcon.API() api.add_route('/add/computer', addComputer()) #Add computer api.add_route('/add/group', addGroup()) #Add group to the list of local groups @@ -584,6 +751,10 @@ api.add_route('/del/cookgrp', delCookGrp()) # Deassign cook from a group api.add_route('/del/emptypcsgroup', delEmptyPcsGroup()) # Delete all computers from a group api.add_route('/del/group', delGroup()) #Delete group api.add_route('/del/grpcomputer', delGrpComputer()) #Delete computer from a group +api.add_route('/del/cook', delCook()) #Delete cook and all status about it +api.add_route('/del/groupscook', delGroupsCook()) #Delete all groups of a cook +api.add_route('/del/cleancook', delCleanCook()) #Delete status of a cook for all computers (Restart cook). No delete groups + api.add_route('/get/computerexists', getComputerExists()) #Returns 0 or 1 (name status) api.add_route('/get/computers', getComputers()) #Get list of computer api.add_route('/get/computersgrp', getComputersGrp()) #Get computers in a group @@ -602,8 +773,8 @@ api.add_route('/upd/cookname', updCookName()) #Update file name of cook and SQL api.add_route('/upd/group', updGroup()) #Update group name -#api.add_route('/check/password', checkPassword()) #Check admin password -#api.add_route('/upd/password', updPassword()) # Update password (Or create it not exists) +api.add_route('/check/password', checkPassword()) #Check admin password +api.add_route('/upd/password', updPassword()) # Update password (Or create it not exists) #api.add_route('/get/password', getPassword()) # Get password (Will be '' if password not exists) class getApiVer(object): diff --git a/client/client.ps1 b/client/client.ps1 index 01cf59e..17bc9df 100644 --- a/client/client.ps1 +++ b/client/client.ps1 @@ -1,4 +1,4 @@ -# Build 5 +# Build 7 $root = $PSCommandPath | Split-Path -Parent $server = (Get-Content "$root\configpcm.ini" | select -Skip 1 | ConvertFrom-StringData).server $resources = (Get-Content "$root\configpcm.ini" | select -Skip 1 | ConvertFrom-StringData).resources @@ -9,8 +9,12 @@ $UUID=(get-wmiobject Win32_ComputerSystemProduct).UUID $exists = Invoke-RestMethod -Method Get -Uri "$server/get/computerexists?ComputerName=$computerName&UUID=$UUID" if ($exists.Result -eq "ERROR"){ - Write-Host "Computer outside database:" $computerName - exit + if ($exists.EXITCODE -eq '1'){ + Write-Host "Computer outside database:" $computerName + }else{ + Write-Host "Computer and UUID of $computerName doesn't match" + } + exit } $Timestamp = [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalSeconds @@ -100,7 +104,13 @@ foreach ($CookName in $cooks){ Invoke-Expression $param if ($? -eq $false){ # Error in CMD $err = 1 - } + } + } + "PWSCRIPT" { # Run a powershell script. Note: Runs as high priv. + Invoke-Expression -Command $param + if ($? -eq $false){ # Error in Script + $err = 1 + } } "REPOTOLOCAL" { # Copy file from repo location to local ($env:temp) for use in cmd or other things Copy-Item "$resources\$param" $env:temp -ErrorVariable errvar -Recurse -Force diff --git a/client/configpcm_example.ini b/client/configpcm_example.ini index 4c13804..650470a 100644 --- a/client/configpcm_example.ini +++ b/client/configpcm_example.ini @@ -1,2 +1,3 @@ server=http://miserver.dominio:3333 -resources=\\\\MISERVER\\REPOFOLDER \ No newline at end of file +resources=\\\\MISERVER\\REPOFOLDER +lang=es \ No newline at end of file diff --git a/client/control.pyw b/client/control.pyw index 4958e22..93e24f7 100644 --- a/client/control.pyw +++ b/client/control.pyw @@ -1,10 +1,11 @@ #!/usr/bin/python3 -# Version 0.6 +# Version 0.61 import easygui import configparser import json import requests import subprocess, platform +from translation import T def ping(host): """ @@ -40,10 +41,15 @@ def sendsettoapi(suburl,goodtext): # Send a add/del/modify to API. Doesn't retur global c_server try: jsonobj = json.loads(requests.get(c_server+suburl).text) + #jsonobj['RESULT'] has to exist for next if + try: + jsonobj['RESULT'] + except: + jsonobj['RESULT'] = "" if jsonobj is not None and jsonobj['RESULT'] is not None and jsonobj['RESULT'] == 'ERROR': - if jsonobj['TEXT']: + try: easygui.msgbox(jsonobj['TEXT'],"Error","Ok") - else: + except: easygui.msgbox("Error no especificado","Error","Ok") return 1 else: @@ -70,7 +76,7 @@ c_resources = config['General']['resources'].replace('\\\\','\\') def menuprinc(): - menu = sendmenudot("Menú principal","Seleccione opción",['1.Equipos','2.Grupos','3.Recetas','4.Reportes/Listados']) + menu = sendmenudot(T('Main menu'),T('Select option'),['1.'+T('Computers'),'2.'+T('Groups'),'3.'+T('Cooks'),'4.Reportes/Listados']) if menu == '1': mcomputers() elif menu == '2': @@ -82,20 +88,25 @@ def menuprinc(): def mcomputers(): global c_server - menu = sendmenudot("Menú equipos","Seleccione opción",['1.Añadir equipo','2.Borrar equipo','3.Añadir equipo a un grupo','4.Listado de equipos']) + menu = sendmenudot(T('Computers menu'),T('Select option'),['1.'+T('Add computer'),'2.'+T('Remove computer'),'3.'+T('Add computer to group'),'4.'+T('Computers list'),'5.'+T('Computer status')]) if menu == '1': - newcomputer = easygui.enterbox("Nombre del nuevo equipo","Añadir equipo") - if easygui.ynbox("Nombre del equipo: '"+newcomputer+"'. ¿Seguro?","Añadir equipo"): + newcomputer = easygui.enterbox("Nombre del nuevo equipo",T('Add computer')) + if easygui.ynbox("Nombre del equipo: '"+newcomputer+"'. ¿Seguro?",T('Add computer')): sendsettoapi("/add/computer?ComputerName="+newcomputer,"Equipo añadido a la base de datos") elif menu == '2': - whatc = showchoicesapi("Seleccione equipo a borrar","Borrar equipo",c_server+"/get/computers") - if whatc is not None and easygui.ynbox("Se va a borrar el equipo '"+whatc+"'. ¿Seguro?","Borrar equipo"): - sendsettoapi("/del/computer?ComputerName="+whatc,"Equipo borrado") + whatc = showchoicesapi("Seleccione equipo a borrar",T('Remove computer'),c_server+"/get/computers") + if whatc is not None and easygui.ynbox("Se va a borrar el equipo '"+whatc+"'. ¿Seguro?",T('Remove computer')): + sendsettoapi("/del/computer?ComputerName="+whatc,T('Computer deleted')) elif menu == '3': m_addcomputergroup() elif menu == '4': - showchoicesapi("Lista de equipos","Listado de equipos",c_server+"/get/computers") + showchoicesapi(T('Computers list'),T('Computers list'),c_server+"/get/computers") + elif menu == '5': + computer = showchoicesapi(T('Select a computer'),T('Computer status'),c_server+"/get/computers") + showchoicesapi(T('Cooks of computer')+' '+computer,T('Computer status'),c_server+"/get/cookpend?ComputerName="+computer+"&SeeAll=1") + showchoicesapi(T('Cooks pending of computer')+' '+computer,T('Computer status'),c_server+"/get/cookpend?ComputerName="+computer) + showchoicesapi(T('Groups of computer')+' '+computer,T('Computer status'),c_server+"/get/groups?ComputerName="+computer) elif menu is None: menuprinc() return @@ -103,15 +114,15 @@ def mcomputers(): def mgroups(): global c_server - menu = sendmenudot("Menú grupos","Seleccione opción",['1.Añadir grupo','2.Borrar grupo','3.Añadir equipo a un grupo','4.Quitar equipo de un grupo','5.Listado de grupos','6.Listado de equipos de un grupo']) + menu = sendmenudot(T('Groups menu'),T('Select option'),['1.'+T('Add group'),'2.'+T('Remove group'),'3.'+T('Add computer to group'),'4.'+T('Remove computer of a group'),'5.Listado de grupos','6.Listado de equipos de un grupo']) if menu == '1': - newgroup = easygui.enterbox("Nombre del nuevo grupo","Añadir grupo") - if easygui.ynbox("Nombre del grupo: '"+newgroup+"'. ¿Seguro?","Añadir grupo"): + newgroup = easygui.enterbox(T('New group name'),T('Add group')) + if easygui.ynbox("Nombre del grupo: '"+newgroup+"'. ¿Seguro?",T('Add group')): sendsettoapi("/add/group?GroupName="+newgroup,"Grupo añadido a la base de datos") elif menu == '2': - group = showchoicesapi("Lista de grupos. Selecciona uno para borrarlo","Borrar grupo",c_server+"/get/groups",'Name') - if group is not None and easygui.ynbox("Borrar grupo '"+group+"'. ¿Seguro?","Borrar grupo"): - sendsettoapi("/del/group?GroupName="+group,"Grupo borrado") + group = showchoicesapi("Lista de grupos. Selecciona uno para borrarlo",T('Remove group'),c_server+"/get/groups",'Name') + if group is not None and easygui.ynbox("Borrar grupo '"+group+"'. ¿Seguro?",T('Remove group')): + sendsettoapi("/del/group?GroupName="+group,T('Group deleted')) elif menu == '3': m_addcomputergroup() elif menu == '4': @@ -124,12 +135,12 @@ def mgroups(): elif menu is None: menuprinc() return - mcomputers() + mgroups() def mcooks(): global c_server global c_resources - menu = sendmenudot("Menú recetas","Seleccione opción",['1.Detalles de una receta','2.Renombrar receta','3.Añadir receta a un grupo','4.Eliminar receta de un grupo','5.Grupos de una receta']) + menu = sendmenudot(T('Cooks menu'),T('Select option'),['1.Detalles de una receta','2.Renombrar receta','3.Añadir receta a un grupo','4.Eliminar receta de un grupo','5.Grupos de una receta']) if menu == '1': cook = showchoicesapi("Lista de recetas implementadas en algún grupo. Selecciona una para ver sus datos","Detalles de una receta",c_server+"/get/cookall",'CookName') if cook is not None: @@ -156,7 +167,7 @@ def mcooks(): if newname is not None and easygui.ynbox("Cambiar nombre de la receta '"+cook+"' por '"+newname+"'. ¿Seguro?","Renombrar receta"): sendsettoapi("/upd/cookname?CookName="+cook+"&CookNewName="+newname,"Receta cambiada de nombre") elif menu == '3': - cook = easygui.enterbox("Nombre de la receta","Añadir receta a un grupo") + cook = easygui.enterbox(T('Name of the cook'),"Añadir receta a un grupo") group = showchoicesapi("Lista de grupos existentes","Listado de grupos",c_server+"/get/groups") if easygui.ynbox("Añadir la receta "+cook+" al grupo '"+group+"'. ¿Seguro?","Añadir receta a un grupo"): sendsettoapi("/add/cookgrp?CookName="+cook+"&GroupName="+group,"Receta añadida al grupo") @@ -179,20 +190,20 @@ def mcooks(): def mreports(): global c_server global c_resources - menu = sendmenudot("Menú reportes","Seleccione opción",['1.Listado de equipos','2.Listado de grupos','3.Equipos y recetas de un grupo','4.Grupos de una receta']) + menu = sendmenudot(T('Reports menu'),T('Select option'),['1.'+T('Computers list'),'2.'+T('Groups list'),'3.Equipos y recetas de un grupo','4.Grupos de una receta']) if menu == '1': #Listado de equipos - showchoicesapi("Lista de equipos","Listado de equipos",c_server+"/get/computers") + showchoicesapi(T('Computers list'),T('Computers list'),c_server+"/get/computers") elif menu == '2': #Listado de grupos - showchoicesapi("Lista de grupos","Listado de grupos",c_server+"/get/groups") + showchoicesapi(T('Groups list'),T('Groups list'),c_server+"/get/groups") elif menu == '3': - group = showchoicesapi("Lista de grupos","Listado de grupos",c_server+"/get/groups") - showchoicesapi("Lista de equipos del grupo "+group,"Listado de equipos y recetas de un grupo",c_server+"/get/computersgrp?GroupName="+group) - showchoicesapi("Lista de recetas del grupo "+group,"Listado de equipos y recetas de un grupo",c_server+"/get/cookgrp?GroupName="+group,'CookName') + group = showchoicesapi(T('Groups list')+'. '+T('Select a group'),T('Groups list'),c_server+"/get/groups") + showchoicesapi("Lista de equipos del grupo "+group,T('List of computers and cooks of a group'),c_server+"/get/computersgrp?GroupName="+group) + showchoicesapi("Lista de recetas del grupo "+group,T('List of computers and cooks of a group'),c_server+"/get/cookgrp?GroupName="+group,'CookName') elif menu == '4': cook = showchoicesapi("Lista de recetas con grupo. Selecciona una para ver sus grupos","Listado de grupos de una receta",c_server+"/get/cookall",'CookName') if cook is not None: - showchoicesapi("Lista de grupos de la receta "+cook,"Listado de grupos de una receta",c_server+"/get/grpcook?CookName="+cook) + showchoicesapi("Lista de grupos de la receta "+cook,T('List of groups of a cook'),c_server+"/get/grpcook?CookName="+cook) elif menu is None: menuprinc() return @@ -200,22 +211,22 @@ def mreports(): def m_addcomputergroup(): - whatc = howchoicesapi("Seleccione equipo a añadir a un grupo","Añadir Equipo a grupo",c_server+"/get/computers") + whatc = showchoicesapi(T('Select computer to add to a group'),T('Add computer to group'),c_server+"/get/computers") if whatc is None: return - whatg = showchoicesapi("Seleccione grupo a ser añadido","Añadir Equipo a grupo",c_server+"/get/groups") + whatg = showchoicesapi(T('Select group to be added'),T('Add computer to group'),c_server+"/get/groups") if whatg is None: return sendsettoapi("/add/grpcomputer?ComputerName="+whatc+"&GroupName="+whatg,"Equipo añadido al grupo") def m_delcomputergroup(): - group = showchoicesapi("Seleccione grupo del que quitar un equipo","Borrar equipo de un grupo",c_server+"/get/groups") - if group is None: - return - computer = showchoicesapi("Seleccione grupo a ser quitado","Borrar equipo de un grupo",c_server+"/get/computersgrp?GroupName="+group) + computer = showchoicesapi("Seleccione equipo para buscar un grupo que borrar",T('Remove computer of a group'),c_server+"/get/computers") if computer is None: return - if easygui.ynbox("Quitar el equipo "+computer+" del grupo '"+group+"'. ¿Seguro?","Borrar equipo de un grupo"): + group = showchoicesapi(T('Select group to delete'),T('Remove computer of a group'),c_server+"/get/groups?ComputerName="+computer) + if group is None: + return + if easygui.ynbox("Quitar el equipo "+computer+" del grupo '"+group+"'. ¿Seguro?",T('Remove computer of a group')): sendsettoapi("/del/grpcomputer?ComputerName="+computer+"&GroupName="+group,"Equipo quitado del grupo") menuprinc() diff --git a/client/translation.py b/client/translation.py new file mode 100644 index 0000000..01cf3b6 --- /dev/null +++ b/client/translation.py @@ -0,0 +1,62 @@ +import configparser + +t_cp = configparser.ConfigParser() +t_cp.read('configpcm.ini') + +t_tlang = t_cp['General']['lang'] + +def T(textid): + textid = textid.strip() + global t_tlang + try: + if t_tlang == 'es': + return T_es(textid) + elif t_tlang == 'en': + return T_en(textid) + else: + return textid + except: + return textid + + + +def T_es(textid): + dict = { + 'Main menu': 'Menú principal', + 'Select option': 'Seleccione opción', + 'Computers': 'Equipos', + 'Groups': 'Grupos', + 'Cooks': 'Recetas', + 'Computers list': 'Lista de equipos', + 'Groups list': 'Lista de grupos', + 'Computer deleted': 'Equipo eliminado', + 'Add computer': 'Añadir equipo', + 'Remove computer': 'Borrar equipo', + 'Add group': 'Añadir grupo', + 'Remove group': 'Borrar grupo', + 'Group deleted': 'Grupo eliminado', + 'Select a computer': 'Selecciona un equipo', + 'Computer status': 'Estado de un equipo', + 'Add computer to group':'Añadir equipo a un grupo', + 'Remove computer of a group':'Quitar equipo de un grupo', + 'Name of the cook':'Nombre de la receta', + 'Select a group': 'Seleccione un grupo', + 'Cooks of computer': 'Recetas del equipo', + 'Groups of computer':'Grupos del equipo', + 'Cooks pending of computer': 'Recetas pendientes del equipo', + 'New group name':'Nombre del nuevo grupo', + 'Computers menu':'Menú equipos', + 'Groups menu':'Menú grupos', + 'Cooks menu':'Menú recetas', + 'Reports menu':'Menú reportes', + 'List of computers and cooks of a group':'Listado de equipos y recetas de un grupo', + 'List of groups of a cook':'Listado de grupos de una receta', + 'Select computer to add to a group':'Seleccione equipo para añadir a un grupo', + 'Select group to be added':'Seleccione grupo a ser añadido', + 'Select group to delete':'Seleccione grupo a quitar' + } + + return dict[textid] + +def T_en(textid): + return textid #English doesn't have to be translated \ No newline at end of file