Podgląd strony do pliku jpg?

Poruszenie w Internecie tematyką wprowadzania cenzury, o której ostatnio pisałem, podsunęło mi pewien pomysł, który mam nadzieję niebawem Wam przedstawię. W między czasie uznałem, że w projekcie przyda mi się funkcjonalność zautomatyzowanego robienia podglądów (thumbnail) stron WWW do obrazków. Miałem przy tym całkiem dużo frajdy i mam nadzieję, że efekty mojej pracy komuś się to przydadzą.

Serwisów które przygotowują podgląd stron jest w sieci niewiele, a takich, które za darmo udostępniają wygodne API, nie mają śmiesznie małych limitów przygotowań podglądów nie znalazłem. Napisałem sobie takie narzędzie sam. Jeśli ktoś chce wykorzystać ten kod – proszę bardzo – proszę tylko o informację gdzie jest on dostępny oraz liczę na darmowy dostęp ;)

Twoja własna mini-przeglądarka

Jak szybko zrobić sobie przeglądarkę z obsługą Flasha, JavaScriptu i tych wszystkich urozmaiceń? Wystarczyło mi kilkanaście minut :) Zdecydowałem się na użycie GTK (domyślnego zestawu kontrolek dla m.in. Gnome) oraz Webkit’a – silnika do renderowania wykorzystywanego w takich przeglądarkach jak Safari (Mac OS), Google Chrome (Windows) czy Midori (Linux):

#!/usr/bin/env python

url = 'http://www.nme.pl'
size = [800, 600]

import gtk,webkit
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_default_size(size[0], size[1])
window.connect('destroy', gtk.main_quit)
preview = webkit.WebView()
preview.open(url)
scrolled = gtk.ScrolledWindow()
scrolled.add(preview)
window.add(scrolled)
window.show_all()
gtk.main()

Właściwy podgląd strony

Kod trzeba było trochę rozbudować. Konfiguracja jest w klasie conf. Uruchamiając kod w pierwszym parametrze należy podać adres strony (nie zapominając o nazwie protokołu, np. http://www.nme.pl).

w katalogu w którym znajduje się skrypt trzeba założyć podkatalog thumb, w którym zapisywane będą obrazki jpg.

shot.py:

#!/usr/bin/env python

__author__ = 'mw AT nme.pl'
__version__ = '1.0'
__date__ = 'wto, 25 sie 2009, 09:15:48 CEST'

import pygtk
pygtk.require('2.0')
import gtk,gtk.gdk,gobject
import webkit
import hashlib
import os,sys

class conf:
    show_scrollbars = True
    show_progress = True
    script_timeout_secs = 15
    size = [1024, 768]

class Snapshot:

    def load_progress_changed(self, view, progress):
        print '%d%%' % progress

    def load_finished(self, view, frame):
        print 'loading finished'
        w = gtk.gdk.get_default_root_window()
        wp = self.window.get_position()
        ws = self.window.get_size()
        sz = w.get_size()
        pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False,8,ws[0],ws[1])
        pb = pb.get_from_drawable(w,w.get_colormap(),wp[0],wp[1],0,0,ws[0],ws[1])
        if (pb != None):
            pb.save('thumbs/'+self.file+'.jpg','jpeg',{'quality':'95'})
        gtk.main_quit()

    def __init__(self, url=None):

        self.url = url
        self.file = hashlib.sha512(url).hexdigest()
        self.overtime = False
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_default_size(conf.size[0], conf.size[1])
        self.window.set_decorated(False)
        self.window.connect('destroy', gtk.main_quit)
        self.preview = webkit.WebView()
        self.preview.open(self.url)
        if conf.show_progress:
            self.preview.connect('load-progress-changed',self.load_progress_changed)
        self.preview.connect('load-finished',self.load_finished)
        self.scrolled = gtk.ScrolledWindow()
        if conf.show_scrollbars:
            self.scrolled.props.hscrollbar_policy = gtk.POLICY_AUTOMATIC
            self.scrolled.props.vscrollbar_policy = gtk.POLICY_AUTOMATIC
        else:
            self.scrolled.props.hscrollbar_policy = gtk.POLICY_NEVER
            self.scrolled.props.vscrollbar_policy = gtk.POLICY_NEVER
        self.scrolled.add(self.preview)
        self.window.add(self.scrolled)
        self.window.show_all()
        gobject.timeout_add(conf.script_timeout_secs*1000, self.timeout)
        gtk.main()

    def timeout(self):
        gtk.main_quit()
        sys.exit(1)

if len(sys.argv)==2:
    Snapshot(url=sys.argv[1])
else:
    print >> sys.stderr, "Usage: %s url\n" % sys.argv[0]
    sys.exit(1)

Wrapper do generowania właściwego poglądu

Skrypt działa, ale wymaga działania X’ów, coś nam jeszcze wyświetla i zapisuje obrazek w skali 1:1. Da się to zrobić w tle. Potrzebujemy do tego dwóch narzędzi – convert z pakietu imagemagick oraz pakietu xvfbVirtual Framebuffer ‘fake’ X server. Mając już te narzędzia – całą robotę zrobi za nas skrypt o nazwie snap:

#!/bin/bash

state=0
plik=`python -c "import hashlib; print hashlib.sha512('$1').hexdigest()+'.jpg'"`
[ -e "thumbs/$plik" ] || {
	xvfb-run -a --server-args='-screen 0 1024x768x16' python shot.py $1
}
state=$?
[ "$state" -eq "0" ] && {
	[ -e "thumbs/$plik" ] && {
		convert -scale 310x -quality 75 thumbs/$plik thumbs/$plik
	} || {
		exit 1
	}
} || {
	exit 1
}

skryptowi nadajemy prawa do jego uruchamiania:

chmod +x snap

i uruchamiamy:

./snap http://www.nme.pl

w katalogu thumb odnajdujemy gotowego jpg’a (jego nazwa jest hashem sha512 URL’a). Wygląda to tak:

www.nme.pl-thumb

Powiązane, teksty w języku angielskim:

  1. Podobne rozwiązanie w oparciu o Qt, warto obejrzeć.
  2. Przykładowy opis jak można uruchomić serwis do generowania podglądów w oparciu o Django z nawiązaniem do gotowych już rozwiązań.

Comments

2 odpowiedzi do wpisu “Podgląd strony do pliku jpg?”
  1. baderman pisze:

    Ah, żeby tak gnome’a i webkita mieszać, no nie ładnie, nie ładnie :) .
    Wszystkie dzieci pamiętają, że gnome jest be a qt rulezi :)

    A tak zupełnie na poważnie, to zgrabna i w sumie prosta rzecz. Podoba mnie się :)

  2. nme pisze:

    -WebKit? ot, taka kontrolka GTK.
    ;)

    QT zaczyna być rulez od kiedy zmieniła mu się licencja, czyli od wersji 4. Wcześniej ten prodakt zupełnie mnie nie interesował :)

Zostaw komentarz