2016-02-06

usborne have made their 1980s computer programming books available as free downloads

Mike Atherton (@MikeAtherton) twitteó a las 6:35 p. m. on vie., feb. 05, 2016:
Wow. @usborne have made their 1980s computer programming books available as free downloads. https://t.co/PiBxpAyXZo https://t.co/cqaGTteCfG
(https://twitter.com/MikeAtherton/status/695662160261865472?s=09)

Obtén la aplicación oficial de Twitter en https://twitter.com/download?s=13

2015-10-31

Dando el paseito



Enviado desde mi smartphone BlackBerry 10.

2014-08-15

Plex: Bajar subtítulos de los episodios "on deck"


El script con el que me bajo los subtítulos de los episodios "on deck" es este (yo lo llamo "subtitulosOnDeck.sh"):


# ruta de la b.d. de Plex Media Server
RUTABD="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db"

# ejecucion de la query en sqlite
cat queryFicherosOnDeckSubs.sql | sqlite3 "$RUTABD" 


# me bajo los subtitulos de todos los ficheros de la lista
while read unfichero; do

  # borro los subtitulos que haya...
  sinextension=${unfichero%.*}
  rm "$sinextension"*srt 

  subliminal -l en es -- "$unfichero"

done < "ficherosondecksubs.txt"


Explicación: la primera línea mete en la variable "RUTABD" la ruta de la b.d. de plex, que no es más que un fichero. Como es tan complicada la meto en una variable porque si no luego el comando no hay quien lo entienda.

La segunda línea ejecuta la query, que está en el fichero "queryFicherosOnDeckSubs.sql" enchufándosela al "sqlite3", que es el motor de base de datos que usa plex. La query genera un fichero que se llama "ficherosondecksubs.txt". Luego para cada línea de ese fichero, ejecuta "subliminal".

En la query aparecen las secciones que se tienen en cuenta en la línea 19. Si quieres que las tenga en cuenta todas, pues bastaría con eliminar las líneas 18 y 19. Si quieres tener en cuenta más secciones, basta con separarlas por comas, por ejemplo ("03 TVShows", "01 Series", "02 Peliculas")

Los dos ficheros, a continuación:




2014-05-10

Popcorn Time

Para ver pelis en inglés.... muy bueno:

Popcorn Time - Download

2013-12-19

Servidor casero (linux) de DNS y DHCP

Si tu router es una mierda, como el mío, aunque tenga DHCP no podrás hacer cosas como:

  • asignarle (centralizadamente) a cada máquina de la red la IP que me de la gana
  • asignarle a cada IP el nombre que me de la gana, porque no tiene DNS

Sin embargo, con un servidor linux y dnsmasq no puede ser más fácil:

Instalamos dnsmasq:

$ sudo apt-get install dnsmasq


Modificamos el fichero /etc/dnsmasq.conf (pongo sólo las líneas interesantes y sus comentarios correspondients):

# If you don't want dnsmasq to read /etc/resolv.conf or any other
# file, getting its servers from this file instead (see below), then
# uncomment this.
#
# Como prefiero tener cuantos menos ficheros mejor, configuraré los servidores
# DNS en este mismo fichero (los de Google, los de R, etc...)
no-resolv

# Add other name servers here, with domain specs if they are for
# non-public domains.
#server=/localnet/192.168.0.1
server=213.60.205.175
server=213.60.205.173
server=212.51.32.254
server=8.8.8.8

server=8.8.4.4

# Set this (and domain: see below) if you want to have a domain
# automatically added to simple names in a hosts-file.
# Creo que no hay otra forma de indicarle los nombres, cuando me interesa
# dárselos yo, van a ir en el fichero /etc/hosts

expand-hosts

# Set the domain for dnsmasq. this is optional, but if it is set, it
# does the following things.
# 1) Allows DHCP hosts to have fully qualified domain names, as long
#     as the domain part matches this setting.
# 2) Sets the "domain" DHCP option thereby potentially setting the
#    domain of all systems configured by DHCP
# 3) Provides the domain part for "expand-hosts"
# Los PCs de mi red local se van a llamar xxxx.LAN.local

domain=LAN.local

# Uncomment this to enable the integrated DHCP server, you need
# to supply the range of addresses available for lease and optionally
# a lease time. If you have more than one network, you will need to
# repeat this for each network on which you want to supply DHCP
# service.
# Este es el rango de IPs que el servidor va a asignar de forma dinámica

dhcp-range=10.0.1.11,10.0.1.99,12h

# Always allocate the host with Ethernet address 11:22:33:44:55:66
# The IP address 192.168.0.60
# Esta máquina va a tener siempre esta IP, por narices

dhcp-host=00:1F:F3:42:33:FF,10.0.1.2

# Override the default route supplied by dnsmasq, which assumes the
# router is the same machine as the one running dnsmasq.
# La ip de mi router (default gateway) es 10.0.1.1

dhcp-option=3,10.0.1.1


El fichero tiene millones de opciones, pero creo que con estas llega.

Luego sólo falta modificar el fichero /etc/hosts para forzar un nombre a aquellas máquinas que no lo tienen, o nos interesa darle uno por cualquier motivo. Por ejemplo:

127.0.0.1       localhost
10.0.1.10       miservidor
10.0.1.1        cablemodem


Las asignaciones dinámicas se almacenan (por defecto) en /var/lib/misc/dnsmasq.leases, ahí podemos mirar cómo está la cosa.









2013-11-19

Actualizar Microserver a la ultima version de Ubuntu


No tuve muchos problemas. Así de memoria:

 - Para actualizar (a una ubuntu que no es LTS), las instrucciones están aquí: https://help.ubuntu.com/community/QuantalUpgrades
 - Luego ya te va diciendo él solito que hay versiones posteriores, y que tienes que ejecutar "do-release-upgrade"
 - al actualizar él solito quita el plex de /etc/apt/sources.lst, con lo que se desinstala (de todas formas, no está actualizado... fue volver a bajar el .deb y volverlo a instalar, no se perdió la configuración ni nada), a ver si lo arreglan algún día 
 - me encontré con este problema: http://askubuntu.com/questions/202027/unable-to-configure-a-service-to-run-at-startup-with-update-rc-d (hay un pequeño bug en la configuración del transmission, y no arranca automáticamente al reiniciar, pero es fácil de corregir)
 - tenía conectada una unidad de red (configurada en el /etc/fstab) y dejó de funcionar, pero creo que el problema es bastante específico de la airport extreme actuando como servidor samba, lo arreglé poniendo sec=ntlm en los parametros

Eso es todo. Ahora estoy con el ubuntu 13.10, que incluye transmission-daemon 2.82 (que es lo que yo quería). Sickbeard, subliminal, etc... ni se enteraron


2013-09-28

2013-08-29

Sacarle más partido a Plex con un poco de SQL

Si no conoces Plex, échale un ojo: http://www.plexapp.com, además de las aplicaciones para Windows y Mac (gratuitas) tienen unos excelentes clientes (baratillos) para iOS y Android que, en sus versiones "premium" (plexpass) tienen una funcionalidad interesante, llamada PlexSync.

Resumidamente, plexsync premite sincronizar automáticamente ciertos contenidos en nuestros dispositivos móviles para, por ejemplo, llevar siempre los episodios que no hemos visto de nuestra serie favorita en el tablet o el móvil.

Como Plex almacena el catálogo de contenidos en una base de datos (SQLite 3) podemos montarnos un plexsync casero con un poco de SQL... le pongo muchos comentarios para que se entienda:

--
--  solo me interesa la ruta del fichero, para llegar a ella
--  tengo que enlazar las tablas 
--  METADATA_ITEMS, MEDIA_ITEMS y MEDIA_PARTS 
--  METADATA_ITEMS es la tabla principal, por asi decirlo
select distinct P.file  
  from METADATA_ITEMS I
           --

           -- tengo varias secciones (musica, peliculas en ingles, etc...)
           -- y no me interesan todas, asi que enlazo la tabla LIBRARY_SECTIONS
           -- para poder filtrar  
           inner join LIBRARY_SECTIONS L       
              on I.library_section_id = L.id
           --

           -- la tabla METADATA_ITEM_SETTINGS me interesa porque es ahí
           -- donde plex almacena si has visto o no el item 
           left outer join METADATA_ITEM_SETTINGS S
              on I.guid = S.guid

           --
           -- ahora vienen las dos tablas que necesito para llegar al
           -- nombre del fichero
           inner join MEDIA_ITEMS M            
              on I.id = M.metadata_item_id
           inner join MEDIA_PARTS P            
              on M.id = P.media_item_id

           --
           -- los episodios de una serie se agrupan en temporadas (el
           -- item "padre") y, a su vez, en series (el "abuelo")        
           left outer join METADATA_ITEMS IPadre
              on I.parent_id = IPadre.id
           left outer join METADATA_ITEMS IAbuelo
              on IPadre.parent_id = IAbuelo.id
 where 

   --
   -- los "no vistos":
   ( S.view_count = 0 or S.view_count is null)
   --

   -- las secciones que me interesan:
   and L.name in
          ("01 Series",
           "02 Peliculas",
           "03 TVShows")

   --
   -- y, ahora viene lo chulo: me interesan los 3 siguientes episodios
   -- de cada serie, así que para cada fila que me devuelve la query 
   -- compruebo si el episodio es uno de los tres primeros que me devuelve
   -- esta subquery. no es muy eficiente, pero tampoco es que tenga prisa...
   and (
          IPadre.[index]*100 + I.[index] in
          (
            select IPadre2.[index] * 100 + I2.[index]
              from METADATA_ITEMS I2
                 inner join LIBRARY_SECTIONS L2       
                    on I2.library_section_id = L2.id
                 left outer join METADATA_ITEMS IPadre2
                    on I2.parent_id = IPadre2.id
                 left outer join METADATA_ITEMS IAbuelo2
                    on IPadre2.parent_id = IAbuelo2.id
              where IAbuelo.id = IAbuelo2.id

                and ( S2.view_count = 0 or S2.view_count is null)
              order by 1
              limit 3            
          )
          or

          --
          -- las peliculas no tienen abuelo
          IAbuelo.id is null
       ) 


Esta query devuelve una lista con las rutas de los ficheros que me interesa tener copiados en, digamos, un pen drive que me llevo por ahí. Sólo falta automatizar la copia:

Metemos la query en un fichero (query.sql) al que le metemos, al principio, estas dos líneas adicionales:

.headers OFF
.output ficheros.txt


y, al final, esta:

.quit

para que cuando ejecutemos la query el sqlite3 no nos devuelva el nombre de la columna y para que el resultado lo guarde en un ficherito llamado "ficheros.txt".

Finalmente, un pequeño script, y listo:

# query para obtener los ficheros ondeck
#   - la query esta en query.sql
#   - deja los resultados en "ficheros.txt"

# ruta de la b.d. de Plex Media Server
RUTABD="/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db"
# ejecucion de la query en sqlite
cat query.sql | sqlite3 "$RUTABD"

# copiamos los ficheros al disco usb, asegurandonos de modificar fecha
while read unfichero; do
  sinextension=${unfichero%.*}
  # echo $sinextension
  nombrefichero=$(basename "$unfichero")
  # echo $nombrefichero
  cp -u "$sinextension".* /media/usb0/series
  touch "/media/usb0/series/${nombrefichero%.*}".*
done < "ficheros.txt"


# borramos ficheros viejos
find /media/usb0/series/* -mtime +1 -exec rm {} \;