Roligt med mail, at och cron

I en kommande serie i åtminstone åtta delar har jag tänkt beskriva hur min eposthantering ser ut. Det dröjer dock litet. Visserligen vore det en lika hastig som smal sak att bara rapa upp programnamn och konfigurationsfiler, men det vore att ha för låga ambitioner. I stället siktar jag på något den fantastiske författaren Michael W. Lucas skrivit om:

One of the old cliches about writing is that you should “write what you know.” In tech writing this is not only wrong, but actively harmful. … Instead, I recommend writing about something you want to know about.

Det är därför det tar litet tid. Tomrummet som uppstår i väntan på de där inläggen går dock att fylla med små finurligheter som inte egentligen uppfyller några sådana krav. Här kommer ett par av det slaget.

Om du har sendmail eller motsvarande i ordning på din maskin så kan du skicka epost med programmet mail.

Till exempel så här:

$ mail jesper
Subject: Lokalpost
Any fool can paint a picture, but it takes a wise person to be able to
sell it.
EOT

EOT var resultatet av att jag tryckte ^D (vilket betyder CTRL-D). Det här mejlet levereras omedelbart till den lokala användaren jesper, vilket ju är jag själv. Det går förstås även att skicka till en riktig epostadress:

$ mail jesper@example.org
Subject: Globalpost
Pig, n.:
        An animal (Porcus omnivorous) closely allied to the human race
        by the splendor and vivacity of its appetite, which, however, is
        inferior in scope, for it balks at pig.
                -- Ambrose Bierce, "The Devil's Dictionary"
EOT

Men med min konfiguration levereras aldrig det senare mejlet!

En del av förklaringen till detta är att sendmail på min maskin använder en "SMART_HOST", alltså en extern STMP-server som relay, och den servern accepterar inte de här epost-meddelandenas avsändaradress.

Om inget annat anges, så får epost skickade med mail nämligen avsändaren användare@maskin, till exempel "jesper@kaja.mydomain", och relay-servern förkastar mejl från sådana ogiltiga avsändare.

Detta är dock lätt att lösa. Om man matar mail med flaggor efter mottagaradressen, så skickas de vidare till sendmail i stället för att tolkas av mail. För att skicka ett mejl till jesper@example.org med en bestämd avsändaradress gör jag alltså så här:

$ mail jesper@example.org -f fortune@example.org
Subject: Fortune
Top scientists agree that with the present rate of consumption, the
earth's supply of gravity will be exhausted before the 24th century.
As man struggles to discover cheaper alternatives, we need your help.
Please...

                        CONSERVE GRAVITY

Follow these simple suggestions:

(1)  Walk with a light step.  Carry helium balloons if possible.
(2)  Use tape, magnets, or glue instead of paperweights.
(3)  Give up skiing and skydiving for more horizontal sports like
     curling.
(4)  Avoid showers ... take baths instead.
(5)  Don't hang all your clothes in the closet ... Keep them in one big
     pile.
(6)  Stop flipping pancakes
EOT

Förutsatt att avsändaradressen fortune@example.org är giltig kommer det här mejlet levereras.

Och nu börjar det roliga, eller rättare: Nu gör vi oss av med det tråkiga.

Först och främst är jag trött på att varje gång jag vill skicka mejl som de här behöva köra fortune, kopiera och till sist klistra in det i mina mejl. Samma resultat går ju att uppnå på det här viset:

$ fortune -a | mail -s "Kakan säger" jesper@example.org -f fortune@example.org

Observera hur flaggan -s, som bestämmer Subject, ligger före mottagaradressen och därmed tolkas av mail i stället för att skickas vidare till sendmail.

Nästa grej jag är trött på är att skicka de här mejlen manuellt, för att sedan få dem levererade några sekunder senare. Därför skickar jag dem i stället med hjälp av programmet at, vars poäng helt enkelt är att köra ett eller flera kommandon vid en annan tidpunkt än omedelbart:

$ at 07:45
fortune -a | mail -s "Kakan säger" jesper@example.org -f fortune@example.org
^D

Med detta schemaläggs skickandet till klockan kvart i åtta på morgonen, nästa gång hon är så mycket. at förstår även mer avancerade tidsangivelser, exempelvis teatime september 7 som inträffar kl. 16.00 nästkommande 7/9. (Ett tråkigare sätt att uttrycka samma tidpunkt är annars 201209071600).

Men så här roligt vill jag inte bara ha någon gång ibland och på eget initiativ, utan varje dag. Att mejla en fortune till sig själv passar mycket bättre i cron, som finns till för att köra kommandon vid upprepade tillfällen.

Det finns massor av sätt att konfigurera körningar i cron, som något visst datum varje månad, en viss minut varannan timme, varje söndag och så vidare. Jag är dock bara intresserad av klockslaget kvart i åtta varje morgon. För att fixa detta gör jag crontab -e och pular in den här raden:

Att 45 är en minut och 7 en timme är lätt att inse. De tre asteriskerna i sin tur, står i tur och ordning för datum, månad och veckodag.

Det går även att mata in kommaterade listor eller spännvidder. Här är en variant som skickar det där mejlet varje vardagsmorgon klockan kvart i åtta, förutom i juli:

Visserligen är det svårt att tänka sig något roligare innehåll för automatiska mejl än fortune, men det är nog bäst om jag täcker något praktiskt användningsområde också.

urlwatch.sh

För det här avsnittet var jag först inne på att jag skulle reproducera Richard Stallmans oerhört praktiska webbläsare, men kom som tur var på bättre tankar.

Det blir dock något liknande, nämligen en webbövervakningstjänst. För att åstadkomma denna tar jag hjälp av ett gammalt skript som nyligen fick sig en omgång och kom online: urlwatch.sh.

Med en default-konfiguration läser urlwatch.sh in ett godtyckligt antal whitespace-separerade url:er ur filen ~/.urlwatch/urls, drar ned dem med curl, tolkar om dem till plaintext med lynx och sparar resultatet i en cache. Andra gången skriptet körs hämtar det samma sidor igen, skriver ut en diff mellan den föregående och nuvarande versionen av sidorna och uppdaterar sedan cache-kopian.

Det här skriptet vill jag köra från cron ett par gånger om dagen, bland annat för att få en ping via epost när SVT Play slänger upp nya program på vissa adresser, exempelvis http://www.svtplay.se/agenda. De övergav ju RSS när de bytte till ny sajt i somras.

För att åstadkomma detta installerar jag först skriptet:

$ curl -o bin/urlwatch.sh \
https://raw.github.com/simio/scripts/4f1d265852529fab701f1ce817a15611839047a8/urlwatch.sh
$ mkdir ~/.urlwatch
$ echo "http://www.svtplay.se/agenda" > ~/.urlwatch/urls

(Byt hashen i adressen till master för att hämta den senaste versionen.)

Sedan lägger jag till det i min crontab (med crontab -e, igen):

Observera att det där inte ska vara flera rader, utan bara en. När den här crontabben är sparad kommer skriptet köras klockan 06.00, 12.00 och 18.00 varje dag, och utmatningen mejlas till jesper@example.org vare sig den är tom eller inte.

Flaggan -f till urlwatch.sh gör att skriptet rapporterar diffar i ett format som passar bättre i mejl.

Mejlprogram som försöker vara listiga kan förresten sabba det här genom att sortera bort epost med samma avsändare som mottagare. GMail är en sådan skurk. Du behöver i så fall ange en annan avsändaradress.

Det är dock inte som ovan jag egentligen använder skriptet i min crontab. Eftersom jag använder min lokala mailspool ser jag för det första till att rapporterna aldrig lämnar datorn, genom att skicka dem till mitt användarnamn i stället för min epostadress.

Sedan vill jag inte heller ha rapporter när ingenting hänt, vilket blir resultatet om man använder skriptet som ovan. I stället låter jag skriptet själv sköta mejlandet. Som en bonus blir allting därmed mycket mindre komplicerat i crontabben.:

Timangivelsen */2 betyder varannan timme.

Flaggan -m säger åt urlwatch.sh att skicka rapporten som epost i stället. Mottagare kan bestämmas med flaggan -r, men eftersom defaultvärdet är den användare som kör skriptet behöver jag inte använda den.

Default-värdet för avsändaradress är daemon@localhost, men vill du ändra det så ska du lägga till den här raden i filen ~/.urlwatch/config:

Nu är det slut på det roliga.

Halvt förolyckad domänflytt

Under augusti bytte Huggpunkt.org både domänregistrar och webbhotell till Binero, från att tidigare ha haft skilda företag som registrar och webbhotell. Under tiden som flytten pågick var forumen stängda för registrering och publicering.

Tyvärr drog processen alldeles för länge ut på tiden. Detta berodde delvis på ordningen som flytten genomfördes i:

  1. Sätt i gång registrarbytet.
  2. Frys diskussionsforumen, genom att stänga av kontoregistrering och publicering/redigering av inlägg.
  3. Kopiera filer och databas för forumen till det nya webbhotellet.
  4. Lås upp diskussionsforumen på det nya webbhotellet (men låt dem fortsätta vara låsta på det gamla).
  5. Vänta tills bytet av registrar är genomfört.
  6. Sätt i gång ompekning av domänen.
  7. Vänta ett par dygn eller så, tills ompekningen propagerats över internet.
  8. Klar.

Om allt hade gått smidigt, så hade nertiden bara varat i något fåtal dygn. Nu blev det i stället frågan om ett par veckor. Problemet var att Bineros kontrollpanel inte upptäckte att domänöverföringen genomförts. Därför gick inte ompekningen att sätta i gång från vare sig den gamla eller den nya registraren, och alla besökare hamnade på det gamla webbhotellet, där forumen stängts.

När teknisk support färdigställt överföringen manuellt, gick det som grädde på moset inte heller att byta namnservrar för domännamnet. Ytterligare ett manuellt ingrepp krävdes med andra ord. När jag skriver detta är bytet av namnservrar dock i full rullning, vilket inte minst märks på att man kastas fram och tillbaka mellan de olika hotellen. Kaoset beräknas fortgå till senast lördag.

Lärdom? Jo visst, ompekningen borde till fullo ha genomförts före (eller förstås efter) bytet av registrar, i stället för samtidigt. Med andra ord borde steg (1) och (5) ha hänt sist, mellan (7) och (8).

Ladda hem från SR

Det går att ladda hem samtliga Sveriges Radios program, inte bara dem som finns i poddformat. I det här inlägget ska jag berätta hur man gör för att hämta de litet klurigare m4a-filerna, samt hur man tankar hem rtmp-strömmar. I ett påföljande inlägg kommer jag att presentera en uppdatering av mitt gamla radioskript, sedan SR gjort om sin sajt en smula.

Jag kommer att demonstrera tre metoder som går att använda när man vill ladda hem ett klipp, ett program eller spela in en stump från den direktsända webbradion.

Ladda hem med en webbläsare

Den här metoden fungerar för många klipp. De enklaste klippen att ladda hem är dem som är märkta med (MP3). Allt du behöver göra är att högerklicka och spara.

Klipplänk 1

Om det inte är ett sådant MP3-klipp du ska hämta hem, så behöver du göra litet mera än bara klicka. Börja med att högerklicka på klippets länk, som kan se ut på ett par olika sätt:

Klipplänk 2 Klipplänk 3

Ladda hem filen och öppna den i en text-editor. Leta sedan upp -avsnittet i filen:

Det är rad 4 du är intresserad av. Där har du nämligen adressen till ljudfilen. Mata in den i webbläsaren, så hämtas den hem.

Kanske fungerar det inte. Får du istället fram en irriterande mediaspelare inuti webbläsarfönstret á la QuickTime, så måste du vara litet lurig. Skapa i sådana fall ett html-dokument på exempelvis ditt skrivbord, och fyll det med följande innehåll:

Öppna filen i din webbläsare, högerklicka på länken och välj att ladda hem den.

Med cURL istället för webbläsare

Människor som begåvats med att använda cURL kan göra så här istället:

$ curl -LO http://sverigesradio.se/topsy/ljudfil/2888490.m4a

Fast med cURL och ett vettigt skal behöver man inte ladda hem någon fil och öppna den i texteditor. Rabbla istället upp den här ramsan:

URL ska givetvis ersättas med adressen till filen som innehåller adressen till ljudfilen. Citattecknen är viktiga.

Ladda hem i MPlayer

Den här metoden bygger på att det går att spela upp filer direkt från webben i MPlayer.

Till att börja med ska du göra likadant som om du laddat hem med din webbläsare: Högerklicka på länken. Ladda dock inte hem länken, utan kopiera den.

Om du bara vill spela upp klippet i MPlayer, så gör du så här:

$ mplayer -playlist "http://sverigesradio.se/api/radio/radio.aspx?type=broadcast&id=2886735&codingformat=.m4a&metafile=asx"

För att spara klippet till hårddisken använder du följande formel:

$ mplayer -dumpstream -dumpfile "Sparat radioprogram".m4a -playlist "http://sverigesradio.se/api/radio/radio.aspx?type=broadcast&id=2886735&codingformat=.m4a&metafile=asx"

En nackdel med detta är att det tar lika lång tid att ladda hem programmet som att lyssna på det. I normalfallet finns inte heller någon fördel – det är helt enkelt bättre att använda föregående metod.

Men när det gäller SR:s äldre klipp och program, som ofta bara finns som rtsp-strömmar, så är det här ett trevligt sätt att hämta hem programmen på.

Spara ljudströmmar med RTMPDump

Den här metoden fungerar för alla rtmp-strömmar, oavsett vad de innehåller. Det finns två sätt att komma åt rtmp-adresser. Det ena är att råka ha dem i en fil sedan tidigare, som jag. :-)

Du behöver förstås installera RTMPDump. (FLVstreamer fungerar taskigt med SR:s strömmar, är min erfarenhet.) Närmare instruktioner för att installera i Windows finns i det här inlägget.

Det andra sättet är att man hittar dem någonstans. Uppenbarligen kommer de numera även som nedladdningsbara .rtmp-filer. Om du inte har någon adress som börjar med rtmp://, utan en http://-adress till en .rtmp-fil, så ladda hem filen och öppna den i en text-editor.

Även den här gången söker du det här avsnittet i filen:

Och även i det här exemplet är det den fjärde raden du är intresserad av.

I det här exemplet råkar rtmp-adressen vara P2:s direktsändning:

rtmp://rtmp-live.sr.se/webbradio/kanaler/p2musik-aac-96

Du kan fuska fram en sändning av högre kvalitet genom att ändra siffran på slutet:

rtmp://rtmp-live.sr.se/webbradio/kanaler/p2musik-aac-192

Eftersom detta är en direktsändning, så fungerar RTMPDump snarare som en inspelningsapparat än ett nedladdningsprogram. Det betyder vad du tror att det betyder: När du startar programmet så börjar det spela in, och när du avslutar det (med CTRL-C) så slutar du spela in.

Nåväl, här är kommandot:

$ rtmpdump -o "Min radioinspelning".m4a -r "rtmp://rtmp-live.sr.se/webbradio/kanaler/p2musik-aac-192" -v

Hade detta inte varit en direktsändning, så skulle det inte ha varit något -v på slutet. Då hade du inte heller behövt avsluta RTMPDump manuellt, eftersom det hade slutat när filen tog slut.

Vill du lyssna på ett program samtidigt som du hämtar hem det – även om det är en direktsändning du spelar in från – så kan du göra så här:

$ mplayer -nocache "Min radioinspelning".m4a

Det var allt. Adjö!

Sveriges Radio från terminalen

Uppdatering 5 februari 2011. Instruktioner för att ladda ned klipp och program, samt spela in till fil från den direktsända webbradion, finns i det här inlägget. Eftersom Sveriges Radio gjort en del förändringar av sin sajt sedan det här inlägget skrevs, så behöver även skriptet uppdateras. Jag återkommer i frågan.

* * *

Det är på tiden att jag delar med mig av mitt fantastiska lilla skalskript för Sveriges Radios webbradio.

SR har två olika typer av webbradio, vid sidan av sina poddradio-arkiv. Dels en liveström, och dels arkiverade klipp.

För att köra skripten behöver du rtmpdump eller flvstreamer, och så förstås en mediaspelare. Jag använder MPlayer.

För att lyssna på live-radion behöver du två filer – själva skriptet och en fil med direktadresser till strömmarna. Filen med adresser ska heta radio.dat och ligga i samma mapp som scriptet. Den ser ut så här:

rtmp://rtmp-live.sr.se/webbradio/kanaler/p1-aac-192
rtmp://rtmp-live.sr.se/webbradio/kanaler/p2-aac-192
rtmp://rtmp-live.sr.se/webbradio/kanaler/p2musik-aac-192
rtmp://rtmp-live.sr.se/webbradio/kanaler/p3-aac-192
rtmp://rtmp-live.sr.se/webbradio/kanaler/p4skaraborg-aac-192
rtmp://rtmp-live.sr.se/webbradio/kanaler/p4orebro-aac-192

Som du ser så finns det flera möjliga adresser till P4, eftersom de har lokala sändningar.

Skriptet ser i sin tur ut så här:

Döp skriptfilen till radio och se till att den är körbar. Nu kan du köra en radiokanal så här:

$ radio p3

Om du istället skulle välja att köra kanalen p4 så skulle den första adressen som innehåller p4 att köras, så för att köra P4 Örebro, som är den andra P4-kanalen i adressfilen, är jag tvungen att göra så här:

$ radio p4orebro

Vidare så går det att spela radio »i bakgrunden«, frikopplat från terminalen. Det är oerhört smidigt om man har datorn påslagen nattetid och vill bli väckt av den. Du kan ställa väckarklockan på 09.30 så här:

$ echo "radio -bg p2" | at 09:30

Men för att smidigt kunna stänga av uppspelningen behöver du ett skript till! Det heter radiotystnad och är litet och simpelt:

Det var allt om live-radio. Att spela upp radioklipp är en helt annan historia. Dessutom är den mera intressant.

Uppdatering 9 dec 2010: OBS! Det följande fungerar inte längre, i och med en ändring som SR gjort på sin sajt. Finurligt nog har de genomfört en förenkling, vilket gör dem ovanliga och fantastiska i världen. :-)

En snabbfix finns i min kommentar nummer 2 nedan, och en mera ingående uppdatering kommer i ett eget blogginlägg så småningom.

Det här skriptet är finurligt, tycker jag åtminstone själv. Döp filen till vad du känner för; själv kallar jag det för webbradio.

Observera att där var en mycket lång rad mitt i alltsamman, som blivit radbruten här i bloggen.

Gör skriptet körbart. Sedan kan du helt enkelt kopiera adressen till webbradioklippet, genom att högerklicka på den här knappen och välja Kopiera länk:

Exempel 1

Den kan också se ut så här:

Exempel 2

När du kopierat länken, så kör du den genom skriptet.

$ webbradio "LÄNK"

Citattecknen är oerhört viktiga. Skulle du få för dig att vilja spara klippet till hårddisken, så kör du istället skriptet så här:

$ webbradio -record "LÄNK"

Filen kommer att sparas med ett filnamn enligt följande format:

SR_[id-nummer]-[datum]-[klockslag].flv

Om du skulle använda en annan mediaspelare än MPlayer, så kan du antagligen ersätta de följande två raderna…

…med de här:

Några frågor?

Ladda hem från Youtube

Tidigare har jag berättat hur man kan ladda hem från SVTPlay, och nu är det dags för Youtube. Jag tänker även berätta hur du kan göra för att konvertera en video till en ljudfil, genom att helt sonika lyfta över det i en egen fil.

Precis som tidigare, så är anledningen till att jag själv gör så här att jag kör ett 64-bitars OpenBSD, och då går det inte att använda Flash. Youtube kommer framöver att gå över till HTML5, och då slipper jag det här krånglet. Du kan pröva deras testversion detta här.

Det absolut enklaste sättet att tanka hem Youtube-videor är att använda sajten KeepVid.com. Det gör du så här:

  1. Gå till videon på Youtube.
  2. Kopiera adressen ur adressfältet.
  3. Klistra in adressen på KeepVid.com och klicka på Download-knappen.
  4. Högerklicka på länken som visas och välj Spara som…

Men detta fungerar inte felfritt! Dessutom är det skönt att kunna genomföra samma grej från ett terminalfönster eller i ett script, åtminstone för mig. Nu kommer jag först att berätta hur du laddar hem en video på det viset, och sedan hur man kan göra för att automatisera litet grand.

Ladda hem videon

Du behöver programmet youtube-dl, som i själva verket är ett Python-script. Se alltså till att ha Python installerat.

Windowsbrukare kan också använda det, och lätt övermäktiga instruktioner för hur scriptet kan installeras finns här.

På *nix-system måste youtube-dl.py dessutom vara körbar. Eftersom det är bra att hålla ordning på sin hemkatalog, så lägger vi scriptet i mappen ~/bin.

$ chmod +x youtube-dl.py
$ mkdir ~/bin
$ mv youtube-dl.py ~/bin/

Nu kollar vi att den går att köra:

$ youtube-dl.py
ksh: youtube-dl.py: not found

Hoppsan! Händer detta mumlar du följande trollformel, så är problemet omedelbart löst på obestämd tid.

$ echo 'export PATH=$PATH:$HOME/bin' >> .profile; export PATH=$PATH:$HOME/bin

Du kan även få permission denied när du kör filen. Lösningen är att köra scriptet så här istället:

$ python ~/bin/youtube-dl.py

Resten är lätt. Surfa till Youtube-sidan med videon, kopiera adressen, och kör scriptet med den enligt följande:

$ youtube-dl.py -bt "http://www.youtube.com/watch?v=yek2D4Kjwgc"

Glöm inte citat-tecknen! Eller snarare: Om du inte vet när de egentligen behövs, så använd dem alltid. (Just här behövs de egentligen inte.)

Youtube på volley

Har man inte Flash kan man inte se videon i webbläsaren. Om man bara vill slå en flukt på videon men inte tanka hem den, är det omständigt att behöva ladda hem den först.

Då kan man använda sig av samma lösning för nedladdning som ovan, men fånga videon »i luften« och spela upp den direkt istället! Så här skapar du ett script som fixar biffen:

Ersätt "mplayer" med kommandot för den mediaspelare du föredrar.

Nu kan du spela upp videor direkt, busenkelt:

$ youtube.sh http://www.youtube.com/watch?v=yek2D4Kjwgc

Scriptet kan spela upp flera videor på rad om du klistrar in adresserna efter varandra.

Hur du plockar loss ljudet

Först och främst ska du se till att du har FFmpeg installerat.

Sedan måste du bestämma om du vill ha en mp3-fil eller en m4a-fil. Vill du ha ljudet i mp3-format, börja med att tanka hem videon så här:

$ youtube-dl.py -o dummy.flv http://www.youtube.com/watch?v=yek2D4Kjwgc

När nedladdningen är färdig så plockar du loss ljudspåret enligt det följande:

$ ffmpeg -vn -acodec copy -i dummy.flv ljudfil.mp3

Strax har du en fil som heter ljudfil.mp3.

Vill du istället ha ljudet i m4a-format, får du ändra parametrarna något.

$ youtube-dl.py -bo dummy.mp4 http://www.youtube.com/watch?v=yek2D4Kjwgc
$ ffmpeg -vn -acodec copy -i dummy.mp4 ljudfil.m4a

Och det var faktiskt det hela.