Saludos a todos, soy nuevo usando python y me interesa desarrollar una aplicacion que desde mi celular pueda apagar, reiniciar y bloquear la pantalla de mi pc, basicamente esas 3 funciones, algunas personas me han dicho que debo usar la libreria pywinrm, otras me dicen que ssh, y otras me dicen que debo desarrollar la app 2 veces, para desktop y para android y no estoy del todo claro. Algun desarrollador que utilice python que me pueda decir los pasos o que es lo que tendria que utilizar para hacerlo? Muchas gracias.
Necesitas una aplicación android. OJO: puedes usar el navegador como cliente para mandar los comandos. Por ejemplo:
197.72.183.34/comando?c=apagar
197.72.183.34/comando?c=encender
A parte de usar el navegador puedes desarrollar tu la aplicación. Siendo para Android deberías usar Java. También puedes usar html+javascript aunque quizás no sea tan cómodo como una aplicación en Java que puedes automatizar. O si qiieres usar cualquier otro lenguaje como oueda ser Python, puedes optar directamente por Termux y ahí disponer de todos los lenguajes como si un sistema Linux se tratase o descargar Pydroid3 si solo vas a desarrollar en Python y usar comandos muy simples.
Ahora, para el programa del pc puedes hacerlo con el lenguaje que quieras o directamente con comandos de la terminal y tareas programables.
Para que no te pierdas, el programa que hagas para Android tiene una única misión, enviar un texto para indicar lo que quieras hacer en el pc. Es super sencillo.
El programa del PC tiene la misión de escuchar los mensajes y ejecutar código en base a ellos.
if textoRecibido == "Apagar":
codigo para apagar.
Para hacer estos programas tu mejor aliado son los sockets, que sirven para enviar datos a través de la red.
En python 2 programas de estas características son aproximadamente 10-15 lineas de código para el cliente y 20-30 para el servidor.
Como info adicional puedes invertir el proceso. Siendo el servidor el que se ejecute en Android y el cliente en el PC.
Por otro lado tienes que abrir puertos del router hacia el dispositivo que RECIBA la conexión.
Si buscas por google python client sockets o python server sockets te saldrán un montón de ejemplos.
Ejemplo de cliente:
import socket
def netcat(host, puerto, contenido):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, puerto))
contenido="GET /index.html HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n"
contenido = contenido.encode('utf-8')
s.sendall(contenido)
response = b''
while 1:
recv = s.recv(2048)
resp = repr(recv)
respT= len(resp)
if respT < 5:
break
response += recv
s.shutdown(socket.SHUT_WR)
s.close()
return response
respuesta = netcat("google.com" , 80 , 1)
print(respuesta)
print("Fin ejec")
Ejemplo código servidor:
import socket
s = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
host = s.gethostname()
port = 9999
serversocket.bind((host, port))
nOR=5
serversocket.listen(nOR)
while True:
clientsocket,addr = serversocket.accept()
print("Got a connection from %s" % str(addr)) msg = 'Thank you for connecting'+ "\r\n"
clientsocket.send(msg.encode('ascii'))
clientsocket.close()
El cliente lo tengo testeado y funciona correctamente aunque necesita mucha mejora. El servidor no lo testee.
Te recomiendo hacerlo de 0. Estes códigos solo los comparto como ejemplos para que más o menos veas como es la historia. No como códigos totalmente funcionales y listos para usar.
Aquí te dejo también un mini ejemplo del uso de sockets en Java. En este caso es parte del código de un servidor RAT para controlar un Android que programé el otro día.
package com.stringmanolo.rs;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import android.os.SystemClock;
/* Mensajes en la app para debug.
import android.widget.Toast;
*/
public class Conexion {
public static void Conectar(){
@Override
public void run() {
/* Intenta establecer una conexión a la dirección y puertos hardcodeados durante timeout*/
try {
/* Bloquea toda la aplicación */
SystemClock.sleep(30000);
socket.connect(new InetSocketAddress("192.168.11.1", 8585), 10000);
/* Muestra el error en un mensaje emergente en la aplicación por motivos de debug.
Toast.makeText(getApplicationContext(),errConexion.toString(),Toast.LENGTH_SHORT).show();
*/
}
/* Comunicación por el socket */
try {
String msgInicial
= "SISTEMA REMOTO OPERATIVO\nEscribe ayuda para mostrar una lista de comandos disponibles\n"; /* Envia el texto al cliente remoto */
peticion.write(msgInicial.getBytes("UTF-8"));
/* INCLUIR: Escribir info al establecer la conexión para identificar el servidor de forma única */
peticion.flush();
/* Recibe por el socket el texto a ejecutar */
/* Mientras se reciban datos desde el cliente */
while((linea = buffLeer.readLine()) != null) {
/* Innecesario, utilizar += en caso de querer loggear input del cliente */
respuesta = linea;
/* En caso de que el input recibido comienze por # */
if (respuesta.charAt(0) == '#') {
/* Quita el # para procesar el resto del input recibido */
respuesta = respuesta.substring(1);
try {
/* Pasa el comando directamente a la consola del sistema. */
/* CUIDADO: Vas crashear la aplicación si utilizas comandos no permitidos por el sistema. O comandos inexistentes. */
/* ALTERNATIVA: Implementa la utilidad o impórtala como librería para manejar las excepciones. */
/* PROBLEMA: No utilizar directamente binarios que requiera de input directo desde shell. */
/* SOLUCIÓN: La aplicación se reinicia cada X tiempo. Esto soluciona múltiples problemas relacionados con cuelges de servicios del sistema */
/* Obtiene el resultado en la consola del sistema del dispositivo generada por el comando. */
/* Mientras se reciba salida del sistema remoto */
while((salidaComando = salidaRemota.readLine()) != null) {
/* Añade saltos de linea a la salida tras cada linea. */
salidaComando += "\n";
/* Escribe en el socket */
peticion.write(salidaComando.getBytes("UTF-8"));
}
/* Muestra el error en un mensaje emergente en la aplicación por motivos de debug.
Toast.makeText(getApplicationContext(),err.toString(),Toast.LENGTH_SHORT).show();
*/
}
}
/* En caso de que el input recibido sea programas */
if (respuesta.trim().equals("programas")) {
/* Muestra los binarios disponibles en el sistema. */
while((salidaBin = stdInput.readLine()) != null) {
salidaBin += "\n";
peticion.write(salidaBin.getBytes("UTF-8"));
}
}
/* En caso de que el input recibido sea salir */
if (respuesta.trim().equals("salir")) {
/* Muestra un mensaje antes de salir. */
peticion.write("Aplicación Cerrada.\nAdios!\n".getBytes("UTF-8"));
/* Cierra el socket aquí o en OnStop */
socket.close();
/* Finaliza La Aplicación Forzosamente */
}
/* En caso de que el input recibido sea ayuda. */
if (respuesta.trim().equals("ayuda")) {
/* Muestra el texto. */
peticion.write("Acciones Disponibles:\nprogramas\n Lista todos los binarios preinstalados en el sistema remoto\n\n#comando\n Ejecuta el comando a continuación del símbolo #, por ejemplo #ls\n\nsalir\n Cierra la conexión y el programa remoto.\n".getBytes("UTF-8"));
}
}
/* Es obligatorio capturar la excepción */
}
} /* Fin Runneable */
}); /* Fin Hilo */
hilo.start();
}
}
Te dejo también el código javascript de un cliente:
function Enviar(ip, puerto, mensaje) {
var b = new XMLHttpRequest(), url = ip+"?mensaje="+mensaje+":"+puerto;
try{
b.onreadystatechange = function(){
if(b.readyState == 4 && b.status == 200) {
alert(b.responseText);
}
}
}catch(err){alert(err)}
b.open("GET", url, true);
b.send();
}
También puedes usar comados como netcat -l -k -v ip puerto > /bin/sh o cmd para exponer el pc a ser controlado directamente por comandos. Podrías usar grep para parsear el text enviado por el cliente y que se ejecute el comando directamente.
Si necesitas ejemplos en otros lenguajes de programación tengo desarrollados clientes y servidores en C, Cpp, php, lua, bash/batch, perl, node.js ....