Zápisník

// Překlad UI a resource souborů v PyQt

PyQt je knihovna pro integraci populární knihovny Qt (u které byla nedávno změněna open-source licence z GPL na LGPL) do Pythonu. Pokud používáte nástroj Qt Designer na návrh uživatelského rozhraní, potřebujete následně přeložit XML popis UI a resourců do kódu pro Python, abyste jej mohli použít.

V C++ variantě Qt je možno jednoduše použít nástroj qmake nebo Automake pro vygenerování příslušného Makefile, který se o překlad do C++ postará. V případě Pythonu není standardně Makefile potřeba, jelikož se moduly kompilují samy při jejich zavádění. S PyQt můžete použít modul uic a XML soubory zkompilovat, nebo je přímo nahrát jako třídy Pythonu.

Alternativně lze použít nástroje do příkazové řádky pyuic4 and pyrcc4 úplně stejně jako jejich originály z knihovny Qt (uic, rcc). Pro své projekty jsem si zvolil tento způsob. Použití nástrojů je jednoduché. Stačí napsat, že chceme přeložit soubor A na soubor B. Příklad následuje.

#compile ui file from Qt Designer
pyuic4 ui_file.ui -o compiled_ui_file.py
#compile resource file (icons, etc..)
pyrcc4 resource_file.qrc -o compiled_resource_file.py

Původně jsem měl jeden jediný shellový skript, který vždy kompiloval všechny soubory najednou (byl jsem příliš líný). Tohle řešení mělo dvě výrazné nevýhody. Jednak kompilace všech souborů sežere nějaký čas, takže tato vlastnost představuje problém v závislosti na množství překládaných resource souborů. Za druhé, a to je pro mě otravnější vlastnost, generátor pyuic4 v hlavičkách vygenerovaného kódu zanechá aktuální čas a datum. Jelikož ze zatím neznámého důvodu uchovávám v Mercurialu i zkompilované verze UI, způsobovalo to pokaždé změnu všech zkompilovaných souboru. Takže jsem osvěžil svoje chabé znalosti tvorby Makefile (a použil taháky z dob minulých) a vytvořil jsem si Makefile pro separátní kompilaci resource souborů.

###### EDIT ##################### 
#Directory with ui and resource files
RESOURCE_DIR = src/resources
 
#Directory for compiled resources
COMPILED_DIR = src/ui
 
#UI files to compile
UI_FILES = confirm.ui main.ui repair.ui settings.ui statistics.ui
#Qt resource files to compile
RESOURCES = images.qrc 
 
#pyuic4 and pyrcc4 binaries
PYUIC = pyuic4.bat
PYRCC = pyrcc4
 
#################################
# DO NOT EDIT FOLLOWING
 
COMPILED_UI = $(UI_FILES:%.ui=$(COMPILED_DIR)/ui_%.py)
COMPILED_RESOURCES = $(RESOURCES:%.qrc=$(COMPILED_DIR)/%_rc.py)
 
all : resources ui 
 
resources : $(COMPILED_RESOURCES) 
 
ui : $(COMPILED_UI)
 
$(COMPILED_DIR)/ui_%.py : $(RESOURCE_DIR)/%.ui
	$(PYUIC) $< -o $@
 
$(COMPILED_DIR)/%_rc.py : $(RESOURCE_DIR)/%.qrc
	$(PYRCC) $< -o $@
 
clean : 
	$(RM) $(COMPILED_UI) $(COMPILED_RESOURCES) $(COMPILED_UI:.py=.pyc) $(COMPILED_RESOURCES:.py=.pyc)  

Funguje s GNU Make (na Windows například v Cygwinu nebo MinGW). Je potřeba poeditovat horní řádky souboru, především upravit cesty k souborům a jejich seznam. Skript překládá soubory následovně (příklad):

  • okno.ui –> ui_okno.py (definice GUI)
  • obrazky.qrc –> obrazky_rc.py (resources)

Teď se kompilují už jen ty změněné, stačí napsat make do konzole. Samozřejmě v pracovním adresáři shodným s umístěním Makefile souboru.

// Můj první plugin pro DokuWiki

Před několika měsíci jsem kompletně updatoval svoji website. Vybral jsem si DokuWiki jako velmi flexibilni engine rozšiřitelný spoustou pluginů.

Též jsem použil Blog plugin a další k vytvoření svého občasníku. Ale chyběla mi jedna vlastnost. Tou bylo zobrazení data vytvoření a autora na stránce příspěvku podobně, jako to vkládá Include plugin v seznamu. Ano, DokuWiki standardně tiskne zápatí, ale pokud je použit Discussion plugin, vloží se až pod všechny komentáře hodně hodně dolů.

Takže jsem spáchal jednoduchý plugin, který informace vkládá těsně pod příspěvek, nad komentáře. Stačí se podívat například na stránce tohoto příspěvku dolů. Musel jsem ale hrábnout do proměnných event handleru (které by v jiném jazyce velmi pravděpodobně byly privátní), abych plugin udělal prvním listenerem události TPL_ACT_RENDER_AFTER, tj. ještě před Discussion pluginem. Důsledkem toho je vždy text před komentáři. Nutno přiznat, že tento trik mi naťuknul Vity. Plugin lze stáhnout na stránce DokuWiki goodies.

// Photobase, nová verze, další featury

Po nějaké době jsem se dokopal k dalším inovacím na mojí fotogalerii. Stalo se tak vlastně až na základě okolností a potřeby nahrát do galerie cca 50 fotografií. Původní způsob jsem ihned zavrhl, protože bych se zřejmě uklikal k smrti. Světlo světa tak spatřil primitivní upload souborů přes FTP. K tomu jsem již dříve pracoval na systému pro lokalizaci, takže nyní mohu psát PhotoBase v angličtině a zachovat i českou verzi. Nemluvě o možnosti jednoduchého překladu do téměř jakéhokoli jazyka.

Lokalizace

PhotoBase

Abych si lokalizaci co nejvíce usnadnil, použil jsem jednoduše asociativního pole. Jednotlivá hesla k překladu jsou klíči pole a přeložená hesla pak obsahem jednotlivých položek. Tvorba nové lokalizace pak spočívá v založení nového souboru v podadresáři /inc/lang podle již existujícího exempláře a následného přeložení hodnot v poli. Jedinou nevýhodou je nutnost zachování korektní PHP syntaxe.

V kódu pak volám pro vložení hesla příslušnou funkci, která zajistí překlad, případně nahlásí debugovací komponentě neexistenci překladu a použije původní text. Pro složitější konstrukce s proměnlivými položkami existuje funkce, která po překladu provede nahrazení výrazů %1, %2 apod. hodnotami uvedenými jako parametry funkce. Tento fígl je použit snad ve všech aplikacích, které znám.

FTP upload

FTP upload

FTP upload

Jak bylo již řečeno, důvodem pro uspíšení vytvoření této funkce byla hromada fotek, které ulpěly na paměťové kartě mého mobilu po dovolené na Vysočině. Upload přes FTP není úplně to, co bych si představoval, pro někoho může být postup příliš složitý nebo nepohodlný, ale je to asi nejjednodušší řešení, kterého jsem byl schopen dosáhnout.

Jak to zhruba funguje … Administrátor musí každému uživateli, který chce nahrávat fotky přes FTP, vytvořit adresář pro uploady nesoucí jeho přihlašovací jméno a příslušný účet, pomocí kterého může uživatel do adresáře fotky nahrát. Tento požadavek je asi ze všeho nejvíc „zdržující“ a navíc je nutno při vytváření účtu dát pozor na přístupová práva, aby nebyla ohrožena bezpečnost aplikace (přístup do jiného než adresáře pro upload). Uživatel potom adresář naplní fotkami, které chce přidat. Pomocí příslušného odkazu přejde k hromadnému vkládání. Skript načte všechny soubory a zkontroluje jejich mime-typy, případně upozorní na neobrázkové soubory, které je nutno před nahráním z adresáře odstranit. Uživatel vybere galerii, do které chce fotografie nahrát a potvrdí.

V tuto chvíli nastává další z problémů tohoto řešení. Skript by měl správně soubory přesunout do adresáře pro fotografie. Ale důsledkem toho, že má FTP uživatel většinou jiná práva než webserver, je fakt, že skript soubory z adresáře pro upload odstranit nemůže. Proto je pouze zkopíruje a na tuto „chybu“ upozorní a varuje před možným opětovným nahráním v případě ponechání oněch souborů.

V budoucnu bych chtěl tuto nepohodlnou funkci nahradit mnohem sofistikovanější. Jako nejhezčí řešení se jeví Java applet. Bohužel v tuto dobu jednoduše prostě netuším, jak to přesně funguje. Například Facebook má velmi povedený. Asi začnu o této alternativě zjišťovat víc. Další možností je uploadovat fotografie v jednom souboru, například jako ZIP nebo TAR. Jenže to naráží na omezení v podobě maximální velikosti dat odesílaných metodou POST, takže se to jeví jako slepá ulička.

Nicméně ...

nové funkce jsou na světě. A to ještě před půl rokem to vypadalo, že tento mini-projekt bude jako spousta jiných zapomenut pod záplavou ostatních věcí a povinností. Takže pro zájemce odkazuji na stránky projektu PhotoBase. Pokud byste se přeci jen rozhodli galerii vyzkoušet, přivítám Vaše odezvy a případné hlášení chyb. Enjoy!

// MiniMath - pozdě, ale přece

MiniMath jsem začal tvořit již někdy v roce 2006 jakožto semestrální práci na předmět Jazyky a překladače. Shodou okolností jsem tehdy měl i pokročilé C++, takže cvičící si k tomu přimyslel nějake požadavky, včetně GUI, a náplň vánočních prázdnin jsem měl jasnou.

Pozdě, ale přece?

Minimath ikonka

Program byl v podstatě hotov někdy ze začátku ledna 2007, nicméně teprve teď jsem se dostal k tomu, abych jej dostal do podoby, která se hodí k publikaci. Proč až teď? Přesnou odpověd neznám, ale zcela jistě v tom měly prsty školní a jiné povinnosti. Následující semestr byl totiž ve znamení programování bakalářky a jiných semestrálek (mj. PhotoBase vznikla jako práce na předmět Internet a WWW). Také se mi povedlo projekt recyklovat v předmětu Programování v jazyku Java, kde jsem celý kód přepsal do Javy a GUI do Swingu. Červenec jsem strávil (doteď nevím, proč tak dlouho) psaním bakalářky a v srpnu jsem částečně „odpočíval“ a částečně se učil na státnice. Po euforii z 20. září jsem nějakou chvíli neměl chuť nic dělat. Další semestr, už na mgr. studiu, byl ve znamení spousty semestrálek a podivných předmětů (znáte to, prvák je vždycky nejhorší). No a tím jsem se na časové ose přiblížil až k dnešku…

Co že to vlastně je

MiniMath prerelease

Hlavní okno programu

MiniMath je tedy překladač a interpreter příkazů vlastního jazyka matematických výrazů a operací. Umožňuje definovat proměnné a funkce včetně rekurze, kterou lze ovládat jen a pouze pomocí ternárního operátoru (nebo spíš funkce) If, a tak rekurzi zastavit, jako jednoduchý příklad lze uvést definici faktoriálu

fact (x) = if (x>0, x*fact(x-1), 1)

a = fact(6)

Hodnoty proměnných se počítají, až při výstupu na obrazovku, tedy jejich definici nelze založit na předchozí hodnotě (např. a=a+2). V tomto případě překladač pozná „přímou“ rekurzi a definici nepoužije. V případě definice faktoriálu výše ovšem pouze upozorní na možnost zacyklení, protože to lze správnou podmínkou zastavit. Výstup na obrazovku se provádí příkazem

write(promenna, „nebo nějaký text“)

Vypočtené hodnoty proměnných se cachují a platnost cache se nastavuje dynamicky podle změny závislostí a redefinicí závislých proměnných/funkcí. Platné cache hodnoty se v logu dynamicky zvýrazňují. Čtení ze vstupu se provádí zabudouvanou funkcí (z hlediska jazyka spíš klíčového slova) read, např.

a = read(„test výzvy ke vstupu“)

V tomto případě se read zavolá při každém vyhodnocení proměnné a (pokud už není v cache).

GUI je vytvořeno na frameworku Qt 4, opensource verzi, program je tudíž uvolněn pod GNU GPL. Pro formátování výstupu lze použít CSS, vzorový soubor je přiložen. MiniMath lze jednoduše rozšířit o další zabudované funkce, které nelze zadefinovat algebraickými operacemi. Ve zdrojovém kódu existuje příslušná abstraktní třída na zabudované funkce/konstanty. Pro lepší čitelnost doporučuji vygenerovat dokumentaci pomocí nástroje Doxygen.

Doufám, že aspoň někomu se můj prográmek bude líbit. Kompletní distribuci najdete na stránce projektu MiniMath.

// Nové výtvory

PhotoBase

PhotoBase

Konečně jsem se donutil k tomu, abych dopiloval a uvolnil první várku mých výtvorů z nedávné doby. Ty kódy existují už několik měsíců, jen jsem se pořád neměl k tomu je dokopat do nějaké rozumné formy a samozřejmě dopsat vhodný readme.txt soubor ;-)

Součástí „první“ várky je tedy jednoduchá webová galerie fotek, kterou jsem již dal do provozu i zde (odkaz). Je opravdu jednoduchá, takže zázraky typu Coppermine Photo Gallery nečekejte. Nicméně díky tomu zase běhá velmi svižně i na slabších strojích. A hlavně, hodlám na ní ještě něco tvořit.

browser statistics

Statistiky browserů

Druhým výplodem, spíš výplůdkem je generátor koláčových grafů na základě statistik získaných pomocí systému BBClone. Vykresluje TOP10 statistiky návštěvnosti (browsery, operační systémy, navštívené stránky a hledaná klíčová slova). Obrázek ukazuje návštěvnost podle browserů na tomto webu.

Více o obou aplikacích v sekci Projekty.

O mně
SW developer, amateur tennis player, rock'n'roll & heavy metal fan.