poniedziałek, 17 czerwca 2013

Twitch.tv bez Adobe Flash

Czyli jak oglądać stream w ulubionym odtwarzaczu wideo.

Aktualne problemy z flash'em pod Linuxem:

  • nowe wersje pluginu Adobe mają wsparcie tylko dla Chrome Pepper - więc dla pozostałych przeglądarek zostają tylko starsze wersje plugina
  • zamknięte źródło ™
  • czasami nie można wyjść z trybu fullscreen
  • czasami wiesza się zajmując 100% czasu procesora
  • czasami po prostu się wywala

Istnieje jakaś alternatywa - shumway ale aktualnie nie wspiera takich rzeczy jak YouTube więc zapewne też Twitch. Dodatkowo SWFObject stwierdza że flash nie jest w ogóle obsługiwany więc zazwyczaj zobaczymy tylko "zainstaluj Adobe Flash".

Pobieranie

Listowanie plików flv dla zadanego linka z archiwum, archive.py:

#!/usr/bin/python3

from urllib.request import urlopen
import json, sys, re

decoder = json.decoder.JSONDecoder()

for arg in sys.argv[1:]:
 m = re.match(r"^.*/([^/]+)/b/([0-9]+)$", arg)
 video_id = int(m.group(2))
 with urlopen("http://api.justin.tv/api/broadcast/by_archive/%d.json" % video_id) as f:
  resp = decoder.decode(f.read().decode())
  for i in resp:
   print(i["video_file_url"])

Przykład użycia:

$ ./archive.py http://www.twitch.tv/some_channel/b/4173086
http://store30.media30.justin.tv/archives/2013-6-15/live_user_some_channel_13713088.flv
http://store38.media38.justin.tv/archives/2013-6-15/live_user_some_channel_13713106.flv
http://store6.media6.justin.tv/archives/2013-6-15/live_user_some_channel_13713124.flv

Pozostaje jeszcze tylko pobrać wypisane pliki.

Oglądanie

Potrzebne nam są livestreamer i rtmpdump. Żeby nie zaśmiecać systemu użyłem python'owego virtualenv. Poniższe kroki zakładają że rtmpdump nie jest zainstalowany w systemie.

Więc:

cd /path/to/project
git clone git://git.ffmpeg.org/rtmpdump
virtualenv env
make -C rtmpdump/
source env/bin/activate
pip install livestreamer

Następnie warto złożyć wszystko w jeden skrypt:

#!/bin/bash

d="$(dirname $0)"

source "${d}"/l/bin/activate
LD_LIBRARY_PATH="${d}"/rtmpdump/librtmp/ livestreamer -p /path/to/player -r "${d}"/rtmpdump/rtmpdump "${@}"

... i zaczynamy oglądać:

./run.sh http://www.twitch.tv/dreamhacksc2 720p

możemy także zapisywać stream do pliku:

./run.sh http://www.twitch.tv/dreamhacksc2 720p -o file.flv

czwartek, 13 czerwca 2013

Eclipse: The Dark IDE - Linux edition

Chwilę temu stumblnąłem na http://ethanschoonover.com/solarized. Jest to dość magiczny zestaw jasnych i ciemnych motywów do dużej ilości edytorów/widget'ów itp... i dodatkowo wygląda dość ładnie. Zastanawiałem się przez chwilę czy aby na pewno kolor tła i zwykłego tekstu nie będzie się zlewał ze sobą - ale przecież na stronie zostało napisane że kolory są zgodne ze specyfikacją CIELAB oraz rozwiązanie było testowane na wielu maszynach. Więc musi być prawdą! ;)

Jako że spędzam dość dużo czasu przed Eclipse'm postanowiłem skorzystać z rady wujka Google - ciemniejsze kolory mogą mniej męczyć oczy (zapewne zwłaszcza gdy programuje się w nocy). Poniżej przedstawiam kroki jak całkowicie ostylować Eclips'a ciemniejszym motywem (Linux edition).

Na zachętę - efekt końcowy

Eclipse

Na starcie dostajemy:

By załadować powyższe motywy w Eclips'ie wymagane są rozszerzenia Eclipse Color Themes oraz Chrome Theme.

Po aplikacji nowego wystroju (motyw dla Aptany oraz samego Eclipse) okazało się że motyw Aptany jest nieco ciemniejszy więc zmieniłem w kilku miejscach kolory na odpowiednie z podstawowego schematu (pobierz zmieniony motyw).
Następnym krokiem jest zmiana kolorów zakładek i innych elementów Eclipse, posłuży nam do tego Chrome Theme. Tutaj można pobrać już gotowy plik konfiguracji ui - należy go umieścić w workspace/.metadata/.plugins/org.eclipse.core.runtime/.settings. W przypadku manualnych zmian należy pamiętać o dodaniu do arkusza CSS linijki z odpowiedzi na stackoverflow.com:

#org-eclipse-e4-ui-compatibility-editor * { background-color: #002b36; }

GTK

Na szczęście motyw dla GTK+ 2 jest łatwo dostępny: https://github.com/heichblatt/gtk2-theme-solarizeddark.
Nie potrzeba włączać go dla całego systemu, w naszym wypadku wystarczy dla samego Eclipse.

GTK2_RC_FILES=~/.themes/solarized.gtkrc /mnt/sandbox/eclipse/eclipse

Desktop file

Jeśli chcesz by Eclipse włączał się już z Twoim nowym motywem poprzez wpis w menu, trzeba w odpowiednim pliku .desktop zmienić linię z Exec. Poniżej cały plik używany przeze mnie:

[Desktop Entry]
Encoding=UTF-8
Name=Eclipse IDE
Comment=Eclipse Programming IDE
Exec=env GTK2_RC_FILES=~/.themes/solarized.gtkrc /mnt/sandbox/eclipse/eclipse
Icon=/mnt/sandbox/eclipse/icon.xpm
Terminal=false
Type=Application
Categories=Application;Development;

Niestety nawet po zaaplikowaniu motywów w tych wszystkich miejscach wciąż może się zdarzyć że jakiś edytor będzie wyświetlał niepoprawne barwy - jak np. edytor Twig'a z paczki Symfony2. (poprawiona konfiguracja)

środa, 30 stycznia 2013

Bugzilla + nginx

Wszystko zaczęło się od pytań - Jaki system raportowania błędów jest najlepszy? Który mi najbardziej odpowiada? Padło na Bugzillę. Rozwiązanie - wydawałoby się - idealne dla potrzeb pojedynczego developera.

Instalacja samej aplikacji przebiegła dość sprawnie. Bugzilla została napisana w Perl'u więc do systemu musiałem doinstalować masę nowych modułów Perla gdyż nigdy go w taki sposób nie używałem. Po instalacji i radości z działającej konfiguracji przy użyciu SQLite, dość szybko okazało się że jedyny tryb w jakim Bugzilla może działać na moim serwerze to CGI. We wszystkich możliwych miejscach starałem się stosować uWSGI, w tym przypadku dążyłem do uruchomienia aplikacji na PSGI. Niestety wspierane są tylko cgi i mod_perl dla Apache. Na szczęście sam Nginx jak i uWSGI umożliwiają uruchamianie skryptów jako CGI. Niestety po skonfigurowaniu ich w taki sposób okazało się ze na otwarcie strony głównej Bugzilli trzeba czekać aż 3 sekundy (serwer nie jest aż tak słaby).

Rozpoczęła się walka :)

Google szybko odpowiedziało zgłoszeniem błędu do samej Bugzilli: https://bugzilla.mozilla.org/show_bug.cgi?id=316665 (można zwrócić uwagę że dodane zostało w 2005 roku ;) ). W zgłoszeniu znajduje się patch który umożliwia uruchomienie Bugzilli w trybie FastCGI (oraz możliwe PSGI).

Ten sam patch można znaleźć na GitHub'ie: https://github.com/Stackato-Apps/bugzilla/blob/master/psgi.patch . Po nagłówku łatki można stwierdzić że napisana została na podstawie wersji 4.0.3 (aktualnie najnowszą jest 4.2.4).

Łatka nie aplikowała się poprawnie dla najnowszej wersji więc na jej podstawie stworzyłem nową . Kolejnym krokiem było dobranie opcji dla uwsgi i uruchomienie serwisu. Aplikacja wstała - wszystko wyglądało na poprawnie działające - do chwili gdy zechciałem się zalogować. W logach zauważyłem występowanie jakiegoś błędu autentykacji "brak danych" dodatkowo strona która powinna była się wyświetlić (z informacją o niepoprawnym haśle/loginie) została ucięta w pół.

Podążając nowym tropem - brakiem danych w POST'ie po stronie serwera, szczęśliwym trafem dotarłem na kolejne zgłoszenie błędu, tym razem dla CGI-Emulate-PSGI.

Okazuje się że problemem jest właśnie to - aplikacja nie otrzymuje danych z POST'a gdy używane jest uWSGI, naprawienie tego wydaje się być proste.. ale kompletnie nie znam Perl'a :) Dochodzi jeszcze dziwny błąd obcinający stronę który może ale nie musi być związany z pierwszym.

Emulacja PSGI zastosowana w łatce używa modułów Plack'a więc została jeszcze możliwość uruchomienia aplikacji bez korzystania z uWSGI - czyli na FastCGI do którego wsparcie jest dodane do Nginx'a.

Na skróty

Czyli Bugzill'a działająca na FastCGI w szybki sposób.

  • Pobieramy kod Bugzill'i
  • Aplikujemy łatkę fastcgi
  • Konfigurujemy Bugzillę poprzez checksetup.pl
  • Konfigurujemy Nginx'a i uruchamiamy serwis Plack (pliki i komendy w dziale poniżej)

W systemach Gentoo można dodać glorpen-overlay w którym znajduje się ebuild aplikujący wspominaną wcześniej łatkę.

Końcowa konfiguracja

Dla Nginx:

#pozostałość z cgi - ale dlaczego by tego nie zostawić?
location ~ ^(.*\.(jpe?g|gif|css|js|png|ico))$ {
        alias /srv/bugzilla/app/$1;
}

location  /  {
        include        fastcgi_params;
        fastcgi_param  SCRIPT_NAME      "";
        fastcgi_pass   unix:///srv/bugzilla/fastcgi.socket;
}

Uruchomienie Plack'a:

#!/bin/bash

d="/srv/bugzilla"
plackup -s FCGI -S "${d}"/fastcgi.socket "${d}"/app/app.psgi --pid "${d}"/plackup.pid -D

i na koniec wyłączenie serwera Plack:

#!/bin/bash

kill `cat /srv/bugzilla/plackup.pid`

środa, 23 stycznia 2013

Automatyczna konfiguracja Windows, cz.3

Tym razem przedstawię ustawienia rejestru które można zmienić by IE7 nie zadawało pytań przy pierwszym uruchomieniu lub pierwszych wykonaniach danej czynności.

Plik ten został przetestowany na obrazie IE VHD z Windows Vista i IE7. Dla innych systemów będzie prawdopodobnie wymagana zmiana ID użytkownika dla którego chcemy zmienić ustawienia. W poniższym przykładzie jest to S-1-5-21-4099969203-747351341-4178853743-1000.

Windows Registry Editor Version 5.00

[HKEY_USERS\S-1-5-21-4099969203-747351341-4178853743-1000\Software\Microsoft\Internet Explorer\InformationBar]
"FirstTime"=dword:00000000

[HKEY_USERS\S-1-5-21-4099969203-747351341-4178853743-1000\Software\Microsoft\Internet Explorer\IntelliForms]
"AskUser"=dword:00000000
"PSMigrated"=dword:00000001

[HKEY_USERS\S-1-5-21-4099969203-747351341-4178853743-1000\Software\Microsoft\Internet Explorer\Main]
"Do404Search"=hex:00,00,00,00
"Save_Session_History_On_Exit"="no"
"Search Page"="http://google.com"
"Start Page"="http://google.com"
"SearchMigrated"=dword:00000000
"RunOnceHasShown"=dword:00000001
"RunOnceComplete"=dword:00000001
"Use FormSuggest"="no"
"Error Dlg Displayed On Every Error"="no"
"Friendly http errors"="no"
"SmoothScroll"=dword:00000000
"AutoSearch"=dword:00000000

Po imporcie zostaną zmienione takie funkcje jak:

  • google zostanie ustawione jako strona główna i wyszukiwarka
  • wyłączone zostaną "przyjazne błędy http", czyli zobaczymy prawdziwe odpowiedzi serwera
  • import zakładek zostanie ominięty

piątek, 18 stycznia 2013

Automatyczna konfiguracja Windows, cz.2

Tym razem przedstawię sposób na automatyczne przejście przez proces wyboru typu sieci (publiczna, domowa, itp). Jest to dość przydatne podczas przygotowywania systemu do współpracy z Selenium Grid.

W poniższych przykładach węzeł ControlSet001 można zastąpić CurrentControlSet jeśli system był chociaż raz uruchamiany, w przeciwnym razie, gdy np. ściągnęliśmy obraz IE VHD i przygotowywujemy go do pierwszego uruchomienia klucz CurrentControlSet nie będzie jeszcze istniał.

W obu przypadkach efektem ominięcia wyboru typu sieci będzie oznaczenie danej sieci jak publiczna.

Windows 7

Tutaj sprawa jest prosta, należy zaimportować poniższy plik do rejestru i cieszyć się brakiem pytania o typ sieci.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Network\NetworkLocationWizard]
"HideWizard"=dword:00000001

Windows Vista

W systemie Vista ominięcie ekranu wyboru jest trochę bardziej skomplikowane. Nie istnieją żadne ustawienia rejestru (z tego co mi wiadomo) które pozwalają na automatyczne ustawienie typu sieci. Pozostaje więc napisanie skryptu VBS.

Set objShell = CreateObject("WScript.Shell")

'wait for window
While objShell.APpActivate ("Set Network Location") = FALSE
Wscript.Sleep 1000
Wend

While objShell.APpActivate ("Set Network Location") = TRUE
Wscript.Sleep 1000

'close window
objShell.Sendkeys "{ESC}"

Wend

Powyższy skrypt czeka na pojawienie się okna o nazwie Set Network Location po czym zamyka je klawiszem ESC.

W przypadku gdy chcemy by system został skonfigurowany juz przy pierwszym uruchomieniu trzeba jeszcze dodać poniższy wpis do rejestru by skrypt został automatycznie uruchomiony.

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce]
"glorpen_reg"="C:\\glorpen\\network_type.vbs"

Wpisy pod kluczem RunOnce są uruchamiane tylko raz - po wykonaniu ich wpisy są usuwane.

wtorek, 8 stycznia 2013

Automatyczna konfiguracja Windows, cz.1

Będzie to krótka seria przedstawiająca skrypty i ustawienia rejestru pozwalające na konfigurację systemów Windows Vista i 7. W tym artykule przedstawię sposób na automatyczną zmianę tematu wyglądu.

Oba poniżej podane pliki należy zapisać z rozszerzeniem vbs.

Wersja dla Windows7

Po uruchomieniu skryptu zostanie otwarte okno personalizacji w którym automatycznie zostanie zastosowany wybrany temat a następnie okno zostanie zamknięte kombinacją klawiszy Alt+f,c (w menu Plik / Zamknij).

'win7_theme.vbs

Set objShell = CreateObject("WScript.Shell")
Theme = """" & "C:\Windows\Resources\Ease of Access Themes\classic.theme" & """"
objShell.Run(cstr("control desk.cpl,,@themes /Action:OpenTheme /file:" & theme))

While objShell.APpActivate ("Personalization") = FALSE
       Wscript.Sleep 1000
Wend

While objShell.APpActivate ("Personalization") = TRUE
       Wscript.Sleep 2000
       objShell.Sendkeys "%fc"
Wend

Wersja dla Windows Vista

Po uruchomieniu skryptu zostanie otwarte okno wyboru tematu (skrypt będzie czekał aż takowe się pojawi). Wybrany temat zostanie zmieniony na ten podany w kodzie, a następnie zostanie wysłane naciśnięcie klawisza Enter.

'winVista_theme.vbs

Set objShell = CreateObject("WScript.Shell")

Theme = """" & "C:\Windows\Resources\Themes\Windows Classic.theme" & """"

objShell.Run(cstr("control desk.cpl,,@themes /Action:OpenTheme /file:" & theme))

While objShell.APpActivate ("Theme Settings") = FALSE
Wscript.Sleep 1000
Wend

While objShell.APpActivate ("Theme Settings") = TRUE
Wscript.Sleep 1600
objShell.Sendkeys "{ENTER}"
Wend