Pues ya es público el (que yo sepa) único plugin funcional para http://series.ly y XBMC. Lo empecé a hacer hace un par de meses en mis ratos libres para poder mantenerme al día en cuanto a series, y aquí está!
Para instalarlo, lo único que hay que hacer es descargar el plugin desde http://bit.ly/sly_xbmc (mirror: https://github.com/plutec/seriesly_xbmc/blob/master/downloads/seriesly_xbmc.zip?raw=true) e instalarlo siguiendo las intrucciones que he publicado en el post anterior:
http://www.plutec.net/2014/04/instalar-plugin-xbmc-zip.html
Poco a poco lo actualizaré (la lista de TODOs es bastante amplia), y cualquier comentario es bienvenido tanto en github (algún error o mejora) como en los comentarios.
Un saludo!
miércoles, 23 de abril de 2014
Instalar plugin en XBMC desde un zip
Voy a explicar cómo instalar un plugin para XBMC partiendo de la base que tenemos el zip con el plugin en nuestro directorio de archivos. El procedimiento es muy simple, pero si nunca se ha hecho resulta un poco extraño, porque no sigue la jerarquía lógica de navegación:
- En primer lugar abrimos XBMC y nos vamos a Videos -> Add-ons,
- obtener más complementos,
- nos desplegará un menú a la derecha donde ya podremos elegir el archivo del plugin desde nuestro directorio de archivo del ordenador.
Un saludo!
Etiquetas:
XBMC
Ubicación:
Málaga, España
martes, 8 de abril de 2014
C y Python mediante sockets
Hoy toca el paso de comunicar un lenguaje de bajo nivel y consumo de recursos (C/C++) con uno que es un poco más avanzado y que consume más recursos (CPU y Memoria), como Python.
La historia general es que necesitaba comunicar una Fonera (la cuál no tiene muchos recursos) con un servidor central (RaspberryPi) que tiene toda la infraestructura desarrollada en Python. Para no complicarme la vida, hice un pequeño servidor en C para la Fonera y un cliente en Python para la Raspberry.
Este código corresponde a la Fonera, y lo podemos guardar como server.c (en Mega)
Lo compilamos para la Fonera y lo ejecutamos: (Compilando C/C++ para La Fonera (MIPS))
Ahora pasamos a crear el código en Python para guardarlo en la RaspberryPi como client.py (en Mega)
NOTA: En la dirección IP habría que poner la IP de la Fonera (servidor), en mi caso es la 192.168.1.69
Ya sólo tendríamos que ejecutar el cliente en la Raspberry con:
En ese momento, el cliente enviará al servidor el mensaje (request:variable\n), el servidor simulará su procesamiento durante 3 segundos y devolverá la respuesta. En esta caso, la respuesta coincide con los datos recibidos, pero no tiene que ser así.
Referencias:
La historia general es que necesitaba comunicar una Fonera (la cuál no tiene muchos recursos) con un servidor central (RaspberryPi) que tiene toda la infraestructura desarrollada en Python. Para no complicarme la vida, hice un pequeño servidor en C para la Fonera y un cliente en Python para la Raspberry.
Este código corresponde a la Fonera, y lo podemos guardar como server.c (en Mega)
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#define MAXLINE 4096 /* buffer length */
#define SERV_PORT 10001 /* port */
#define LISTENQ 8 /* maximum number of client connections */
/* This function read a character from a buffer (fd) until it reads
the character (until), and it saves in (data). */
int read_until(int fd, char *data, char until) {
int len = 0;
char a[1];
int n;
do {
n = recv(fd, a, 1, 0);
if (n>0) // OK
data[len++] = a[0];
} while (a[0]!=until);
data[len] = '\0';
return len;
}
int main (int argc, char **argv) {
int listenfd, connfd, n;
socklen_t client_len;
char buf[MAXLINE];
struct sockaddr_in cliaddr, servaddr;
// Socket creation
listenfd = socket (AF_INET, SOCK_STREAM, 0);
// Preparing the socket address
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind (listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
listen (listenfd, LISTENQ);
printf("Server running! Waiting...\n");
while(1) {
client_len = sizeof(cliaddr);
connfd = accept (listenfd, (struct sockaddr *) &cliaddr, &client_len);
printf("Received request...\n");
read_until(connfd, buf, '\n');
printf("Received content: %s" , buf);
// Proccess the content
// ...
sleep(3); //Simulating process time
// Send response
send(connfd, buf, strlen(buf), 0);
// Close client connection
close(connfd);
} // And wait for another client
// Close listening socket
close (listenfd);
}
Lo compilamos para la Fonera y lo ejecutamos: (Compilando C/C++ para La Fonera (MIPS))
$ mips-linux-gcc server.c -o server
$ ./server
Ahora pasamos a crear el código en Python para guardarlo en la RaspberryPi como client.py (en Mega)
import socket
import sys
SERVER = '192.168.1.69' # Server IP or domain
PORT = 10001 # Server port
"""
This function read a character from a buffer (fd) until it reads
the character (until), and return the string.
"""
def read_until(fd, until):
to_ret = ''
try:
a = fd.recv(1)
while a[0] != until:
to_ret += a
a = fd.recv(1)
to_ret += a
except:
print "Error: Socket closed (or another thing!) :P"
return None
return to_ret;
def main():
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect the socket to the port where the server is listening
server_address = (SERVER, PORT)
print 'Connecting to %s in port %s' % server_address
sock.connect(server_address)
try:
# Send message
message = 'request:variable\n'
print 'Sending: %s' % message
sock.sendall(message)
# Wait the response
data = read_until(sock, '\n')
print 'Received: %s' % data
finally:
print 'Closing socket'
sock.close()
if __name__ == '__main__':
main()
NOTA: En la dirección IP habría que poner la IP de la Fonera (servidor), en mi caso es la 192.168.1.69
Ya sólo tendríamos que ejecutar el cliente en la Raspberry con:
$ python client.py
En ese momento, el cliente enviará al servidor el mensaje (request:variable\n), el servidor simulará su procesamiento durante 3 segundos y devolverá la respuesta. En esta caso, la respuesta coincide con los datos recibidos, pero no tiene que ser así.
Referencias:
- http://www.cs.dartmouth.edu/~campbell/cs50/socketprogramming.html
- http://pymotw.com/2/socket/tcp.html
Ubicación:
Málaga, España
sábado, 5 de abril de 2014
API para series.ly (sin token)
Hace un par de meses comencé un mini-proyectito personal para poder ver series y películas sentado cómodamente en mi sofá con la RaspberryPi y sin tener que descargarlas previamente, pero esto vendrá en otra entrega. :P
Solicité acceso a la API de Series.ly y estuve unos 5 días esperando respuesta, sin resultado positivo. Tras ver esto, empecé a indagar en algunos foros y vi que había gente que llevaba esperando más de 5 meses para obtenerla, así que miré un poco el código fuente de la web, las peticiones JavaScript, y aquí está el resultado. Una API de series.ly en Python y basada en la página web, es decir, sin necesidad de tener acceso a la API oficial (con token necesario).
Con la API se puede loguear, ver "mis series", "mis películas", cambiar estados, ver los links disponibles para cierta película/serie, información sobre capítulos.
Para que veáis lo fácil que es utilizarla, os dejo el archivo de ejemplos (también está en GitHub):
Si alguien necesita una invitación a series.ly, que lo pida por Twitter, comentarios, email o cualquier otro medio que encuentre. :P
Solicité acceso a la API de Series.ly y estuve unos 5 días esperando respuesta, sin resultado positivo. Tras ver esto, empecé a indagar en algunos foros y vi que había gente que llevaba esperando más de 5 meses para obtenerla, así que miré un poco el código fuente de la web, las peticiones JavaScript, y aquí está el resultado. Una API de series.ly en Python y basada en la página web, es decir, sin necesidad de tener acceso a la API oficial (con token necesario).
https://github.com/plutec/apisly
Con la API se puede loguear, ver "mis series", "mis películas", cambiar estados, ver los links disponibles para cierta película/serie, información sobre capítulos.
Para que veáis lo fácil que es utilizarla, os dejo el archivo de ejemplos (también está en GitHub):
import sly
api = sly.APISLY(username='username', password='password')
print api.my_series()
print api.my_movies()
print api.get_serie_info('7HV4DXUHE5', 1)
print api.search('anillos')
print api.get_film_info('NE2FYXX5KE', 2)
print api.get_links(1653, 2)
print api.get_activity()
Si alguien necesita una invitación a series.ly, que lo pida por Twitter, comentarios, email o cualquier otro medio que encuentre. :P
Ubicación:
Málaga, España
lunes, 24 de marzo de 2014
Compilando C/C++ para La Fonera (MIPS)
En esta entrada quiero mostrar lo sencillo que es programar en C/C++ para la Fonera (arquitectura MIPS). En la Fonera que cogí, ya tengo instalado dd-wrt, pero da exactamente igual que se tenga OpenWRT. Hay muchos manuales por Internet para flashearlas.
Para compilar, una de las opciones es aumentar el espacio de almacenamiento de la Fonera e instalar el SDK allí. La otra opción, mucho más simple, es compilar en nuestra máquina y moverlo a la Fonera con un simple "scp", así que vamos a por esta segunda opción.
Si estás usando dd-wrt, debes activar el servicio SSH a través de su interfaz web.
Lo primero que tenemos que hacer es descargar el SDK de la página de OpenWRT para x86_64 (mirror), descomprimirlo en una carpeta, e introducir la ruta del mismo en el PATH del sistema:
Después, creamos un "Hola Mundo!", guardando como hello_world.c:
Y lo compilamos:
Si en lugar de código en C, queremos compilar código en C++, el comando sería el siguiente:
Lo mandamos a La Fonera con "scp" (la contraseña solicitada es la del panel de administración, y el usuario siempre root, da igual el que uses en la interfaz web):
Entramos a la Fonera (nos pedirá la contraseña del panel de administración web, de nuevo):
Y probamos nuestro "Hola Mundo!"
Et voilà!
Para compilar, una de las opciones es aumentar el espacio de almacenamiento de la Fonera e instalar el SDK allí. La otra opción, mucho más simple, es compilar en nuestra máquina y moverlo a la Fonera con un simple "scp", así que vamos a por esta segunda opción.
Si estás usando dd-wrt, debes activar el servicio SSH a través de su interfaz web.
Lo primero que tenemos que hacer es descargar el SDK de la página de OpenWRT para x86_64 (mirror), descomprimirlo en una carpeta, e introducir la ruta del mismo en el PATH del sistema:
wget http://downloads.openwrt.org/kamikaze/7.06/atheros-2.6/OpenWrt-SDK-atheros-2.6-for-Linux-x86_64.tar.bz2
tar xvjf OpenWrt-SDK-atheros-2.6-for-Linux-x86_64.tar.bz2
export PATH=$PATH:~/OpenWrt-SDK-atheros-2.6-for-Linux-x86_64/staging_dir_mips/bin/
Después, creamos un "Hola Mundo!", guardando como hello_world.c:
#include <stdio.h>
int main()
{
printf("Hello World!\n");
return 0;
}
Y lo compilamos:
mips-linux-gcc hello_world.c -o hello
Si en lugar de código en C, queremos compilar código en C++, el comando sería el siguiente:
mips-linux-g++ hello_world.cc -o hello
Lo mandamos a La Fonera con "scp" (la contraseña solicitada es la del panel de administración, y el usuario siempre root, da igual el que uses en la interfaz web):
scp hello root@192.168.1.X:
Entramos a la Fonera (nos pedirá la contraseña del panel de administración web, de nuevo):
ssh root@192.168.1.X
Y probamos nuestro "Hola Mundo!"
root@fonera:~$ ./hello
Hello World!
Et voilà!
Ubicación:
Málaga, España
domingo, 23 de marzo de 2014
Comunicando PHP y Python con sockets
Después de tanto tiempo sin escribir nada (¿alguna vez he escrito algo?), me voy a poner a ello!
Como parte de un proyecto algo más grande que estoy desarrollando (y que pronto dejaré libre), una de las partes es comunicar una interfaz web desarrollada en PHP y un gestor de información implementado en Python y ambos en máquinas diferentes comunicadas por red local. He optado por utilizar sockets para comunicar ambas partes, Python en modo servidor y el PHP jugando la parte cliente.
Vamos a empezar con la parte cliente (PHP):
Guardamos este como client.php y pasamos a implementar el servidor (Python).
Lo guardamos como server.py
Abrimos una consola y ejecutamos el servidor con:
Sin cerrar el servidor (obviamente), lanzamos esto para que el cliente haga una petición:
Y en pantalla nos mostrará la información que ha enviado el servidor con unas pocas líneas más de debug.
La parte del cliente también se puede guardar en el directorio de nuestro servidor web (Apache, nginx...) y lanzarlo a través de una llamada al navegador.
Curiosidades:
Como parte de un proyecto algo más grande que estoy desarrollando (y que pronto dejaré libre), una de las partes es comunicar una interfaz web desarrollada en PHP y un gestor de información implementado en Python y ambos en máquinas diferentes comunicadas por red local. He optado por utilizar sockets para comunicar ambas partes, Python en modo servidor y el PHP jugando la parte cliente.
Vamos a empezar con la parte cliente (PHP):
<?php
error_reporting(E_ALL);
$address = gethostbyname('localhost');
$service_port = 10000;
/* Create a TCP/IP socket */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
echo "socket_create() fails: Reason: " . socket_strerror(socket_last_error()) . "<br/>";
} else {
echo "Socket created.<br/>";
}
echo "Trying connect to '$address' in port '$service_port'...";
$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
echo "socket_connect() fails. Reason: $result " . socket_strerror(socket_last_error($socket)) . "\n";
} else {
echo "OK.<br/>";
}
$in = "OLAKASE, I'm your POU oversized to fill more than 16 characters";
socket_write($socket, $in, strlen($in));
echo "Receiving...<br/>";
$all_out = '';
while ($out = socket_read($socket, 2048)) {
$all_out .= $out;
}
echo "Received: ". $all_out . "<br/>";
echo "Closing socket...<br/>";
socket_close($socket);
echo "Closed.";
?>
Guardamos este como client.php y pasamos a implementar el servidor (Python).
import socket
# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to the port
server_address = ('localhost', 10000)
print 'Starting up on %s port %s' % server_address
sock.bind(server_address)
# Listen for incoming connections
sock.listen(5)
while True:
# Wait for a connection
print 'Waiting for a connection'
connection, client_address = sock.accept()
try:
print 'Connection from: ', client_address
# Receive the data in small chunks
try:
all_data = ''
while True:
data = ''
try:
data = connection.recv(16, socket.MSG_DONTWAIT)
except:
pass
if data:
all_data += data
else:
break
print 'Received "%s"' % all_data
if all_data:
# -------------------
# Process input data and generate your output info
# -------------------
print '** Sending info to the client **'
print info
connection.sendall(info)
except:
break
finally:
try:
connection.close()
except:
pass
Lo guardamos como server.py
Abrimos una consola y ejecutamos el servidor con:
python server.py
Sin cerrar el servidor (obviamente), lanzamos esto para que el cliente haga una petición:
php client.php
Y en pantalla nos mostrará la información que ha enviado el servidor con unas pocas líneas más de debug.
La parte del cliente también se puede guardar en el directorio de nuestro servidor web (Apache, nginx...) y lanzarlo a través de una llamada al navegador.
Curiosidades:
- En la parte servidora, se recoge la información de 16 en 16 bytes y se almacena en una cadena más grande. Aquí se podría poner algún tipo de control, para no causar un "buffer overflow" (lo mismo en la recepción de la parte cliente).
- Los datos que se envían (servidor) yo los quería mandar estructurados, y no una simple cadena, así que he hecho uso de JSON antes de enviarlo con "connection.sendall(info)" y así en el cliente se pueden "decodificar" a su recepción. Esta técnica también se puede usar en el cliente para solicitar los datos al servidor.
- En el cliente, "gethostbyname('localhost');" se puede sustituir directamente por la IP.
- He usado un puerto alto (10000) para no necesitar permisos de superusuario a la hora de ejecutar el servidor, así, si se consigue ejecutar código arbitrario, al menos tendría sólo permisos de usuario... (It's something!).
- Al principio del post he dicho que las máquinas están comunicadas por red local, pero en este ejemplo están en la misma máquina.
- Fin!
Referencias:
- http://pymotw.com/2/socket/tcp.html
- http://no.php.net/manual/en/sockets.examples.php
Ubicación:
Málaga, España
domingo, 10 de marzo de 2013
Nuevo propósito?
Como próposito de año nuevo (por decir algo), voy a intentar continuar con el blog.
Poco a poco iré insertando las entradas antiguas a la vez que publicando contenido más reciente, desde reseñas de libros a pequeños tutoriales con problemas que me he encontrado en mi día a día (tecnológicamente hablando).
Poco a poco iré insertando las entradas antiguas a la vez que publicando contenido más reciente, desde reseñas de libros a pequeños tutoriales con problemas que me he encontrado en mi día a día (tecnológicamente hablando).
Suscribirse a:
Entradas (Atom)





