VYSOKÉ UČENÍ TECHNICKÉ V BRNĚ BRNO UNIVERSITY OF TECHNOLOGY
FAKULTA INFORMAČNÍCH TECHNOLOGIÍ ÚSTAV INFORMAČNÍCH SYSTÉMŮ FACULTY OF INFORMATION TECHNOLOGY DEPARTMENT OF INFORMATION SYSTEMS
VEŘEJNÉ ZAKÁZKY EU: STATISTIKY A PŘEHLEDY
BAKALÁŘSKÁ PRÁCE BACHELOR'S THESIS
AUTOR PRÁCE AUTHOR
BRNO 2014
VOJTĚCH KURKA
VYSOKÉ UČENÍ TECHNICKÉ V BRNĚ BRNO UNIVERSITY OF TECHNOLOGY
FAKULTA INFORMAČNÍCH TECHNOLOGIÍ ÚSTAV POČÍTAČOVÝCH SYSTÉMŮ FACULTY OF INFORMATION TECHNOLOGY DEPARTMENT OF COMPUTER SYSTEMS
VEŘEJNÉ ZAKÁZKY EU: STATISTIKY A PŘEHLEDY TENDERS OF EU: STATISTICS AND SURVEYS
BAKALÁŘSKÁ PRÁCE BACHELOR'S THESIS
AUTOR PRÁCE VOJTĚCH KURKA AUTHOR
VEDOUCÍ PRÁCE SUPERVISOR
BRNO 2014
Ing. PAVEL OČENÁŠEK, Ph. D.
Abstrakt Cílem této práce je poskytnout uživateli různorodé statistiky a přehledy o veřejných zakázkách EU. Statistiky a přehledy jsou ve formě grafů, textových srovnání a teplotních map. Vycházejí přitom z dat, které aplikace zjistí z webových stránek pro to určených. Ty jsou uloženy v MySQL databázi a mimo jiné i poskytovány ve strojově čitelném formátu dalším zájemcům. Důraz je kladen na jednoduché a srozumitelné především grafické zpracování dat. Přístup k těmto vizualizacím je přes webové stránky optimalizované pro nejpoužívanější prohlížeče.
Abstract The purpose of this bachelor thesis is to provide well-arranged statistics and surveys about tenders in the European Union. Statistics and surveys are visualized as graphs, textual informations and different kinds of maps. Those statistics are based on data from corresponding EU information system and stored in MySQL database. In advance these data are offered to others in machine readable format. Easy understanding and mainly graphical representation of data is the most important part. All statistics are accessible via web pages optimized for the most common web browsers.
Klíčová slova Evropská unie, veřejné zakázky, webové stránky, data mining, sběr dat, vizualizace, grafy, PHP, MySQL, API, JSON
Keywords European Union, tender, web pages, data mining, data visualization, graphs, statistics, PHP, MySQL, API, JSON
Citace Vojtěch Kurka: Veřejné zakázky EU: Statistiky a přehledy, bakalářská práce, Brno, FIT VUT v Brně, 2014
Veřejné zakázky EU: Statistiky a přehledy
Prohlášení Prohlašuji, že jsem tuto bakalářskou práci vypracoval samostatně pod vedením Ing. Pavla Očenáška, Ph.D. Uvedl jsem všechny literární prameny a publikace, ze kterých jsem čerpal. …………………… Vojtěch Kurka 20. 5. 2014
Poděkování Chtěl bych poděkovat vedoucímu práce, Ing. Pavlu Očenáškovi, Ph.D., za odborné rady a trpělivost. Neméně vděčný jsem rodičům za jejich podporu po celou dobu mého studia.
© Vojtěch Kurka, 2014 Tato práce vznikla jako školní dílo na Vysokém učení technickém v Brně, Fakultě informačních technologií. Práce je chráněna autorským zákonem a její užití bez udělení oprávnění autorem je nezákonné, s výjimkou zákonem definovaných případů.
Obsah Obsah...................................................................................................................................................1 1 Úvod...................................................................................................................................................2 2 Specifikace aplikace...........................................................................................................................3 2.1 Existující řešení...........................................................................................................................3 2.2 Prezentace dat uživateli...............................................................................................................3 2.3 Uložení dat..................................................................................................................................3 2.4 Získávání dat...............................................................................................................................3 2.5 Statistiky a přehledy....................................................................................................................4 3 Analýza a návrh..................................................................................................................................6 3.1 Použité technologie.....................................................................................................................6 3.2 Ukládání dat................................................................................................................................7 3.3 Získávání dat.............................................................................................................................10 3.4 Prezentace dat...........................................................................................................................11 4 Implementace...................................................................................................................................13 4.1 Pamatovák.................................................................................................................................13 4.2 Seznam kategorií dokumentů a informací o zemích..................................................................16 4.3 Fronta........................................................................................................................................18 4.4 Plánovač....................................................................................................................................18 4.5 Otrok.........................................................................................................................................20 4.6 Průběh stahování.......................................................................................................................23 4.7 Dozorce.....................................................................................................................................24 4.8 Použití architektury pro stahování dat také z jiných serverů.....................................................25 4.9 Prezentace dat...........................................................................................................................25 4.10 Testování architektury a komponent.......................................................................................28 5 Další vývoj projektu.........................................................................................................................29 6 Závěr................................................................................................................................................30 Literatura............................................................................................................................................31
1
1
Úvod
S rozvojem informačních technologií přišla i možnost cokoliv měřit, zaznamenávat, hodnotit a přepočítávat. Díky tomu je možné i pro obyčejného smrtelníka představit si, kolik videí je každou minutu nahráno na Youtube, kolik slonů se narodí v Africe a v neposlední řadě také to, kolik a kdo nejvíce vypisuje veřejných zakázek. Infografiky a různá srovnání se stávají stále oblíbenější v běžných tématech. Ovšem téma veřejných zakázek, které nyní stojí v povzdálí, je neméně zajímavé. Díky získaným informacím je možné pomocí interaktivních grafů prezentovat zajímavé a užitečné skutečnosti o tom, který ze států Evropské unie nabízí nejvíce práce, či které odvětví je nejpopulárnější. Cílem této práce je jednoduchou a srozumitelnou formou prezentovat zajímavá čísla a poměry, které se týkají veřejných zakázek jednotlivých států Evropské unie. Pomocí grafů a teplotních map je možné si názorně ukázat zákoutí tohoto oboru. Práce navrhuje možná řešení problémů při získávání dat, jejich uložení a následné prezentaci pomocí nejrozšířenějších technologií.
2
2
Specifikace aplikace
Tato kapitola popíše funkce, požadavky a vlastnosti prezentace dat uživateli, uložení a získávání těchto dat. V krátkosti popíše také aktuální situaci v oblasti statistik a přehledů nejen veřejných zakázek.
2.1
Existující řešení
Fenomén statistik a přehledů v různých oblastech pro širokou veřejnost se začíná objevovat až v posledních letech s nástupem digitalizace dat. V této chvíli jsou statistiky veřejných zakázek doménou statistických úřadů a specializovaných agentur. Pro veřejnost jsou připraveny dokumenty většinou pro tabulkové procesory, které podávají velmi jednoduché a strohé informace.
2.2
Prezentace dat uživateli
Pro zobrazení grafů, statistik a teplotních map slouží webová stránka. Má přehlednou, strukturovanou nabídku odkazů na každé stránce, aby se uživatel mohl jednoduše orientovat. Nabídka vede na jednotlivé statistiky a přehledy, na jedné stránce může být více tématicky příbuzných statistik. Popis grafů je v samostatné kapitole.
2.3
Uložení dat
Data jsou uložena v relační databázi. Je nutné ukládat data tak, aby byla zachována jejich provázanost. Například detailní stránka o zakázce může obsahovat informace o tom, ze které země pochází. Do databáze se tedy uloží pouze odkaz na správnou zemi z tabulky dostupných zemí. Data budou dostupná pomocí aplikačního rozhraní v JSON formátu, kvůli dalším možnostem rozšíření například na mobilní platformy.
2.4
Získávání dat
Data budou získávána z webového systému TED [1]. Budou staženy a uloženy informace o zadání zakázek ze všech států Evropské unie. Stažení bude možno distribuovat na více počítačů a spustit jej paralelně.
3
2.5
Statistiky a přehledy
V této kapitole budou popsány všechny statistiky a přehledy o veřejných zakázkách. Jsou rozděleny dle způsobu prezentace.
2.5.1
Mapy
Mapy s různými způsoby vizualizace informací. Výběr dat je možno omezit dle kategorií. Demografická mapa světa – mapa zobrazující celý svět, opticky rozdělený dle zemí. Každá země je vyplněna různě intenzivní barvou v závislosti na počtu vypsaných veřejných zakázek. Demografická mapa Evropy – stejný typ mapy jako minulá, soustřeďuje se na Evropu. Demografická mapa světa dle populace – v této mapě intenzita barvy znázorňuje počet vypsaných veřejných zakázek na 1 000 000 obyvatel. Demografická mapa Evropy dle populace – opět stejná mapa se zaměřením na Evropu. Teplotní mapa – tato mapa zobrazuje jednotlivá místa, kde jsou zakázky vypisovány, s přesností na města. Barva oblastí přechází od zelené po červenou – čím více se barva blíží červené, tím více zakázek bylo v daném místě vypsáno.
2.5.2
Výsečové grafy
Výsečové grafy ukazují procentuální podíly různých parametrů na celkovém počtu veřejných zakázek. Následující grafy znázorňují podíly: Země – dle zemí a skupin zemí (Evropská unie, Evropský hospodářský prostor, …). Jazyk – dle jazyků, ve kterých byla zakázka původně vypsána, navíc volitelně dle zemí. Kategorie – dle kategorií na první a druhé úrovni stromu kategorií a dle zemí. Zakázky – dle zakázek a zemí. Druh dokumentu – dle druhu dokumentu a zemí. Zadavatel – dle zadavatele a zemí. Řízení – dle řízení a zemí. Nařízení – dle nařízení a zemí.
2.5.3
Jiné
Tato kategorie obsahuje grafy, které se nedají zařadit do jiných kategorií. Dny v týdnu – tento sloupcový graf ukazuje, kolik zakázek bylo vypsáno v jednotlivých dnech týdne. Výsledná data pro graf lze omezit dle země a kategorie. 4
Trvání – histogram ukazující, jaká je nejčastější doba trvání veřejné zakázky – čas od vypsání do očekávaného ukončení výběrového řízení. Zobrazený výsledek je možné omezit dle země nebo kategorie.
5
3
Analýza a návrh
Tato kapitola se zabývá analýzou problémů vyplývajících ze specifikace a návrhem jejich řešení.
3.1
Použité technologie
PHP Pro serverovou část projektu je využit jazyk PHP [2]. V tomto jazyce jsou implementovány všechny moduly a komponenty, včetně modulů pro získávání dat. Volba padla právě na PHP vzhledem k jeho rozšířenosti a oblíbenosti. Tuto technologii v dnešní době podporuje drtivá většina hostingových služeb, proto je vhodná i pro projekt, který má ukázat jednoduchost získání dat z různých zdrojů a jejich zpracování. MySQL Jako úložiště dat je použita databáze MySQL [3] z podobných důvodů jako PHP. Na internetu je k dispozici nepřeberné množství tutoriálů a návodů, jak s MySQL pracovat. jQuery Pro dynamické zpracování formulářů a načtení dat pomocí AJAXu [22] je použita knihovna jQuery [4]. Tato knihovna zastřešuje nejpoužívanější funkce Javascriptu a zjednodušuje použití asynchroních požadavků vzhledem k nekompatibilitě prohlížečů. Google API Google API [5] poskytuje různorodou sadu aktivních komponent pro webové stránky. Pro účely projektu jsou použity komponenty pro zobrazení teplotních map a různých grafů. Google API je použito z důvodu jednoduchého nasazení, široké podpory a dobré dokumentace. JSON Pro načítání nových dat formuláři je použit JSON jako transportní formát dat. Oproti XML je stručnější a má přímou podporu v prohlížečích. Composer Composer [6] je balíčkovací systém pro PHP. Jedná se o obdobu nástrojů pro správu aplikací v Unixových systémech. Díky tomuto nástroji je velmi jednoduché udržovat aktuálnost používaných
6
knihoven či distribuovat výslednou aplikaci bez toho, aby obsahovala použité knihovny a tím zvětšovala svou velikost. Selenium Nástroj Selenium [7] je původně určen pro testování uživatelského rozhraní webových stránek. Je to server, který spustí prohlížeč a provádí na stránce příkazy zadané ve skriptu. Byl zvolen převážně kvůli existenci a kvalitě knihovny pro použití v jazyce PHP.
3.2
Ukládání dat
O manipulaci s daty, která jsou uložena v MySQL databázi, se stará modul jménem Pamatovák. Tento modul poskytuje rozhraní pro operace s daty – vkládání, editace, mazání a výběr z databáze. Používá architekturu Model a Controller, díky které se dá lehce udržovat a rozšiřovat. Společné funkce jednotlivých modelů a kontrolérů jsou obsaženy v abstraktních třídách. Konkretní logické objekty z nich následně dědí a implementují vlastní metody, specifické pro daný objekt.
7
3.2.1
Schéma databáze
Pro uložení informací o dokumentech popisujících veřejné zakázky, kategorie, a další data byla navržena následující struktura.
Obrázek 3.1: Databázové schéma Pamatováka 8
category – informace o kategoriích a jiných informacích přímo souvisejících s dokumenty. Záznamy jsou strukturovány jako strom, přesný popis obsahuje kapitola 4.2 Seznam kategorií dokumentů a informací o zemích. document – tabulka obsahuje záznamy o jednotlivých dokumentech. Cizí klíče s příponou _id, u kterých není uvedena vazba, ukazují do tabulky category. Vzhledem k počtu takových vztahů byly pro přehlednost schématu vynechány. place – místa, kde se vypisují veřejné zakázky. queue – fronta úkolů použitá využívána Plánovačem a Otrokem. cpv_map – vazební tabulka s informacemi o tom, do kterých kategorií spadají dokumenty. system – nastavení Pamatováka, především hesla pro manipulaci s daty a přístupem k Dozorci. Uvedené databázové schéma obsahuje pouze tabulky nezbytně nutné pro uložení dat a běh aplikace. V aplikaci přibyly další tabulky pro archivaci dokumentů a předpočítané statistické výsledky.
3.2.2
Komunikace s ostatními moduly
Komunikace s ostatními moduly probíhá pomocí JSON rozhraní. Pomocí HTTP protokolu pošle jiný modul požadavek se zadanými parametry buď pomocí metody GET, POST nebo ve formátu JSON v těle zprávy. Následně Pamatovák odpoví s daty ve formátu JSON, opět v těle zprávy. Požadavek pro Pamatovák má povinné tyto parametry: controller – značí, se kterou entitou z databáze bude požadavek pracovat, action – udává, jakou operaci budeme nad daty provádět, data – asociativní pole samotných dat. Odpověď od Pamatováka má také pevnou strukturu. Obsahuje: info – tato položka je nepovinná – jedná se o doplňující informace o zpracování požadavku, error – taktéž nepovinná položka, která obsahuje případné chybové hlášení, data – obsahuje data v závislosti na druhu požadavku.
9
Cache Vzhledem k tomu, že se data nemění příliš často, je vhodné použít při zpracování požadavků cache paměť. Ta ušetří zbytečné opakované dotazy do databáze, které by jinak vracely stále stejná data. Identifikace obsahu odpovědi, která se má z paměti načíst, je zajištěna kombinací parametrů požadavku pro Pamatovák. Při výběru dat z paměti se zkontroluje poslední modifikace dat a pokud záznamu skončila platnost dle konfiguračního souboru, provede se kompletní vyhodnocení požadavku. Data pro cache jsou uložena jako serializované asociativní PHP pole v textové podobě v souboru na disku. Pro zvýšení výkonu je možné použít některou z technologií jako Memcache a Memcached, ovšem jejich nasazení na běžný hosting není triviální.
3.2.3
Zabezpečení komunikace s ostatními moduly
Požadavky, které mění obsah databáze, je vhodné zabezpečit tak, aby je nemohla neoprávněná strana provést. Z tohoto důvodu je nutné, aby požadavky na vložení, editaci a mazání dat posílaly zároveň s daty i heslo. To se vygeneruje pouze jednou při instalaci Pamatováka a v databázi je uloženo pomocí hash funkce. Pokud Pamatovák zpracovává požadavek bez hesla nebo se špatným heslem, jeho odpověď bude obsahovat HTTP stavový kód 403 a v položce error v těle odpovědi odpovídající informace o neoprávněném přístupu.
3.3
Získávání dat
Tato kapitola se zabývá získáváním dat z primárního zdroje.
3.3.1
Struktura zdroje dat
Pokud se na vyhledávání na stránkách TED podíváme z pohledu typových stránek, najdeme zde dvě základní. První z nich je stránka s výsledky. Tato stránka obsahuje, kromě jiného, stránkovač a seznam výsledků vyhledávání – odkazů na jednotlivé dokumenty. Druhá typová stránka je stránka s detailními informacemi o daném dokumentu. Postup získání dat je tedy nasnadě – pomocí vyhledávacího formuláře zobrazíme námi požadované výsledky. Následně získáme ze stránky seznam odkazů na detailní stránky. Pokud je daný odkaz v databázi, nemusíme na něj ani přistoupit. Pokud ovšem tento odkaz v databázi není, tak jej navštívíme, získáme data a ty uložíme do databáze společně s odkazem.
10
3.3.2
Získání dat ze stránky
Získání dat ze stránky se z prvu může zdát jako složité, opak je však pravdou. Každý z HTML prvků na stránce je adresovatelný pomocí Xpath [13] identifikátoru. Stačí tedy získaný HTML kód zpracovat pomocí libovolné knihovny pro zpracování XML a HTML stromů a najít prvky, které obsahují požadovaná data. Pro účely tohoto projektu je použit PHP Simple HTML DOM Parser [10] vzhledem k jeho monopolní pozici v porovnání s ostatními nástroji a jednoduchosti použití.
3.3.3
Plánovač a Otrok
Pro získání dat z typových stránek slouží dva moduly, Plánovač a Otrok. Plánovač existuje vždy jeden a má za úkol zpracovávat výsledky vyhledávání ve zdroji dat. Očekává první typovou stránku, ze které vybírá odkazy na jednotlivé detailní stránky dokumentů. Pokud detailní odkaz není v databázi, vloží jej do fronty pro zpracování Otroky. Otroků může najednou existovat více. Starají se o získání dat z detailních stránek a uložení získaných dat do databáze. Odkazy pro zpracování vybírají z fronty. Tím, že může existovat více Otroků zároveň a díky komunikaci s Pamatovákem pomocí JSON rozhraní, je možné spustit Otroky na více oddělených strojích a distribuovat tak zátěž. Zároveň je možné pro Otroky definovat proxy servery, přes které přistupují ke zdroji dat a tím částečně maskovat aktivitu Otroků.
3.3.4
Komunikace Plánovače a Otroků
Pro komunikaci Plánovače a Otroků je použita fronta. Ta je realizována pomocí tabulky v MySQL databázi, fronta je typu FIFO.
3.3.5
Údržba dat a přehled datového úložiště
Pro správu dat, udržbu vazebních tabulek a podobné administrativní úkony je určen modul Dozorce. Ten má za úkol například získávat GPS souřadnice o místech, sledovat velikost dat v databázi, či vytvářet a aktualizovat agregační výpočty pro zrychlení generovaní odpovědí.
3.4
Prezentace dat
Data jsou návštěvníkovi prezentována jako webová stránka. Dokud se stránka nenačte uživateli celá, tak neprovádí žádné dotazy do databáze. Ty si vyžádá pomocí API od Pamatováka. Jednotlivé grafy a teplotní mapy jsou rozděleny tématicky do kategorií. Každá stránka v kategorii obsahuje jeden či více grafů nebo teplotních map. U každého grafu je interaktivní
11
formulář, který reaguje na změnu hodnot jeho prvků. Po změně hodnoty odešle dotaz na nová data Pamatováku. Jako odpověď dostane JSON objekt s daty, pomocí kterých aktualizuje graf.
3.4.1
Tvorba grafů a teplotních map
Grafy jsou vykreslovány pomocí Google API, konkrétně balíčku Corecharts. Pro teplotní mapy je použito Google Maps API. Obě tyto komponenty jsou jednoduché objekty, které očekávají zadání dat ve formě JavaScript pole. Jak už bylo zmíněno, data pro grafy a teplotní mapy jsou získána ze serveru pomocí JSON API a následně vložena do grafu.
12
4
Implementace
Tato kapitola se zabývá implementací jednotlivých modulů. Bude rozebrán postup vytváření modulů stejně jako problémy, které při implementaci nastaly.
4.1
Pamatovák
Pamatovák, tedy modul starající se o databázi, je navržen pomocí architektury Model – Controller. Je to architektura odvozená od Model – View – Controller [11], kdy je pouze vynechán pohled. Není ho potřeba, jelikož Pamatovák komunikuje s ostatními moduly pomocí JSON API. Adresářová struktura Adresářová struktura se skládá z následujících složek: |_ app |
|_ controllers
|
|_ models
|_ cache |_ config |_ lib |_pamatovak Složka config obsahuje soubory s nastavením prostředí a připojení k databázi. Složka lib pak zdrojové kódy všech knihoven a nástrojů, které jsou použity. Mezi tyto nástroje patří i samotný Pamatovák. Tento přístup byl zvolen kvůli oddělení zdrojových kódů samotného Pamatováka jako obecného nástroje a zdrojových kódů pro konkrétní použití. Při takto zvoleném rozdělení je velice jednoduché aktualizovat Pamatováka na novou verzi pouhým přepsáním složky s nástrojem. Složka app obsahuje již zmíněné zdrojové kódy konkrétního použití Pamatováka. Jsou rozděleny na modely a kontroléry. Toto rozdělení a názvy složek je nutné dodržet, neboť Pamatovák automaticky načítá zdrojové kódy a očekává je v těchto místech. Programová struktura Obecný nástroj Pamatovák se skládá z osmi tříd. Základem je třída Pamatovak, která se stará o počáteční kontrolu přípojení databáze, instalaci a spuštění jednotlivých částí. Při prvním spuštění Pamatováka s prázdnou databází se provede instalace pomocí třídy Install. Ta zkontroluje, zda je
13
v databázi přítomna tabulka s nastavením. Pokud není, vytvoří ji zároveň s heslem, které bude později použito při komunikaci požadavků s vyšším oprávněním – typicky změna dat v databázi či přidání nových. Po úspěšné instalaci lze v konfiguračním souboru nastavit konstantu INSTALL tak, aby se již kontrola databáze neprováděla a tím se ušetřil databázový dotaz. Po kontrole instalace již nic nebrání spuštění nejdůležitější třídy Router. Ta má na starosti zpracování požadavku a volání příslušných kontrolérů. Pamatovák obsahuje také předky pro všechny budoucí modely a kontroléry. Jedná se o třídy Controller a Model. Ty obsahují základní metody pro manipulaci s databází i podpůrné metody pro kontrolu oprávnění. Třída Cache slouží pro obsluhu zrychleného vyřizování požadavků. Vzhledem k povaze dat lze u některých požadavků uložit jejich výsledek, který bude použit bez nutnosti provádět výpočty znovu u dalšího požadavku. Třída Response obsahuje metody pro nastavení odpovědi – HTTP kód stavu, kódování atd. Třída tools je souborem různorodých nástrojů a pomůcek, které se používají napříč celým modulem. Ošetřování chybových stavů V Pamatováku může dojít na různých místech k chybě. Aby se uživatel API dověděl co udělal špatně, je na místě chyby vytvořena instance výjimky Exception a předána volající metodě. Pokud je to nestandardní chyba, se kterou si volající metoda sama neporadí, dostane se tento objekt až do instance třídy Pamatovak, která řídí celý běh aplikace. Na této úrovni Pamatovák odešle odpověď s vyplněným polem error, ve kterém se nachází chybové hlášení výjimky a s HTTP kódem 500. Typické použití Pokud chceme pomocí API obsluhovat entitu Document, stačí pro ni vytvořit model a kontrolér. Model bude obsahovat metody pro manipulaci s tabulkou v databázi. Pro základní operace INSERT, UPDATE, SELECT a DELETE není třeba vytvářet žádné metody – obsahuje je předek Model. Model musí povinně obsahovat položky table_name a pk_name. Ty uchovávají název tabulky a primárního klíče. Všechny veřejné metody kontroléru lze volat pomocí API. Není třeba je přidávat do žádného konfiguračního souboru, Router sám rozhodne o jejich správném zavolání. Pokud je z akce kontroléru volána metoda protect, je v požadavku nutné uvést položku secret, která obsahuje heslo vygenerované po instalaci. Pokud požadavek toto heslo neobsahuje, odpověď Pamatováka má HTTP kód 403 – tedy nepovolený přístup.
14
Proces uložení entity Document Data o dokumentu jsou Pamatováku předána tak, jak se nacházejí na stránkách systému TED, jen rozdělena na jednotlivé položky. Dle kódů uvedených u každé položky, případně pomocí popisu, jsou v databázi nalezeny cizí klíče tabulky category a vloženy na jejich místa. Výjimkou je určení místa a CPV kódů. Místa jsou uložena ve zválštní tabulce jako dvojice město a země. Dokument tedy obsahuje cizí klíč do této tabulky. Dokument může obsahovat více CPV kódů, stejně tak jeden CPV kód může náležet více dokumentům. Tento vztah zajišťuje vazební tabulka cpv_map, která uchovává dvojici identifikátorů – dokumentu a CPV kódu. Automatické spouštění odpovídajících metod kontrolérů a modelů Při zpracování požadavku je potřeba vždy právě jeden kontrolér – ten, který obsluhuje požadavek. Proto se při spouštění Pamatováka neimportují všechny kontroléry, ale pouze jeden. U modelů toto pravidlo neplatí, jeden kontrolér jich může využívat více. Jak už bylo zmíněno, všechny kontroléry a modely dodržují konvence pojmenování. Díky tomu lze načíst odpovídající soubor s kontrolérem tak, že se upraví název kontroléru z požadavku, aby měl první písmeno velké, je připojen řetězec Controller a přípona. Po ověření existence souboru pomocí funkce file_exists je importován soubor. V dalším kroku je zkontrolována existence třídy kontroléru funkcí class_exists, existence metody pomocí method_exists. Po ověření je zavolána metoda akce a řízení Pamatováka předáno jí. Všechny modely jsou načteny pro možné použití v kontroléru. Pomocí funkce glob je získán seznam všech souborů v adresáři models odpovídající regulárnímu výrazu „*.php“. Každá položka výsledku je importována do programu. Tímto jsou načteny všechny modely v adresáři, instance jednotlivých tříd si vytváří každý kontrolér sám. Ochrana databáze proti SQL Injection Útok SQL Injection využívá provedení dotazů s uživatelským vstupem (například ID získávané položky) bez ošetření speciálních znaků. Pokud je systém náchylný na tento typ útoku, může útočník manipulovat se všemi daty v databázi. Pamatovák se proti tomuto útoku brání ošetřením vstupu pomocí metody prepare, která je součástí objektu PDO pro přístup do databáze. Funkci prepare je předán jako parametr SQL dotaz, kdy místo všech uživatelských vstupů jsou vloženy značky. Při provedení dotazu metodou execute poté PDO ošetří uživatelské parametry a vloží již bezpečné hodnoty na místa jejich značek. 15
Vytváření akcí pro získání statistických dat Akce, které poskytují Prezentéru data pro zobrazení v grafech a na mapách, jsou přítomny v jednom kontroléru s názvem StatisticsController. Všechny mají podobnou strukturu. Jejich povinností je zpracovat vstupní parametry, pomocí odpovídajícího modelu získat data, převést je na strukturu akceptovanou grafy a odeslat je Prezentéru. Modely dodávají data jako pole asociativních polí. Tato struktura ovšem není podporována Google API pro zobrazení, proto je nutné data konvertovat do podoby pole jednoduchých polí. Tato konverze se provádí následovně (proměnná $result_data obsahuje data z modelu, $api_data je prázdné pole): foreach($result_data as $c){ $api_data[] = array($c['description'], (int)$c['count']); } Z toho vyplývá, že se po načtení dat z databáze musí celý výsledek projít podruhé. Při větším počtu záznamů je toto velmi náročné a zbytečné. V další verzi aplikace bude tento krok optimalizován – buď bude model dodávat data přímo v požadovaném formátu, nebo bude konverze provedena na straně klienta. Agregace dat pro teplotní mapu Teplotní mapa, jeden z přehledových prvků, očekává souřadnice místa, které má zobrazit, a jeho váhu. Tato data mohou být dále omezena dle jednotlivých kategorií. Z podstaty uložení dat v Pamatováku vyplývá, že dotaz pro získání dat by mohl trvat při větším počtu záznamů neúměrně dlouho [23]. Proto Pamatovák obsahuje tabulku heatmap_cache, ve které jsou data již agregována. Tabulka obsahuje informace o zeměpisné šířce a výšce, váhu (počet dokumentů v tomto místě) a příslušnost ke kategorii. Pokud se jedná o místa bez rozdělení na ktegorie, má toto pole hodnotu NULL. Po stáhnutí nových dokumentů je nutno tuto agregační tabulku vypočítat znovu. Tato funkce je dostupná z administračního rozhraní jménem Dozorce.
16
4.2
Seznam kategorií dokumentů a informací o zemích
Pro získání seznamu kategorií byl vytvořen samostatný nástroj s názvem TedCategories. Ten pomocí dotazů na systém TED získá všechny kategorie, dle kterých jsou rozděleny dokumenty. Na stránce vyhledávací funkce systému TED je dostupný formulář pro nastavení kritérií výběru dokumentů. Tato kritéria nejsou kvůli velikosti obsažena přímo ve stránce, ale jsou dynamicky načítána pomocí JSON API. Prvním krokem při stáhnutí jednoho stromu kategorií je načtení kořenového prvku. Ten je stažen jako JSON dokument a obsahuje ID následovníků. Pro každého z potomků je zavolána funkce pro zpracování znovu, je tedy použita rekurze. Po zpracování každé odpovědi jsou zjištěné informace uloženy do databáze. Odpověď serveru obsahuje popisky kategorií v takovém jazyce, jaký je nastaven pomocí cookies. Pro další jazyky je potřeba spustit procházení kategorií znovu s upravenou metodou pro ukládání informací. Pokud je již jednou seznam stažen, je potřeba záznamy pouze aktualizovat, nepřidávat další. Uložení stromu kategorií v databázi Pro uložení stromových dat do relační databáze existuje několik technik, pro potřeby tohoto projektu byla zvolena implementačně nejjednodušší metoda – ukládání jednotlivých uzlů s odkazem na předka. Vzhledem k neměnnosti dat bylo možné ke každému prvku uložit předpočítané informace o hloubce zanoření a pořadí. Toho využívají některé statistické dotazy, které získávájí například všechny kategorie s určitou hloubkou. Zjednodušení zjišťování kategorií dokumentů pro statistiky Dokumenty jsou kategorizovány ve většině případů velmi konkrétně – položkami na osmé a nižší úrovni stromu kategorií. Aby byly statistické dotazy co nejjednodušší, jsou uloženy ve vazební tabulce cpv_map také informace o první a druhé úrovni kategorie dokumentu. Díky tomuto postupu nemusí každý statistický požadavek procházet strom kategorií a zjišťovat odpovídající kategorii na nejvyšších úrovních. Informace o zemích Data o zemích (populace, rozloha) jsou získána pomocí nástroje GetCountries [8]. Tento nástroj pravidelně aktualizuje data o zemích ze serveru GeoNames [9] a následně je poskytuje v různých,
17
strojově čitelných formátech. Pro tento projekt byl použit JSON formát – byl vygenerován seznam všech zemí s údaji o populaci a rozloze. Následně vložen přímo do skriptu countries.php (ve složce kitchen s jednorázovými skripty) a funkcí json_decode převeden na pole asociativních polí. Poté byly v cyklu do databáze uloženy všechny informace k záznamům o zemích v tabulce category.
4.3
Fronta
Pro realizaci fronty je využit Pamatovák. Seznam požadavků je uložen v tabulce queue. Každý záznam obsahuje informace o úkolu a příznaky taken a done. Při vložení nového úkolu jsou oba příznaky nastaveny na hodnotu NULL, po zabrání úkolu Otrokem je nastaven taken na aktuální datum a čas, stejně jako po splnění úkolu i done. Problém přístupu ke frontě více Otroky najednou je vyřešen pomocí příkazů LOCK a UNLOCK tabulky queue. Tabulka se uzavírá pouze při vybírání požadavků z vrcholu fronty, neboť je potřeba, aby se dotazy SELECT a UPDATE chovaly jako jedna transakce. Po splnění nejsou úkoly mazány z databáze. Fronta je uchovává pro kontrolu duplicit úkolů. Unikátním prvkem je URL adresa dokumentu, který má Otrok stáhnout.
4.4
Plánovač
Modul Plánovač se skládá ze tří tříd. První je HttpClient, která poskytuje jednoduché rozhraní pro zasílání HTTP požadavků – většinou pro komunikaci s Pamatovákem. Druhou třídou je tools, která obsahuje pomocné nástroje. Tyto třídy jsou společné pro Otroka i Plánovače. Získání seznamu dokumentů Pro získání seznamu dokumentů je nutné navštívit stránku s funkcí vyhledávání v systému TED, nastavit správné parametry a procházet postupně jednu stránku za druhou. Systém TED ovšem funguje poměrně složitým způsobem, kdy si některé údaje o návštěvníkovi ukládá pomocí SESSION, jiné v cookies a další dočasné identifikátory přímo ve zdrojovém kódu stránky. Pouze pomocí přístupu přes nástroj cURL [18] nebylo možné simulovat přesně podmínky tak, aby se zobrazila požadovaná data. Proto byl zvolen odlišný postup pomocí nástroje Selenium. Tímto způsobem bylo docíleno stavu, kdy se skript jeví systému TED jako normální uživatel a vyhledávání funguje tak, jak má.
18
Po získání seznamu dokumentů je tento odeslán pomocí jednoho požadavku Pamatováku, který je vloží do fronty. Struktura Plánovač je jedna třída, která řídí celý proces získání seznamu odkazů na dokumenty. Po spuštění skriptu se provede úvodní nastavení vyhledávacích kritérií – například interval dat, typ dokumentu nebo směr procházení (sestupně, vzestupně). Jak již bylo zmíněno, po přístupu na stránku s výsledkem se získají jednotlivé URL adresy, které se následně odešlou Pamatováku do fronty. Načítání konfiguračních souborů Při
inicializaci
Plánovače
očekává
konstruktor
globálně
dostupné
pole
se
jménem
$_PlanovacConfig. Toto pole je uloženo v souboru config.php v kořenovém adresáři modulu, který je načítán v souboru index.php. Toto pole obsahuje uživatelsky definované volby. Pro zjednodušení použitelnosti nemusí toto pole obsahovat žádné položky v případě, že mají být nastaveny výchozí hodnoty. Aby se při spuštění Plánovače nemusela provádět sada složitých podmínek kontrolujících přítomnost jednotlivých položek nastavení a omezila se možnost chyby, je v konstruktoru definováno pole $default_config. Pomocí funkce array_merge je toto pole sloučeno s polem $_PlanovacConfig a tím zajištěna přítomnost všech nutných položek nastavení. Tento způsob načítání nastavení je použit i u Otroka a Prezentéra. Optimalizace stahování seznamu odkazů Možnou optimalizací Plánovače by mohlo být použití nástroje PhantomJS místo Selenia. Funguje obdobně, ale ke svému běhu nevyžaduje kompletní prohlížeč, nýbrž pouze vykreslovací jádro – v tomto případě WebKit. Stinnou stránkou použití tohoto nástroje je jeho závislost na konkrétním jazyku, JavaScriptu. Je tedy otázkou, zda technologicky tříštit projekt, či zkrátit proces stahování nových dat řádově o jednotky minut při týdenní aktualizaci. Ukázka použití Selenia Po spuštění Selenium WebDriver, serveru distribuovaném jako JAR soubor, je potřeba pro komunikaci knihovna pro cílový jazyk – PHP. Pro testovací účely jednu takovou vytvořil Facebook [17], k Plánovači je připojena pomocí Composeru. Prvním krokem je vytvoření ovladače, tedy objektu, který komunikuje se Seleniem: $driver = RemoteWebDriver::create( $host, array(WebDriverCapabilityType::BROWSER_NAME => $browser) 19
); Proměnná $host obsahuje IP adresu a port, na kterém poslouchá Selenium, proměnná $browser pak název prohlížeče, který bude použit. V případě Plánovače to je firefox. Druhým krokem je otevření stránky. K tomu slouží metoda get ovladače. $driver->get('http://ted.europa.eu/TED/'); Dále již lze pracovat se stránkou stejně jako v prohlížeči. Stačí najít prvek na stránce a spustit jeho akci. Například kliknutí na tlačítko s titulkem „Access to the complete search form“ se provede takto: $driver->findElement(WebDriverBy::xpath( "//a[@title='Access to the complete search form']") )->click(); Pro nalezení prvku lze použít jeho identifikátor, pořadí, anebo, jako v tomto případě, Xpath identifikátor. Metody ovladače se dají dle libosti řetězit, proto můžeme click aplikovat přímo na výběr prvku a nemusíme výsledek findElement ukládat do proměnné. HttpClient HttpClient je třída obsahující často používané způsoby zasílání požadavků. Obsahuje stejný způsob načítání nastavení jako ostatní moduly a ke svému běhu potřebuje rozšíření cURL. Toto rozšíření je bežně přítomno na všech hostingových službách, nejedná se o nestandardní knihovnu. Při vytváření instance tohoto klienta očekává konstruktor URL adresu. Po vytvoření lze volat různé metody v závislosti na tom, jaký typ požadavku je potřeba. Po ruce jsou metody pro GET požadavek, POST požadavek, dále obě varianty směrované přes TOR proxy server [12]. Volitelným parametrem pro všechny funkce je zadání cookies jako asociativní pole.
4.5
Otrok
Třída Otrok obsahuje hlavní metodu, která řídí pracovní tok skriptu. Nejprve se pomocí API dotáže Pamatováka na nový úkol. Pokud žádný v databázi není, vyčká dvě sekundy a zeptá se znovu. Pokud dostane úkol, přistoupí na zadanou URL adresu a získá z ní informace o dokumentu. Data se ze stránky získávají pomocí Xpath identifikátoru. K tomu slouží nástroj PHP Simple HTML DOM Parser – k projektu je přiložen pomocí balíčkovacího systému Composer. Získaná data odešle společně s identifikačním číslem úkolu zpět Pamatováku, ten se postará o zpracování dat a uložení do databáze.
20
Získání dat ze stránky pomocí PHP Simple HTML DOM Parser Pro získání dat ze stránky je prvním krokem vytvoření stromu prvků z HTML kódu: $tree = str_get_html($page); Funkce str_get_html vytvoří instanci objektu simple_html_dom, která reprezentuje celý strom HTML dokumentu a poskytuje funkce pro manipulaci s prvky. Jednou z takových funkcí je i find, jejíž parametr je Xpath identifikátor prvku. $div = $tree->find('div[id=docContent]', 0); Nyní proměnná obsahuje prvek div s ID docContent. Pomocí opětovného volání funkce find lze získat seznam řádků tabulky obsažené v prvku div: $rows = $div->find('tr'); Nad tímto seznamem lze iterovat pomocí konstrukce foreach a dále pracovat s obsahem řádků jako běžným řetězcem: foreach($rows as $r){ $string = $r->plaintext; } Předčasné ukončení stahování Pokud je potřeba z nějakého důvodu ukončit běh Otroka, není vhodné to udělat pomocí ukončení procesu, může totiž dojít k nekonzistenci dat (například označení úkolu ve frontě jako taken a nedodání odpovídajících dat). Pro předčasné ukončení obsahuje Otrok pojistku. Ta po zpracování 10 úkolů od Pamatováka zkontroluje soubor break.txt. Pokud tento soubor obsahuje řetězec „BREAK“, Otrok se řádně ukončí. Tento mechanismus slouží také pro hromadné ukončování Otroků, i na více strojích. Pomocí jednoduché skriptu lze nahrát break.txt na více míst a tím efektivně ukončit veškeré stahování. Blokování přístupu k systému TED Pro stažení každého dokumentu je potřeba provést jeden dotaz na cílový systém TED. Při 100 000 dokumentech je tento počet požadavků poněkud nápadný – správci serveru TED tedy zablokovali IP adresu Otroka. Tento problém je vyřešen použitím přístupu pomocí sítě TOR. Otrok obsahuje v konfiguračním souboru možnost volby mezi přímým požadavkem na cílový server a požadavkem přes proxy server. Po zablokování i nové adresy si stačí v Dozorci zvolit novou identitu. Pro správné fungování stahování přes TOR je potřeba mít funkční proxy server, který podporuje přípojení do této sítě. Instalace takového proxy serveru je triviální, funguje spolehlivě s výchozím nastavením. Je důležité v souborech s nastavením modulů Otrok i Dozorce správně 21
nastavit porty pro připojení k proxy serveru. Otrok očekává IP adresu a port pro odesílání požadavků, Dozorce IP adresu a port pro správu TOR proxy serveru – kvůli správě identit. Sledování průběhu stahování Pro sledování činnosti jak Otroka, tak Plánovače, obsahuje každý z nich metodu log, která zapisuje informace o prováděných úkonech. Záznamy se zapisují po jednom do souboru – není použit hromadný zápis kvůli situaci, kdy je potřeba prozkoumat náhlý pád modulu. Každý záznam obsahuje informaci o datu, času a krátkou zprávu. Pro každé spuštění modulu je vytvořen samostatný soubor se záznamy o činnosti, název obsahuje časový údaj o spuštění. Toto opatření je zavedeno kvůli studiu průběhu stahování a statistik. V pozdějších verzích bude možné implementovat pro Dozorce přesnou statistiku chování Otroků a Plánovače a na základě těchto dat optimalizovat chování modulů. Omezení dlouho běžících skriptů Jazyk PHP a jeho správa paměti nebyly původně navrženy pro dlouhou dobu běhu skriptu [21]. Proto je nutné na tuto skutečnost myslet při vývoji dlouho běžícího skriptu, kterým Otrok je. Prvním omezením je doba běhu skriptu, která bývá většinou 30 sekund. Tento limit lze změnit buď nastavením položky v konfiguračním souboru php.ini nebo přímo ve skriptu pomocí funkce set_time_limit. Plánovač a Otrok si nastavují tuto hodnotu na -1, což znamená, že žádný časový limit nemají. Dále je nutné mít na paměti, že PHP neuvolňuje paměť automaticky v době běhu skriptu. Je dobrou praxí uvolňovat nepotřebné velké datové struktury explicitně funkcí unset.
22
4.6
Průběh stahování
Stahování dat o nově vypsaných veřejných zakázkách má několik kroků. Prvním z nich je stažení seznamu dokumentů ze stránky vyhledávání systému TED. O tuto úlohu se stará modul Plánovač, který odešle Pamatováku seznam zjištěných URL adres. Ty jsou uloženy ve frontě, odkud si je ve druhém kroku vyzvedne jednu po druhé Otrok a stáhne informace obsažené na dané adrese. Následně je odešle zpět Pamatováku, který je uloží do databáze. Celý průběh stáhnutí dokumentu i s označováním dokončených úkolu ve frontě je zobrazen na následujícím obrázku:
Obrázek 4.1: Diagram průběhu stahování Po stáhnutí dokumentů je potřeba pomocí Dozorce vygenerovat doplňující informace o dokumentech pro statistiky. Jedná se především o zjištění odpovídajících CPV kódů pro první a druhou úroveň kategorie a získání GPS souřadnic pro nová města. Archivace neaktuálních dokumentů V současné verzi aplikace zobrazuje statistiky pro běžící veřejné zakázky – ty, jejichž datum ukončení je pozdější, než aktuální datum, a zakázky, které nemají zadané žádné datum ukončení. Aby se zakázky nehromadily v pracovní tabulce document a cpv_map a tím nezpomalovaly provádění dotazů, je nutné je nějakým způsobem archivovat. Pro jednoduchost byly použity tabulky document_archive a cpv_map_archive, do nichž se neaktuální dokumenty přesouvají. Tento údržbový krok lze provést pomocí připravené funkce v Dozorci.
23
Neaktuální dokumenty jsou záměrně uchovávány pro další rozvoj projektu. S dokumenty aktuálními v různých časových intervalech se nabízí nové statistiky a přehledy, například vývoj počtu zakázek v čase.
4.7
Dozorce
Pro sledování procesu stahování a údržbové operace s frontou byl vytvořen nástroj Dozorce. Jedná se o aplikaci sestávající z jedné třídy, která obsahuje metody například pro smazání chybných úkolů, přehled počtu stažených dokumentů, získání nové identity pro TOR nebo doplnění GPS souřadnic jednotlivých míst. Tuto aplikaci je vhodné umístit jak na server s Pamatovákem, tak na počítač, kde se spouští Otrok. Pro každý modul nabízí rozdílné funkce. Autentizace uživatele je pomocí zadání hesla z Pamatováka. Doplnění GPS souřadnic jednotlivých míst Pro zjištění GPS souřadnic jednotlivých míst je použita služba Geocoding [20] společnosti Google. Funguje jako API, v požadavku je uvedena adresa – dvojice město a země, v odpovědi jsou poté uvedeny souřadnice a další informace ve formátu JSON. Google tuto službu poskytuje zdarma, ale s omezením. Limitem je 2 500 požadavků na souřadnice během 24 hodin. Po úvodním stáhnutí 100 000 dokumentů bylo potřeba zjistit souřadnice téměř 10 000 různých míst, většinou měst. Limit počtu požadavků byl vyřešen použitím sítě TOR stejně jako v případě omezeného přístupu k systému TED u Otroka. Autentizace Dozorce Pamatovákem Jak již bylo zmíněno, Dozorce používá pro autentizaci uživatele heslo, které je uloženo v tabulce system v databázi Pamatováka. Pro co nejjednodušší použití je v Pamatováku přítomen kontrolér LoginController, který má pouze jedinou akci – login. Tato akce obsahuje volání metody protect, která zajistí ověření uživatele. Pokud požadavek obsahoval správné heslo, odešle se Dozorci odpověď s HTTP stavovým kódem 200 a zprávou o úspěšnosti přihlášení.
24
4.8
Použití architektury pro stahování dat také z jiných serverů
Trojice modulů Pamatovák, Plánovač a Otrok se dá jednoduchým způsobem upravit pro stahování i jiných dat, než jen ze systému TED. Pro takovou úpravu stačí navrhnout nové databázové schéma pro daná data, upravit modely Pamatováka a skripty Otroka a Plánovače pro získání dat. Celá architektura se dá takto upravit díky velmi častému konceptu webových informačních systémů. Ten spočívá v použití vyhledávacího formuláře, pomocí kterého se dá chronologicky zobrazit seznam všech požadovaných položek a následně je stáhnout. Získání dat z webové stránky také zjednodušuje dodržování zásad přístupnosti webových stránek. Správná struktura HTML kódu a pojmenování prvků velmi usnadňuje nalezení chtěných dat.
4.9
Prezentace dat
O prezentaci dat se stará modul jménem Prezentér. O logiku aplikace pak třída Prezenter, která řídí spouštění jednotlivých komponent. Třída Categories poskytuje metody pro získání seznamu stránek k zobrazení v menu, třída Snippets zajišťuje sestavení interaktivních formulářů. V souboru Language.php jsou překladové slovníky jazyků a funkce pro získání správného textu na základě zvoleného jazyka a kotvy. Kotva je jedinečný identifikátor textu ve slovníku jazyka, který se umístí v aplikaci a místo ní je doplněn patřičný text. Správa stránek s grafy Každá stránka aplikace, která se nachází v menu a je přístupná návštěvníkovi, je reprezentována souborem ve složce pages. Pro pojmenování těchto souborů platí pravidlo – první částí je číslo, které udává pořadí zobrazení, dále je uvedena kategorie stránky a nakonec překladová kotva reprezentující název stránky. Části jsou oddělené pomlčkou a místo mezer použito podtržítko. Výhodou tohoto unifikovaného názvosloví souborů je jednoduchost zobrazení a načítání správné stránky při přístupu uživatele. Aplikace nemusí uchovávat žádná data o stránce, vše potřebné je obsaženo v názvu souboru. Třídě Categories tedy stačí seznam souborů ve složce pages k vytvoření navigace. Přidání nové stránky spočívá jen ve vytvoření nového souboru. Vytváření grafů a formulářů pro jednotlivé statistiky JavaScript soubor forms-api.js obsahuje sadu objektů pro rychlé a jednoduché používání grafů a map. Tyto objekty mají připravené funkce pro načítání dat z Pamatováka a jejich aktualizaci 25
v závislosti na kritériích nastavených ve formuláři. Pro použití stačí typicky vytvořit objekt požadovaného grafu a předat mu identifikátor prvku grafu (připravený div element), identifikátor formuláře, název kontroléru a akci Pamatováka. Takto připravený objekt reaguje na změnu formuláře, pokud k ní dojde, získá od Pamatováka nová data a zobrazí je. Vytváření formulářů Jak již bylo zmíněno, pro vytváření formulářů slouží třída Snippets. Ta obsahuje jednotlivé komponenty, které mohou být použity ve formulářích, ve všech podporovaných jazykových mutacích. Pro vytvoření formuláře stačí zavolat metodu a předat jí seznam kritérií, která budou ve formuláři. Napříč celým Prezentérem i Pamatovákem je použito jednotné názvosloví právě kvůli jednoduchosti a znovupoužitelnosti. Vytváření komponent pro fomuláře Díky tomu, že se kategorie v čase nemění, je možné předem vygenerovat jednotlivé komponenty pro použití ve formulářích. Ve složce kitchen jsou skripty pojmenované dle komponent. Každý ze skriptů načte data o požadované kategorii z databáze a vypíše připravenou komponentu ve všech jazykových verzích. Takto vygenerované komponenty jsou uloženy ve třídě Snippets jako řetězce pro přímé použití ve formulářích. Možné zlepšení pro budoucí verze je generování komponent s ukládáním do souborů tak, aby je mohla třída Snippets načítat automaticky a nebyl potřeba zásah programátora. Zejména bude tato funkcionalita užitečná při rozšiřování jazykových verzí projektu. Nastavení reakcí na změny formulářů Nastavení reakcí na změny formulářů se provádí přímo v jednotlivých souborech s obsahem stránky, ihned po vytvoření objektu zobrazovaného prvku. Je využita metoda change knihovny jQuery, aby nebylo nutné zasahovat do kódů formulářů. Nastavení reakcí vypadá takto (příklad je ze stránky s výsečovým grafem zobrazujícím podíly jednotlivých zemí na celkovém počtu veřejných zakázek): $("#by-countries-form").change(function(){ piechart_object.updateData("by-countries-form"); }); by-countries-form je identifikátor fomuláře, proměnná
piechart_object
obsahuje instanci objektu výsečového grafu. Metoda updateData zjistí hodnoty formuláře, aktuální nastavení jazyka aplikace a odešle požadavek s těmito parametry Pamatováku. Jakmile dojde odpověď, jsou grafu předána nová data (proměnná response obsahuje celou odpověď): data = google.visualization.arrayToDataTable(response.data); 26
a graf je vykreslen znovu (proměnná chart obsahuje instanci grafu od Google API, proměnná options nastavení grafu): chart.draw(data, options); Metoda
updateData
si
uchovává
poslední
provedený
požadavek
v proměnné
last_request. Je to kvůli situaci, kdy uživatel provede nový požadavek na data (změní formulář), zatímco původní požadavek ještě nebyl dokončen. Tato funkce je realizována následovně: if(last_request && last_request.readystate != 4){ last_request.abort(); } Podmínka zkoumá stav minulého požadavku a pokud nebyl dokončen, zruší jej. Optimalizace zobrazení teplotní mapy V původním návrhu poskytování dat Pamatovákem pro vykreslení teplotní mapy měla data tolik prvků, kolik existovalo dokumentů. Počet dokumentů se tedy rovnal počtu míst, která se měla zobrazit na mapě. Vzhledem k počtu dokumentů bylo od tohoto způsobu upuštěno a byla provedena optimalizace. Výběr dat z databáze nyní probíhá dle míst s tím, že u každého místa je uveden počet dokumentů vztahujících se k místu. Tato hodnota je použita jako váha při vykreslování mapy. Je nutné, jak již bylo popsáno výše, vytvořit tabulku s predpočítanými hodnotami. Tato optimalizace byla provedena kvůli limitu počtu zobrazených bodů, který se v nejrozšířenějších prohlížečích pohybuje kolem hodnoty 15 000. Výpočet histogramu trvání zakázky Data pro histogram trvání zakázky nejsou vytvářena na straně serveru, ale v prohlížeči uživatele. Celý výpočet obstarává objekt Histogram, který je součástí Google API poskytující i ostatní grafy a mapy. Tento způsob byl zvolen pro redukci zátěže serveru [14]. Řešení problému Same Origin Policy Pro zajištění vyšší bezpečnosti uživatelů prohlížečů bylo zaveden opatření jménem Same Origin Policy [19]. Jedná se o zákaz provádění požadavků pomocí AJAXu a podobných technologií na jinou doménu, než na které je provozována webová stránka. Toto omezení se v restriktivnějších prohlížečích vztahuje i na subdomény, což je případ použití Pamatováka. Ten funguje na subdoméně pamatovak.tenderstats.eu, Prezentér ovšem na tenderstats.eu. Tento problém je řešitelný buď na straně klienta, nebo serveru. Na straně klienta lze v některých prohlížečích použít pro AJAX požadavek alternativní objekt určen přímo k tomuto účelu. 27
Vzhledem k tomu, že tuto praktiku lze aplikovat pouze na Internet Explorer, bylo nakonec zvoleno systémové řešení na straně serveru. Technologie Cross Resource Sharing byla zavedena a je podporována prohlížeči právě pro sdílení prostředků (provádění požadavků mimo doménu stránky) mezi více systémy. Pro její použití stačí v hlavičce odpovědi na takový požadavek uvést pole Access-Control-Allow-Origin. Vzhled uživatelského prostředí Pro úpravu vzhledu prostředí je použita CSS/JS knihovna Twitter Bootstrap [15]. Obsahuje pravidla pro vzhled formulářů, tlačítek a jiných prvků stejně jako mřížkový systém pro pozicování prvků. Těchto vlastností je využito co nejvíce pro urychlení vývoje a zajištění uživatelského komfortu. Volba jazyka aplikace Při prvním příchodu uživatele je prostředí aplikace nastaveno na český jazyk. V pravém horním rohu, na liště navigace, je možné změnit jazyk aplikace, v tuto chvíli je podporována mimo češtiny angličtina. Pokud uživatel změní jazyk, uloží se informace o aktuálním jazyce do souboru cookies, s platností třiceti dnů. Tato technika má dvě hlavní výhody. První z nich je zjištění nastavení jazyka při opakované návštěvě aplikace v průběhu delšího časového období, uživatel tak nemusí volit jazyk znovu. Druhou výhodou je čistota URL – Prezentér si nemusí předávat tuto informaci v adrese, ale zjistí ji právě pomocí cookies.
4.10
Testování architektury a komponent
Vývoj a testování interaktivních formulářů pro grafy a teplotní mapy a architektury probíhal na projektu StatistikaNehod.cz [16]. Díky tomuto projektu bylo možné hned na začátku odhalit nedostatky v návrhu aplikace a zároveň přinesl nápady na vylepšení funkčnosti a zpříjemnění uživatelského rozhraní.
28
5
Další vývoj projektu
Tato kapitola se zabývá možnostmi dalšího rozvoje, projekt bude udržován a dále vyvíjen i po odevzdání bakalářské práce. Diskuze výsledků s odborníky Výsledky, které prezentuje aplikace se i nezainteresovanému návštěvníkovi jeví jako velmi zajímavé a místy překvapivé. Ovšem před prohlášením výsledků správnými a přesnými by bylo dobré je prodiskutovat s odborníkem na veřejné zakázky. Výsledek tohoto sezení by mohl být uveřejněn přímo na stránkách projektu. Nové statistiky a přehledy Nejen z diskuze s odborníkem na veřejné zakázky, ale i z návrhů široké veřejnosti by mohly vzniknout statistiky a přehledy, které v tuto chvíli v projektu nejsou. Jak bylo popsáno v kapitole o Prezentéru, vytváření nových statistik a map je jednoduché, proto nic nebrání rozšíření portfolia metrik. Nápověda široké veřejnosti Pokud má být projekt dobře dostupný i pro širokou veřejnost, bylo by vhodné implementovat interaktivní funkci slovníku pojmů. Tento slovník by mohl obsahovat například vysvětlení rozdílu mezi řízením a nařízením zakázky, informace o různých typech dokumentů a podobně. Tento slovník může fungovat jako našeptávač, kdy se při najetí myší nad specifický výraz zobrazí vysvětlení s příkladem.
29
6
Závěr
Cílem této bakalářské práce bylo představit odborné i široké veřejnosti různorodé statistiky a přehledy o veřejných zakázkách Evropské unie formou webové aplikace s interaktivními grafy a mapami. K dosažení vytyčeného cíle bylo potřeba nejprve získat potřebná data ze systému TED. Za tímto účelem byla vytvořena architektura několika modulů pro automatizované stahování a uložení dat. Celý systém je provozován na běžně dostupném hostingu tak, aby demonstroval jednoduchost a nenáročnost získávání, uložení a prezentaci i větších dat, která nejsou původně dostupná ve strojově čitelném formátu. Výsledná aplikace má potenciál přiblížit poměry, panující v oblasti veřejných zakázek. Nabízí jednoduchý nástroj pro zkoumání trendů ve vypisovaných zakázkách i specialistům z jiných oborů, kteří by jinak tyto statistiky nebyli schopni vytvořit. Další rozvoj projektu je popsán v příslušné kapitole. Tento vývoj není pouze hypotetický, nýbrž reálně plánovaný v nejbližší budoucnosti s ohledem na časové možnosti autora.
30
Literatura [1] TED Tenders Electronic Daily [online]. 2014 [cit. 2014-05-20]. Dostupné z: http://ted.europa.eu/TED/main/HomePage.do. [2] THE PHP GROUP. PHP: Hypertext Preprocessor [online]. 2014 [cit. 2014-05-20]. Dostupné z: http://php.net/. [3] ORACLE. MySQL :: The world's most popular open source database [online]. 2014 [cit. 2014-05-20]. Dostupné z: http://www.mysql.com/. [4] THE JQUERY FOUNDATION. jQuery [online]. 2014 [cit. 2014-05-20]. Dostupné z: http://jquery.com/. [5] GOOGLE. Google Charts [online]. 2014 [cit. 2014-05-20]. Dostupné z: https://developers.google.com/chart/. [6]
Composer [online]. 2014 [cit. 2014-05-20]. Dostupné z: https://getcomposer.org/.
[7] Selenium - Web Browser Automation [online]. 2014 [cit. 2014-05-20] . Dostupné z: http://docs.seleniumhq.org/. [8] Get countries in MySQL/XML format [online]. 2014 [cit. 2014-05-20]. Dostupné z: http://peric.github.io/GetCountries/. [9]
GeoNames [online]. 2014 [cit. 2014-05-20]. Dostupné z: http://www.geonames.org/.
[10] PHP Simple HTML DOM Parser [online]. 2014 [cit. 2014-05-20]. Dostupné z: http://simplehtmldom.sourceforge.net/. [11] BERNARD, Borek. Úvod do architektury MVC. Zdroják [online]. 2009 [cit. 2014-05-20]. Dostupné z: http://www.zdrojak.cz/clanky/uvod-do-architektury-mvc/ [12] Tor Project: Anonymity Online [online]. 2014 [cit. 2014-05-20]. Dostupné z: https://www.torproject.org/. [13] REFSNES DATA. XPath Tutorial [online]. 2014 [cit. 2014-05-20]. Dostupné z: http://www.w3schools.com/Xpath/. [14] KUČERA, Petr. Vztah klient-server u webových aplikací. Brno, 2011. Bakalářská práce. Vysoké učení technické v Brně. Fakulta informačních technologií. [15]
TWITTER, Bootstrap [online]. 2014 [cit. 2014-05-20]. Dostupné z: http://getbootstrap.com/.
[16] KURKA, Vojtěch. Statistika nehod na českých dálnicích [online]. 2014 [cit. 2014-05-20]. Dostupné z: http://statistikanehod.cz/. [17] FACEBOOK, php-webdriver [online]. 2014 [cit. 2014-05-20]. Dostupné z: https://github.com/facebook/php-webdriver. [18]
curl and libcurl [online]. 2014 [cit. 2014-05-20]. Dostupné z: http://curl.haxx.se/. 31
[19] MOZILLA. Same-origin policy - Web security | MDN [online]. 2014 [cit. 2014-05-20]. Dostupné z: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy. [20] GOOGLE. The Google Geocoding API - Google Maps API Web Services [online]. 2014 [cit. 2014-05-20]. Dostupné z: https://developers.google.com/maps/documentation/geocoding/. [21] VRÁNA, Jakub. 1001 tipů a triků pro PHP. Brno: Computer Press, a.s., 2010. ISBN 978-80251-2940-1. [22] RESIG, John. JavaScript a Ajax: moderní programování webových aplikací. Vyd. 1. Překlad Ondřej Baše, Ondřej Žižka. Brno: Computer Press, 2007, 360 s. ISBN 978-80-251-1824-5. [23] RESIG, John. MySQL profesionálně: optimalizace pro vysoký výkon. Vyd. 1. Překlad Ondřej Baše, Ondřej Žižka. Brno: Zoner Press, 2009, 712 s. Encyklopedie webdesignera. ISBN 978-807413-035-9.
32