RSS Reader / Downloader em um NAS

0

Primeiro, não sou um profissional de NAS e não sou um profissional de Unix. Em segundo lugar, eu li a pergunta do outro RSS-downloader , mas rsstail é uma fonte C e tvrss é uma GUI-program. Eu também verifiquei o NetVibes , mas não consigo classificar por título.

Eu comprei um Zyxel NSA310 e pensei que seria uma boa idéia ter um leitor / downloader de RSS nele. Há um broadcatcher nele, mas ele não armazena os itens RSS e eu não preciso dessa lógica adicional onde os downloads são iniciados com base nos itens RSS.

Ele deve baixar os feeds RSS e armazenar o conteúdo em arquivos legíveis. Quando chego em casa de uma viagem, quero ver todos os itens RSS desses feeds e não apenas os últimos 30 ou algo assim. Como eu uso o PuTTY para conectar ao meu NAS, não posso usar nenhum programa GUI. No que diz respeito à saída, não sei o que procurar, mas o texto simples seria suficiente. Para mim, faz sentido classificar os itens RSS por título e por data.

Para que você saiba o que está no NAS:

root@NAS:~# uname -a
Linux NAS 2.6.31.8 #4 Fri Jul 20 18:10:42 CST 2012 armv5tel GNU/Linux
root@NAS:~# busybox
BusyBox v1.17.2 (2012-07-20 17:55:00 CST) multi-call binary.
Copyright (C) 1998-2009 Erik Andersen, Rob Landley, Denys Vlasenko
and others. Licensed under GPLv2.
See source distribution for full notice.

Usage: busybox [function] [arguments]...
   or: function [arguments]...

        BusyBox is a multi-call binary that combines many common Unix
        utilities into a single executable.  Most people will create a
        link to busybox for each function they wish to use and BusyBox
        will act like whatever it was invoked as.

Currently defined functions:
        [, [[, acpid, addgroup, adduser, adjtimex, arp, ash, awk, basename,
        beep, bzip2, cat, catv, chat, chgrp, chmod, chown, chroot, chrt, chvt,
        cksum, clear, cmp, cp, crond, crontab, cryptpw, cttyhack, cut, date,
        dd, deallocvt, delgroup, deluser, depmod, devmem, df, diff, dirname,
        dmesg, dnsdomainname, du, echo, ed, egrep, eject, env, expand, expr,
        false, fgrep, flock, free, freeramdisk, fsck, fsync, getopt, getty,
        grep, gunzip, gzip, halt, head, hexdump, hostname, hwclock, id,
        ifconfig, init, insmod, install, ionice, ip, ipaddr, ipcrm, ipcs,
        iplink, iproute, iprule, kill, killall, less, linuxrc, ln, logger,
        login, losetup, ls, lsmod, lspci, lsusb, lzop, lzopcat, man, microcom,
        mkdir, mke2fs, mkfs.ext2, mknod, mkpasswd, mkswap, mktemp, modinfo,
        modprobe, more, mountpoint, mv, netstat, nslookup, openvt, passwd,
        pidof, ping, ping6, pivot_root, poweroff, printenv, printf, ps, pwd,
        raidautorun, rdev, readahead, readlink, reboot, reset, resize, rev, rm,
        rmdir, rmmod, route, rtcwake, script, scriptreplay, sed, seq, setfont,
        setlogcons, setsid, sh, sha256sum, sha512sum, showkey, sleep, sort,
        split, start-stop-daemon, strings, su, swapoff, swapon, sync, tac,
        tail, tar, tee, telnet, telnetd, test, time, timeout, top, touch, tr,
        traceroute, traceroute6, true, tty, ttysize, ubiattach, ubidetach,
        udhcpc, udpsvd, uname, unexpand, uniq, unlzop, unxz, unzip, uptime,
        usleep, vi, volname, wall, wc, which, who, whoami, xargs, xz, xzcat,
        yes, zcat, zcip

Não tenho cc/gcc ou make . Eu não consigo encontrar um instalador de pacotes também.

O Google encontrou coisas para mim codificadas em Python usando feedreader , mas elas exigem distutils , o que eu não tenho e não consigo instalar isso.

A única solução em que consigo pensar agora é usar wget em conexão com crontab . No entanto, eu teria que fazer toda a análise e tudo em shell script (desde que eu não sei Python ou Perl). Isso parece inconveniente.

O que posso fazer / experimentar? Qualquer ajuda é apreciada.

    
por sjngm 22.03.2013 / 22:17

1 resposta

1

Aqui está o que parece funcionar para mim. Eu tive isso correndo com crontab por um tempo e funciona para mim. Suporta RSS e Atom, eu acho. No entanto, se você pretende usá-lo, considere-o um ponto de partida. Se você adaptá-lo e a mudança for útil, sinta-se à vontade para voltar e contar à comunidade.

O resultado é uma estrutura de diretório com o nome do feed sendo o nome do diretório e as várias entradas gravadas como arquivos. Esses arquivos contêm o conteúdo inalterado e, na parte inferior, um link para a fonte. Os nomes de arquivos consistem no título do item e seu registro de data e hora, a data do arquivo é configurada para esse registro de data e hora. Dessa forma, você pode classificá-los por nome ou hora facilmente.

rss-parser.awk :

function removeFirstTag(str) {
    sub("[^>]*>", "", str)
    return str
}
function extractCdata(str) {
    gsub(".*<!\[CDATA\[|]]>.*", "", str)
    return str
}
function cleanup(str) {
    return extractCdata(removeFirstTag(str))
}

BEGIN {
    written = 0
    existed = 0
    if (feedTitle) {
        system("mkdir -p '" outDir "/" feedTitle "'")
    }
}

/<\/description>|<\/content>/ {
    indescr = 0
}
/<\/summary>/ {
    insummary = 0
}
/<\/item>|<\/entry>/ {
    gsub(/\//, "-", title)
    fname = outDir "/" feedTitle "/" title " - " dateSec
    fnameEnc = fname
    gsub(/\$/, "\$", fnameEnc)
    gsub(/"/, "\\"", fnameEnc)
    if (!description) {
        description = summary
    }
    if (link != "") {
        description = description "\nLink: " link
    } else if (guid != "") {
        description = description "\nLink: " guid
    }

    write = system(binPath "/stat \"" fnameEnc "\" -c \"%u\" 1> /dev/null 2>&1")
    if (write == 1) {
        print description > fname
        system(binPath "/touch \"" fnameEnc "\" -d \"" date "\"")
        written = written + 1
    } else {
        existed = existed + 1
    }
}

{
    if (indescr == 1) {
        description = description "\n" $0
    }
}

/<title[ >]/ {
    if (!feedTitle) {
        feedTitle = cleanup($0)
        system("mkdir -p '" outDir "/" feedTitle "'")
    } else {
        title = cleanup($0)
    }
}
/<item[ >]|<entry[ >]/ {
    title = ""
    description = ""
    summary = ""
    date = ""
    link = ""
    guid = ""
}
/<description[ >]|<content[ >]/ {
    indescr = 1
    description = cleanup($0)
}
/<summary[ >]/ {
    insummary = 1
    summary = cleanup($0)
}
/<link[ >]/ {
    link = cleanup($0)
    if (index(link, "magnet") == 1) {
        link = ""
    }
}
/<guid[ >]|<id[ >]/ {
    guid = cleanup($0)
}
/<pubDate[ >]|<published[ >]|<dc:date[ >]/ {
    date = cleanup($0)
    binPath "/date -d '" date "' +'%s'" | getline dateSec
}

END {
    print "Done : " feedTitle " (new: " written "/old: " existed ")"
    if (existed == 0 && written != 0) {
        print "=== NOTE === : All entries are new. You may want to check this feed more often"
    }
}

O arquivo rss-parser.cfg consiste em linhas como

http://thatonesite.com/feed-with-nice-title
http://thatothersite.com/feed=Specific feed title is better

rss-parser.sh :

#!/bin/sh

parse() {
    url="$1"
    name="$2"
    echo "Start: $name ($url)"
    wget -q -U "$userAgent" -O rss-news.xml $url
    sed -e 's/
//g' -e 's/<\([a-z/]\)/\n</g' rss-news.xml | \
        $binPath/awk \
            -v "feedTitle=$name" \
            -v "binPath=$binPath" \
            -v "outDir=./data" \
            -f rss-parser.awk | \
        more
}

userAgent="Opera/9.80 (Windows NT 6.1; Win64; x64; U; de) Presto/2.10.289 Version/12.01"
binPath=/bin
cd 'dirname $0'
if [ -z "$1" ]; then
    echo "================= '$binPath/date +"%d.%m.%Y %H:%M"'"
    start='$binPath/date +%s'
    while read line
    do
        if [ ! -z "$line" -a "${line:0:1}" != "#" ]; then
            url=${line%%=*}
            name=${line#*=}
            if [ "$name" == "$url" ]; then
                name=""
            fi
            parse "$url" "$name"
        fi
    done < "rss-parser.cfg"
    echo "================= Took '$binPath/date -d "$start seconds ago" +%s' seconds"
else
    parse "$1" "$2"
fi

Sem parâmetros, analisa rss-parser.cfg . Caso contrário, os parâmetros são

./rss-parser.sh [<URL> [<feed name>]]

Espero que seja útil para alguém ...

    
por 14.04.2013 / 19:31

Tags