
[{"content":"","date":"11. 5. 2015","externalUrl":null,"permalink":"/tags/c%23/","section":"Tags","summary":"","title":"C#","type":"tags"},{"content":"","date":"11. 5. 2015","externalUrl":null,"permalink":"/clanky/","section":"Články","summary":"","title":"Články","type":"clanky"},{"content":"","date":"11. 5. 2015","externalUrl":null,"permalink":"/tags/java/","section":"Tags","summary":"","title":"Java","type":"tags"},{"content":"OdbcProxy je program, který umožňuje přes HTTP protokol pracovat s ODBC nebo OLE DB zdroji v počítači, na kterém běží. Po spuštění naslouchá na portu 47115 a poskytuje metody pro otevření spojení, jeho uzavření, výběr a úpravu dat v použitém zdroji.\nProgram vznikl z důvodu odstranění podpory pro ODBC v Javě 8 a nemožnosti aktualizovat ovladače na používaném zdroji dat, které by umožnily komunikaci přímo přes JDBC. OdbcProxy vytváří webovou službu, přes kterou je možné pracovat s ODBC nebo OLE DB zdroji. Je možné jej nainstalovat i jako Windows službu a spouštět po startu serveru. OdbcProxy pro svůj běh potřebuje nainstalovaný Microsoft .NET 3.5.\nPo spuštění jsou k dispozici následující URL:\nhttp://localhost:47115/odbcproxy/connect http://localhost:47115/odbcproxy/select http://localhost:47115/odbcproxy/execute http://localhost:47115/odbcproxy/close Všechny adresy přijímají POST metodou XML data a XML data také vrací. HTTP klient musí poslat také hlavičku Content-Type: application/xml\nSoubory ke stažení # Program odbcproxy včetně zdrojových souborů (Zip, 116 kB)\nAplikace je v adresáři bin/Debug. Soubor odbcproxy.exe stačí kamkoliv nakopírovat, pokud ho nechcete spouštět z adresáře projektu.\nPro spuštění potřebuje administrátorská práva. Pokud je spuštěn z konzole, zkusí se navázat na port 47115. V případě úspěchu začne na tomto portu zpracovávat dotazy a program je možné ukončit stiskem klávesy Enter.\nPro instalaci programu jako Windows služby můžete použít aplikaci installutil.exe, která je součástí .NET Frameworku. Více informací o tomto programu je k dispozici například na Programování Windows Services nebo How to: Install and Uninstall Services. Ukázka klienta v Javě (Zip, 4.5 MB) XSD soubor pro vytvoření tříd klienta Projekt na github.com Metoda connect # Slouží k otevření ODBC nebo OLE DB spojení se zadaným zdrojem.\nVstupní data # XML element Popis ConnectionString Definice datového zdroje a jeho parametrů. UsingOleDb Určuje, zda ConnectionString popisuje zdroj pro ODBC nebo OLE DB. Hodnoty: true / false. \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;ConnectRequest\u0026gt; \u0026lt;ConnectionString\u0026gt; Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\\UserData\\Documents\\AccessTest01.accdb;Persist Security Info=False; \u0026lt;/ConnectionString\u0026gt; \u0026lt;UsingOleDb\u0026gt;true\u0026lt;/UsingOleDb\u0026gt; \u0026lt;/ConnectRequest\u0026gt; Odpověď # XML element Popis ConnectionAutoCloseTime Čas, kdy dojde k automatickému uzavření spojení, pokud jej klient neuzavře metodou close. ConnectionID Identifikátor nově vytvořeného spojení. Error Textový popis chyby, pokud se nepovedlo spojení vytvořit. Success Určuje, zda byla operace úspěšně dokončena. \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;ConnectResponse xmlns:i=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34;\u0026gt; \u0026lt;ConnectionAutoCloseTime\u0026gt;2015-05-09T15:26:25.6425929+02:00\u0026lt;/ConnectionAutoCloseTime\u0026gt; \u0026lt;ConnectionID\u0026gt;70e2623e-c01a-4764-8f48-1d6a1fcbc3c1\u0026lt;/ConnectionID\u0026gt; \u0026lt;Error i:nil=\u0026#34;true\u0026#34;/\u0026gt; \u0026lt;Success\u0026gt;true\u0026lt;/Success\u0026gt; \u0026lt;/ConnectResponse\u0026gt; Metoda close # Uzavře dříve otevřené spojení ke zdroji dat.\nVstupní data # XML element Popis ConnectionID Identifikátor spojení. \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;CloseRequest\u0026gt; \u0026lt;ConnectionID\u0026gt;70e2623e-c01a-4764-8f48-1d6a1fcbc3c1\u0026lt;/ConnectionID\u0026gt; \u0026lt;/CloseRequest\u0026gt; Odpověď # XML element Popis Error Textový popis chyby, pokud se nepovedlo spojení uzavřít. Success Určuje, zda byla operace úspěšně dokončena. \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;CloseResponse xmlns:i=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34;\u0026gt; \u0026lt;Error i:nil=\u0026#34;true\u0026#34;/\u0026gt; \u0026lt;Success\u0026gt;true\u0026lt;/Success\u0026gt; \u0026lt;/CloseResponse\u0026gt; Metoda select # Slouží k výběru dat.\nVstupní data # XML element Popis ConnectionID Identifikátor spojení. Query SELECT dotaz. \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;SelectRequest\u0026gt; \u0026lt;ConnectionID\u0026gt;70e2623e-c01a-4764-8f48-1d6a1fcbc3c1\u0026lt;/ConnectionID\u0026gt; \u0026lt;Query\u0026gt;select * from Tabulka1 where quantity \u0026amp;lt; 5\u0026lt;/Query\u0026gt; \u0026lt;/SelectRequest\u0026gt; Odpověď # XML element Popis ConnectionAutoCloseTime Čas, kdy dojde k automatickému uzavření spojení, pokud jej klient neuzavře metodou close. Error Textový popis chyby, pokud došlo během provádění dotazu k chybě. Success Určuje, zda byla operace úspěšně dokončena. Rows Seznam dat, které vrátil dotaz. \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;SelectResponse xmlns:i=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34;\u0026gt; \u0026lt;ConnectionAutoCloseTime\u0026gt;2015-05-10T08:02:17.806343+02:00\u0026lt;/ConnectionAutoCloseTime\u0026gt; \u0026lt;Error i:nil=\u0026#34;true\u0026#34;/\u0026gt; \u0026lt;Rows\u0026gt; \u0026lt;Row\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;ID\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:int\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;6\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;CODE\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:string\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;P101205\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;HEADER\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:string\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;TEST06\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;PRICE_VAT\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:decimal\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;799\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;VAT\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:double\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;21\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;QUANTITY\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:double\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;3\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;PRICE_WO_VAT\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:decimal\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;660.3306\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;TOTAL\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:decimal\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;2397\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;/Row\u0026gt; \u0026lt;Row\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;ID\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:int\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;7\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;CODE\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:string\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;P101206\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;HEADER\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:string\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;TEST07\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;PRICE_VAT\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:decimal\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;200\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;VAT\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:double\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;21\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;QUANTITY\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:double\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;2\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;PRICE_WO_VAT\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:decimal\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;165.2893\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;Column\u0026gt; \u0026lt;Header\u0026gt;TOTAL\u0026lt;/Header\u0026gt; \u0026lt;Value i:type=\u0026#34;a:decimal\u0026#34; xmlns:a=\u0026#34;http://www.w3.org/2001/XMLSchema\u0026#34;\u0026gt;400\u0026lt;/Value\u0026gt; \u0026lt;/Column\u0026gt; \u0026lt;/Row\u0026gt; \u0026lt;/Rows\u0026gt; \u0026lt;Success\u0026gt;true\u0026lt;/Success\u0026gt; \u0026lt;/SelectResponse\u0026gt; Metoda execute # Slouží k úpravě dat (INSERT / UPDATE / DELETE).\nVstupní data # XML element Popis ConnectionID Identifikátor spojení. Query Dotaz na změnu dat. \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;ExecuteRequest\u0026gt; \u0026lt;ConnectionID\u0026gt;70e2623e-c01a-4764-8f48-1d6a1fcbc3c1\u0026lt;/ConnectionID\u0026gt; \u0026lt;Query\u0026gt; INSERT INTO Tabulka1(CODE, HEADER, PRICE_VAT, VAT, QUANTITY) VALUES(\u0026#39;X100201\u0026#39;, \u0026#39;ODBC Proxy Test 01\u0026#39;, 1500, 21, 14) \u0026lt;/Query\u0026gt; \u0026lt;/ExecuteRequest\u0026gt; Odpověď # XML element Popis AffectedRows Počet ovlivněných řádků. ConnectionAutoCloseTime Čas, kdy dojde k automatickému uzavření spojení, pokud jej klient neuzavře metodou close. Error Textový popis chyby, pokud došlo během provádění dotazu k chybě. Success Určuje, zda byla operace úspěšně dokončena. \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;ExecuteResponse xmlns:i=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34;\u0026gt; \u0026lt;AffectedRows\u0026gt;1\u0026lt;/AffectedRows\u0026gt; \u0026lt;ConnectionAutoCloseTime\u0026gt;2015-05-10T08:18:14.229503+02:00\u0026lt;/ConnectionAutoCloseTime\u0026gt; \u0026lt;Error i:nil=\u0026#34;true\u0026#34;/\u0026gt; \u0026lt;Success\u0026gt;true\u0026lt;/Success\u0026gt; \u0026lt;/ExecuteResponse\u0026gt; Ukázky vytvoření spojení k různým zdrojům # Microsoft Access # \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;ConnectRequest\u0026gt; \u0026lt;ConnectionString\u0026gt; Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\\UserData\\Documents\\AccessTest01.accdb;Persist Security Info=False; \u0026lt;/ConnectionString\u0026gt; \u0026lt;UsingOleDb\u0026gt;true\u0026lt;/UsingOleDb\u0026gt; \u0026lt;/ConnectRequest\u0026gt; Microsoft Excel # \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;ConnectRequest\u0026gt; \u0026lt;ConnectionString\u0026gt; Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=D:\\UserData\\Documents\\openxml01.xlsx; \u0026lt;/ConnectionString\u0026gt; \u0026lt;UsingOleDb\u0026gt;false\u0026lt;/UsingOleDb\u0026gt; \u0026lt;/ConnectRequest\u0026gt; Microsoft Visual FoxPro # \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;ConnectRequest\u0026gt; \u0026lt;ConnectionString\u0026gt; Driver={Microsoft Visual FoxPro Driver};SourceType=DBF;SourceDB=D:\\UserData\\Documents\\dbf_directory;Exclusive=No; \u0026lt;/ConnectionString\u0026gt; \u0026lt;UsingOleDb\u0026gt;false\u0026lt;/UsingOleDb\u0026gt; \u0026lt;/ConnectRequest\u0026gt; SQLBase # \u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;utf-8\u0026#34;?\u0026gt; \u0026lt;ConnectRequest\u0026gt; \u0026lt;ConnectionString\u0026gt; PROVIDER=SQLBASEOLEDB.1;Data Source=Island;User ID=SYSADM;Password=SYSADM \u0026lt;/ConnectionString\u0026gt; \u0026lt;UsingOleDb\u0026gt;true\u0026lt;/UsingOleDb\u0026gt; \u0026lt;/ConnectRequest\u0026gt; Více příkladů je k dispozici na www.connectionstrings.com.\n","date":"11. 5. 2015","externalUrl":null,"permalink":"/clanky/odbcproxy/","section":"Články","summary":"OdbcProxy je program, který umožňuje přes HTTP protokol pracovat s ODBC nebo OLE DB zdroji v počítači, na kterém běží. Po spuštění naslouchá na portu 47115 a poskytuje metody pro otevření spojení, jeho uzavření, výběr a úpravu dat v použitém zdroji.\n","title":"OdbcProxy","type":"clanky"},{"content":"Vítejte na pdynet.net. Najdete tu starší články o programování v C++, C# a PHP, o Linuxu a Windows, několik mých programů ke stažení a fotky z Poděbrad a okolí.\n","date":"11. 5. 2015","externalUrl":null,"permalink":"/","section":"pdynet.net","summary":"","title":"pdynet.net","type":"page"},{"content":"","date":"11. 5. 2015","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"Pro rychlé smazání cache Internet Exploreru je možné použít následující program. Po spuštění se pokusí přes funkce FindFirstUrlCacheEntry a FindNextUrlCacheEntry vyhledat záznamy v dočasné paměti prohlížeče, které následně smaže. Pokud je program spuštěn na Windows Vista nebo novějších, nastartuje sám sebe ještě na pozadí s nižší integritou, aby pročistil cache stránek, pro které se IE spouští s nižší integritou. Ve výchozím nastavení to jsou vlastně všechny stránky zóny „Internet“, pro které je povolen chráněný režim.\nProgram pro spuštění potřebuje nainstalovaný Microsoft .NET Framework, minimálně ve verzi 3.5. Aplikace nemá žádná okna, jedná se o konzolovou aplikaci. V základním nastavení nemaže cookies. Pokud chcete zároveň odstranit uložené cookies, stačí programu předat parametr „-c“.\nclriecache.exe -c Soubory ke stažení # Program clriecache (Zip, 17 kB) Zdrojové soubory (Zip, 117 kB) ","date":"4. 5. 2014","externalUrl":null,"permalink":"/clanky/smazani-cache-internet-exploreru/","section":"Články","summary":"Pro rychlé smazání cache Internet Exploreru je možné použít následující program. Po spuštění se pokusí přes funkce FindFirstUrlCacheEntry a FindNextUrlCacheEntry vyhledat záznamy v dočasné paměti prohlížeče, které následně smaže. Pokud je program spuštěn na Windows Vista nebo novějších, nastartuje sám sebe ještě na pozadí s nižší integritou, aby pročistil cache stránek, pro které se IE spouští s nižší integritou. Ve výchozím nastavení to jsou vlastně všechny stránky zóny „Internet“, pro které je povolen chráněný režim.\n","title":"Smazání cache Internet Exploreru","type":"clanky"},{"content":"Výpočet MD5 hashe je v Javě jednoduchá věc na pár řádků. Veškerou práci odvede třída MessageDigest metodami update a digest. Výstupem z metody digest je pole bytů, které v následujícím kódu převedeme na String.\nMetody encodeHex a encodeHexString pochází z Apache Commons Codec.\nimport java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MD5 { private static final char[] DIGITS_LOWER = {\u0026#39;0\u0026#39;, \u0026#39;1\u0026#39;, \u0026#39;2\u0026#39;, \u0026#39;3\u0026#39;, \u0026#39;4\u0026#39;, \u0026#39;5\u0026#39;, \u0026#39;6\u0026#39;, \u0026#39;7\u0026#39;, \u0026#39;8\u0026#39;, \u0026#39;9\u0026#39;, \u0026#39;a\u0026#39;, \u0026#39;b\u0026#39;, \u0026#39;c\u0026#39;, \u0026#39;d\u0026#39;, \u0026#39;e\u0026#39;, \u0026#39;f\u0026#39;}; protected static char[] encodeHex(byte[] data, char[] toDigits) { int l = data.length; char[] out = new char[l \u0026lt;\u0026lt; 1]; for (int i = 0, j = 0; i \u0026lt; l; i++) { out[j++] = toDigits[(0xF0 \u0026amp; data[i]) \u0026gt;\u0026gt;\u0026gt; 4]; out[j++] = toDigits[0x0F \u0026amp; data[i]]; } return out; } public static String encodeHexString(byte[] data) { return new String(encodeHex(data, DIGITS_LOWER)); } public static String md5(String input, String charsetName) throws NoSuchAlgorithmException, UnsupportedEncodingException { MessageDigest md5 = MessageDigest.getInstance(\u0026#34;MD5\u0026#34;); md5.update(input.getBytes(charsetName)); return encodeHexString(md5.digest()); } public static String md5(String input) throws NoSuchAlgorithmException, UnsupportedEncodingException { return md5(input, Charset.defaultCharset().name()); } }","date":"15. 5. 2013","externalUrl":null,"permalink":"/clanky/java-jak-vypocitat-md5-hash/","section":"Články","summary":"Výpočet MD5 hashe je v Javě jednoduchá věc na pár řádků. Veškerou práci odvede třída MessageDigest metodami update a digest. Výstupem z metody digest je pole bytů, které v následujícím kódu převedeme na String.\n","title":"Java - výpočet MD5 hashe","type":"clanky"},{"content":"Xml2xlsx je program pro převod jednoduchých XML souborů do XLSX tabulky. Pro spuštění potřebuje nainstalovaný Microsoft .NET Framework, minimálně ve verzi 3.5. Program se spouští s parametry, zadanými na příkazové řádce. Výsledná data jsou do XLSX souboru vkládána knihovnou ExtremeML.\nProgram je určen pro získání dat z XML souborů, které obsahují data snadno převeditelná do tabulky. Následující ukázka XML představuje typický příklad, pro který je program napsán.\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34; ?\u0026gt; \u0026lt;level1\u0026gt; \u0026lt;level2\u0026gt; \u0026lt;name\u0026gt;Item 1\u0026lt;/name\u0026gt; \u0026lt;price\u0026gt;1\u0026lt;/price\u0026gt; \u0026lt;description\u0026gt;Description of item 1.\u0026lt;/description\u0026gt; \u0026lt;/level2\u0026gt; \u0026lt;level2\u0026gt; \u0026lt;name\u0026gt;Item 2\u0026lt;/name\u0026gt; \u0026lt;price\u0026gt;2\u0026lt;/price\u0026gt; \u0026lt;description\u0026gt;Description of item 2.\u0026lt;/description\u0026gt; \u0026lt;/level2\u0026gt; \u0026lt;level2\u0026gt; \u0026lt;name\u0026gt;Item 3\u0026lt;/name\u0026gt; \u0026lt;price\u0026gt;3\u0026lt;/price\u0026gt; \u0026lt;description\u0026gt;Description of item 3.\u0026lt;/description\u0026gt; \u0026lt;/level2\u0026gt; \u0026lt;/level1\u0026gt; XML data obsahují opakující se element level2, uvnitř kterého jsou elementy, které sami neobsahují žádné další zanořené elementy. Program xml2xlsx je určen k uložení hodnot z rodičovského elementu, v tomto případě jím je element level2. Xml2xlsx nepracuje s případnými atributy elementů, ale pouze s jejich hodnotami.\nNásledující parametry jsou povinné pro spuštění programu:\n-f, --file\nCesta k XML soboru. -e, --element\nRodičovský element, ve kterém budou hledána data. Následující parametry jsou volitelné:\n-n, --number_elements\nSeznam elementů s číselnými hodnotami. V předchozím příkladu je to například element price. Jména více elementů je možné oddělit čárkou. Například: -n price1,price2. -i, --ignore_elements\nČárkou oddělený seznam elementů, které nebudou uloženy do XLSX souboru. V předchozím příkladu by jím mohl být například element description. -c, --sheet_count\nMaximální počet řádků uložených v XLSX tabulce. Program xml2xlsx neoplývá moc velkým výkonem a pokud zdrojový XML soubor obsahuje hodně jedinečných textů, může výsledné zpracování XML souboru trvat opravdu dlouho. Pokud má XML soubor řádově stovky nebo tisíce záznamů, které je nutno do XLSX tabulky uložit, může zpracování celého souboru trvat jednotky nebo i desítky minut. Tento parametr může celkový čas, potřebný pro zpracování XML souboru zkrátit, ovšem za cenu, že výstupem z programu bude několik XLSX souborů. -t, --add_time\nDo jména XLSX souboru bude doplněn aktuální čas. Pokud by se XML soubor jmenoval sample.xml, budou data uložena do souboru sample-20120325-153011.xlsx, kde čísla ve jménu souboru odpovídají aktuálnímu času. -v, --verbose\nPři procházení XML souboru bude do konzole vypisován počet zpracovaných elementů. -u, --url\nCesta k XML souboru, pokud je nutné jej stáhnout z internetu. Data budou uložena do souboru určeným povinným parametrem -f. -x, --noproxy\nPro stažení souboru nepoužije výchozí proxy server, nastavený v systému. -s, --username a -p, --password\nPřihlašovací údaje, pokud je XML soubor stahován například z FTP serveru. Soubory ke stažení # Program xml2xlsx (7Zip, 1.0 MB) Program xml2xlsx (Zip, 1.7 MB) Zdrojové soubory Ve staženém archívu s programem je k dispozici adresář test se vzorovým XML souborem a několika CMD soubory s ukázkou použití.\n","date":"25. 3. 2012","externalUrl":null,"permalink":"/clanky/xml2xlsx/","section":"Články","summary":"Xml2xlsx je program pro převod jednoduchých XML souborů do XLSX tabulky. Pro spuštění potřebuje nainstalovaný Microsoft .NET Framework, minimálně ve verzi 3.5. Program se spouští s parametry, zadanými na příkazové řádce. Výsledná data jsou do XLSX souboru vkládána knihovnou ExtremeML.\n","title":"xml2xlsx","type":"clanky"},{"content":"Uploadlast je program pro příkazový řádek, který v zadaném adresáři vyhledá naposledy změněný soubor, který uloží na FTP server. Pro spuštění potřebuje nainstalovaný Microsoft .NET Framework, minimálně ve verzi 3.5. Program je možné použít pro zálohování souborů na vzdálený FTP server. Používám ho pro zálohování SQL dumpu databáze.\nV mém případě v noci vytvořím ZIP archív se jménem ve formátu zaloha-2011-01-01.zip. V počítači, kde tyto zálohy vznikají, ponechávám soubory několik dní staré. Protože jsem chtěl nejnovější soubor ukládat i na jiné místo, napsal jsem si tento malý program.\nV programu jsou použity následující komponenty:\nparser NDesk.Options pro zpracování vstupních parametrů programu Povinné parametry pro spuštění programu:\n-d, --dir\nLokální adresář, ve kterém bude vyhledán naposledy změněný soubor. -r, --remote\nAdresa FTP serveru, včetně vzdáleného adresáře, kam má být soubor uložen. Například: ftp://ftp.server.net/folder1/folder2/. -u, --user\nUživatelské jméno pro přihlášení k FTP serveru. -p, --password\nHeslo pro přihlášení k FTP serveru. Volitelné parametry pro spuštění programu:\n-k, --keep\nPočet souborů, které budou na FTP serveru ponechány. Výchozí hodnota je 10. Program si po uploadu souboru na FTP načte obsah vzdáleného adresáře a ponechá v něm pouze k nejnovějších souborů. Ostatní soubory smaže. -t, --timestamp\nDo jména lokálního souboru doplní aktuální čas uploadu. Pokud by se lokální soubor jmenoval například: zaloha.zip, bude na FTP server uložen pod jménem zaloha-20110101-230500.zip. Příklad použití:\nuploadlast.exe -d c:\\backup -r ftp://ftp.example.net/backup/ -u user -p password uploadlast.exe -d c:\\backup -r ftp://ftp.example.net/backup/ -u user -p password -t uploadlast.exe -d c:\\backup -r ftp://ftp.example.net/backup/ -u user -p password -k 4 Soubory ke stažení # Program uploadlast Zdrojové soubory ","date":"14. 8. 2011","externalUrl":null,"permalink":"/clanky/uploadlast-ftp-upload-naposledy-zmeneneho-souboru/","section":"Články","summary":"Uploadlast je program pro příkazový řádek, který v zadaném adresáři vyhledá naposledy změněný soubor, který uloží na FTP server. Pro spuštění potřebuje nainstalovaný Microsoft .NET Framework, minimálně ve verzi 3.5. Program je možné použít pro zálohování souborů na vzdálený FTP server. Používám ho pro zálohování SQL dumpu databáze.\n","title":"uploadlast - FTP upload naposledy změněného souboru","type":"clanky"},{"content":"TaskDialog je přirozeným nástupcem okna MessageBox. Je dostupný ve Windows Vista nebo Server 2008 a novějších. TaskDialog je umístěn v knihovně Comctl32.dll od verze 6. Pokud chcete ve vlastní .NET aplikaci TaskDialog použít, můžete sáhnout po hotovém řešení přímo od Microsoftu - Windows® API Code Pack for Microsoft® .NET Framework.\nWindows® API Code Pack for Microsoft® .NET Framework obsahuje zdrojové soubory a přeložené knihovny pro podporu některých novinek, uvedených ve Windows Vista a Windows 7 v .NET aplikacích.\nAby bylo možné TaskDialog zobrazit, musí se aplikace odkázat na správnou verzi knihovny Comctl32.dll. Jednou z možností je vložit manifest přímo do aplikace - tento způsob je použitý i ve výše zmíněné knihovně. Druhou možností je použití funkcí CreateActCtx, ActivateActCtx a DeactivateActCtx pro nahrání správné verze knihovny Comctl32.dll za běhu aplikace. I pro tento způsob již existuje hotové řešení na How to apply Windows XP themes to Office COM add-ins, jen se musí trochu upravit, aby fungovalo i v 64 bitových systémech.\nTento způsob je použitý také v programu dotsplit. Na stránce programu je k dispozici i zdrojový kód, kde je v souboru ActivationContext.cs kód, pro nahrání správné verze knihovny Comctl32.dll. V souboru dotsplit.xaml.cs je následně v metodě DisplaySplitResult vidět, jak lze TaskDialog zobrazit.\n","date":"2. 1. 2011","externalUrl":null,"permalink":"/clanky/jak-zobrazit-taskdialog-v-dot-net-aplikaci/","section":"Články","summary":"TaskDialog je přirozeným nástupcem okna MessageBox. Je dostupný ve Windows Vista nebo Server 2008 a novějších. TaskDialog je umístěn v knihovně Comctl32.dll od verze 6. Pokud chcete ve vlastní .NET aplikaci TaskDialog použít, můžete sáhnout po hotovém řešení přímo od Microsoftu - Windows® API Code Pack for Microsoft® .NET Framework.\n","title":"Jak zobrazit TaskDialog v .NET aplikaci","type":"clanky"},{"content":"","date":"2. 1. 2011","externalUrl":null,"permalink":"/foto/","section":"Foto koutek","summary":"","title":"Foto koutek","type":"foto"},{"content":"Historické fotky 04\n40 fotografií. Kliknutím otevřete prohlížeč, listovat můžete šipkami nebo tažením prstem.\n","date":"2. 1. 2011","externalUrl":null,"permalink":"/foto/historicke-fotografie-podebrad-04/","section":"Foto koutek","summary":"","title":"Historické fotografie Poděbrad 04","type":"foto"},{"content":"Historické fotky 03\n40 fotografií. Kliknutím otevřete prohlížeč, listovat můžete šipkami nebo tažením prstem.\n","date":"30. 10. 2010","externalUrl":null,"permalink":"/foto/historicke-fotografie-podebrad-03/","section":"Foto koutek","summary":"","title":"Historické fotografie Poděbrad 03","type":"foto"},{"content":"Historické fotky 02\n40 fotografií. Kliknutím otevřete prohlížeč, listovat můžete šipkami nebo tažením prstem.\n","date":"2. 10. 2010","externalUrl":null,"permalink":"/foto/historicke-fotografie-podebrad-02/","section":"Foto koutek","summary":"","title":"Historické fotografie Poděbrad 02","type":"foto"},{"content":"Historické fotky 01\n40 fotografií. Kliknutím otevřete prohlížeč, listovat můžete šipkami nebo tažením prstem.\n","date":"14. 9. 2010","externalUrl":null,"permalink":"/foto/historicke-fotografie-podebrad-01/","section":"Foto koutek","summary":"","title":"Historické fotografie Poděbrad 01","type":"foto"},{"content":"Pro otevření DBF souborů v C# můžeme použít ODBC ovladač pro Visual FoxPro. Podmínkou je jeho existence v systému. Ovladač je možné stáhnout na stránce Visual FoxPro ODBC Driver. Následující kousek kódu ukazuje, jak je možné otevřít DBF soubor a načíst jeho obsah.\nclass Dbf2 { public OdbcConnection Connect(string SourceDB) { try { OdbcConnection conn = new OdbcConnection();\nconn.ConnectionString = \u0026#34;Driver={Microsoft Visual FoxPro Driver};\u0026#34; + \u0026#34;SourceType=DBF;\u0026#34; + \u0026#34;SourceDB=\u0026#34; + SourceDB + \u0026#34;;\u0026#34; + \u0026#34;Exclusive=No\u0026#34;; conn.Open(); return conn; } catch (OdbcException e) { DisplayOdbcError(e); return null; } } private void DisplayOdbcError(OdbcException e) { string errorMessages = \u0026#34;\u0026#34;; for (int i = 0; i \u0026lt; e.Errors.Count; i++) { errorMessages += \u0026#34;Index #\u0026#34; + i + \u0026#34;\\n\u0026#34; + \u0026#34;Message: \u0026#34; + e.Errors[i].Message + \u0026#34;\\n\u0026#34; + \u0026#34;NativeError: \u0026#34; + e.Errors[i].NativeError.ToString() + \u0026#34;\\n\u0026#34; + \u0026#34;Source: \u0026#34; + e.Errors[i].Source + \u0026#34;\\n\u0026#34; + \u0026#34;SQL: \u0026#34; + e.Errors[i].SQLState + \u0026#34;\\n\u0026#34;; } Console.WriteLine(errorMessages); } public void Run() { OdbcConnection conn = Connect(\u0026#34;D:\\\\dbfdata\u0026#34;); if (conn == null) return; try { string SQL = \u0026#34;SELECT * FROM dbfsoubor\u0026#34;; OdbcCommand MyCommand = new OdbcCommand(SQL, conn); OdbcDataReader dr = MyCommand.ExecuteReader(); while (dr.Read()) { StringBuilder sb = new StringBuilder(); for (int col = 0; col \u0026lt; dr.FieldCount; col++) { sb.Append(dr[col].ToString().Trim()); if (col \u0026lt; dr.FieldCount - 1) sb.Append(\u0026#34;, \u0026#34;); } Console.WriteLine(sb.ToString()); } dr.Close(); } catch (OdbcException e) { DisplayOdbcError(e); } if (conn != null) conn.Close(); } }","date":"8. 8. 2010","externalUrl":null,"permalink":"/clanky/pripojeni-k-foxpro-tabulkam-pomoci-odbc/","section":"Články","summary":"Pro otevření DBF souborů v C# můžeme použít ODBC ovladač pro Visual FoxPro. Podmínkou je jeho existence v systému. Ovladač je možné stáhnout na stránce Visual FoxPro ODBC Driver. Následující kousek kódu ukazuje, jak je možné otevřít DBF soubor a načíst jeho obsah.\n","title":"Připojení k FoxPro tabulkám v C# pomocí ODBC","type":"clanky"},{"content":"Představme si situaci, kdy máme textovou proměnou, která obsahuje hodnoty oddělené určitým znakem. Z této proměnné budeme chtít získat pouze jedinečné hodnoty, seřadit je podle abecedy a odstranit případné bílé znaky na začátku a konci. Pokud do tohoto úkolu zapojíme Linq, stačí nám na to jen jeden řádek kódu.\nV následujícím příkladu máme proměnou src, která obsahuje hodnoty oddělené čárkou. Pro lepší čitelnost jsou metody Linqu rozepsány na samostatné řádky.\nstring src = \u0026#34;A1, A2,B1, C1, C2,A2,B1, C1, A0,A3,A9,A8,A7,A6\u0026#34;; var values = src.Split(new char[] { \u0026#39;,\u0026#39; }, StringSplitOptions.RemoveEmptyEntries) .Select(x =\u0026gt; x.Trim()) .Distinct() .OrderBy(x =\u0026gt; x) .ToArray(); Console.WriteLine(String.Join(\u0026#34;,\u0026#34;, values)); rozdělení hodnot do pole Select(x =\u0026gt; x.Trim()) vrací hodnotu bez případných bílých znaků na začátku nebo konci Distinct() vrací pouze jedinečné hodnoty OrderBy(x =\u0026gt; x) všechny hodnoty seřadí podle abecedy ToArray() z výsledku předchozí metody vytvoří pole, které nakonec použijeme pro vypsání výsledku ","date":"5. 6. 2010","externalUrl":null,"permalink":"/clanky/linq-hledani-jedinecnych-hodnot/","section":"Články","summary":"Představme si situaci, kdy máme textovou proměnou, která obsahuje hodnoty oddělené určitým znakem. Z této proměnné budeme chtít získat pouze jedinečné hodnoty, seřadit je podle abecedy a odstranit případné bílé znaky na začátku a konci. Pokud do tohoto úkolu zapojíme Linq, stačí nám na to jen jeden řádek kódu.\n","title":"Linq a vyhledání jedinečných hodnot","type":"clanky"},{"content":"","date":"29. 5. 2010","externalUrl":null,"permalink":"/tags/bash/","section":"Tags","summary":"","title":"Bash","type":"tags"},{"content":"Mailarch je program pro příkazový řádek, který umí vytvořit zip archív a odeslat jej emailem. Pro spuštění potřebuje nainstalovaný Microsoft .NET Framework, minimálně ve verzi 3.5.\nV programu jsou použity následující komponenty:\nknihovna DotNetZip pro kompresi do ZIP formátu parser NDesk.Options pro zpracování vstupních parametrů programu Povinné parametry pro spuštění programu\n-l, --list\nTextový soubor v kódování UTF-8 se seznamem soborů nebo adresářů, které chcete přidat do zip archívu. Každý záznam musí být na samostatném řádku. Komentáře v soboru musí začínat znakem „#”. -s, --smtp\nAdresa SMTP serveru, přes který bude zpráva doručena. -f, --from\nAdresa odesílatele. -t, --to\nAdresa příjemce. -a, --archive\nJméno archívu, který má být vytvořen. Tento soubor bude uložen v příloze zprávy a zadané jméno bude použito i pro předmět emailu. Volitelné parametry pro spuštění programu\n-p, --password\nHeslo, které bude použito pro vytvoření archívu. -ssl\nTřída SmtpClient využije SSL pro odeslání dat. Podmínkou je, aby SMTP server podporoval šifrované spojení. -dc\nTřída SmtpClient použije uživatelské jméno a heslo uživatele, pod kterým je program spuštěn, pro přihlášení k SMTP serveru. Příklad použití:\nmailarch.exe -l pokus.txt -s mail.example.com -f from@example.com -t to@example.com -a pokus.zip Soubory ke stažení # Program mailarch Zdrojové soubory Zdrojový kód # using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Net.Mail; using System.Globalization; using Ionic.Zip; namespace mailarch { class MailArch { private AppArguments args; private StringBuilder messages = new StringBuilder(); private string temp_file; public MailArch(AppArguments app_arg) { this.args = app_arg; } public void Start() { FileStream fs = null; // Otevreni seznamu souboru a adresaru. try { using (StreamReader zip_files = new StreamReader(args.file_list)) { using (ZipFile zip = new ZipFile()) { // Znakova sada konzole. int oem_cp = CultureInfo.CurrentCulture.TextInfo.OEMCodePage; zip.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding(oem_cp); // Uroven komprese. zip.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression; // Ulozeni hesla pro archiv. if (!String.IsNullOrEmpty(args.password)) zip.Password = args.password; // Zpracovani vsech radku ze souboru. string line; while ((line = zip_files.ReadLine()) != null) { line = line.Trim(); // Preskoceni prazdnych radek nebo komentaru. if (line.Length == 0 || line.StartsWith(\u0026#34;#\u0026#34;)) continue; // Kontrola, jestli je zaznam soubor nebo adresar. if (File.Exists(line)) { DisplayMessage(\u0026#34;Zipping file \u0026#34; + line); zip.AddFile(line); } else if (Directory.Exists(line)) { string path = Path.GetFullPath(line); DisplayMessage(\u0026#34;Zipping directory \u0026#34; + path); zip.AddDirectory(line, path); } else { DisplayMessage(\u0026#34;List entry \u0026#34; + line + \u0026#34; not found\u0026#34;); } } // Vytvoreni archivu v docasnem souboru. temp_file = Path.GetTempFileName(); zip.Save(temp_file); } } // Odeslani souboru v priloze. DisplayMessage(\u0026#34;Creating new message\u0026#34;); MailMessage message = new MailMessage(args.sender, args.recipient); message.Subject = args.archive; DisplayMessage(\u0026#34;Adding attachment \u0026#34; + args.archive); fs = new FileStream(temp_file, FileMode.Open, FileAccess.Read); message.Attachments.Add(new Attachment(fs, args.archive, System.Net.Mime.MediaTypeNames.Application.Octet)); message.Body = messages.ToString(); DisplayMessage(\u0026#34;Sending message\u0026#34;); SmtpClient client = new SmtpClient(args.smtp_server); client.DeliveryMethod = SmtpDeliveryMethod.Network; client.UseDefaultCredentials = args.default_credentials; client.EnableSsl = args.ssl; client.Send(message); fs.Close(); fs = null; DisplayMessage(\u0026#34;Message sent\u0026#34;); } catch (Exception e) { DisplayMessage(e.Message); } finally { try { if (fs != null) fs.Close(); // Smazani docasneho souboru. if (!String.IsNullOrEmpty(temp_file) \u0026amp;\u0026amp; File.Exists(temp_file)) File.Delete(temp_file); } catch { } } } private void DisplayMessage(string message) { string time = DateTime.Now.ToString(); messages.AppendLine(time + \u0026#34;: \u0026#34; + message); Console.WriteLine(time + \u0026#34;: \u0026#34; + message); } } }","date":"29. 5. 2010","externalUrl":null,"permalink":"/clanky/mailarch/","section":"Články","summary":"Mailarch je program pro příkazový řádek, který umí vytvořit zip archív a odeslat jej emailem. Pro spuštění potřebuje nainstalovaný Microsoft .NET Framework, minimálně ve verzi 3.5.\nV programu jsou použity následující komponenty:\nknihovna DotNetZip pro kompresi do ZIP formátu parser NDesk.Options pro zpracování vstupních parametrů programu ","title":"mailarch - vytvoření a odeslání zip archívu emailem","type":"clanky"},{"content":"Dotsplit je program určený k rozdělení souboru na menší části. Pro spuštění vyžaduje nainstalovaný Microsoft .NET Framework 3.5. Dotsplit neumí soubory komprimovat nebo šifrovat, pouze je rozdělit na menší části a vytvořit dávkový soubor pro jejich spojení do původního souboru. Program jsem si napsal jen abych si vyzkoušel Windows Presentation Foundation.\nOkno programu je rozděleno na 3 hlavní části.\npole pro výběr zdrojového souboru pole pro výběr adresáře, kam budou uloženy vytvořené soubory pole pro zadání požadované velikosti souboru Po 1. spuštění jsou v rozbalovacím poli 3 hodnoty (5 MB, 10 MB, 700 MB). Do tohoto pole můžete napsat vlastní velikost souboru v bytech, kB, MB nebo GB. Například 798156, 500 kB, 128 MB nebo 4,7 GB. Minimální povolená hodnota je 200 kB. Tuto hodnotu si dotsplit uloží pro příští spuštění.\nV případě, že by rozdělením souboru vzniklo více než 100 částí, zobrazí program dotaz, jestli má opravdu pokračovat.\nKdyž dotsplit rozdělí soubor, uloží do cílového adresáře dávkový soubor, kterým je možné části spojit do původního souboru. Tento dávkový soubor je uložen v kódování CP852, které ve výchozím nastavení používá příkazový řádek. Díky tomu můžete rozdělit i soubory s diakritikou v názvu.\nSoubory ke stažení # Instalace programu Program bez instalace Zdrojové soubory • Doplněno 29. května 2010\nPokud se Vám nedaří spustit soubor setup.exe, zkuste zrušit jeho blokování podle následujícího obrázku.\nPříklad rozdělení DVD obrazu na 700 MB části # Dejme tomu, že máte uložený obraz DVD v iso souboru, který potřebujete rozdělit na 700 MB části. Soubor přetáhněte myší nad 1. pole nebo jej vyhledejte pomocí tlačítka se 3 tečkami. Pokud chcete uložit části souboru do jiného adresáře, než kde se nachází originální soubor, zadejte do 2. pole cestu k adresáři, kam chcete části uložit. K vyhledání adresáře můžete opět využít tlačítko se 3 tečkami. Do 3. pole zadejte požadovanou velikost částí. V tomto případě tedy 700 MB. Rozdělení odstartuje stiskem tlačítka Rozdělit. ","date":"4. 4. 2010","externalUrl":null,"permalink":"/clanky/dotsplit/","section":"Články","summary":"Dotsplit je program určený k rozdělení souboru na menší části. Pro spuštění vyžaduje nainstalovaný Microsoft .NET Framework 3.5. Dotsplit neumí soubory komprimovat nebo šifrovat, pouze je rozdělit na menší části a vytvořit dávkový soubor pro jejich spojení do původního souboru. Program jsem si napsal jen abych si vyzkoušel Windows Presentation Foundation.\n","title":"dotsplit - program pro rozdělení souboru","type":"clanky"},{"content":"","date":"26. 12. 2009","externalUrl":null,"permalink":"/tags/php/","section":"Tags","summary":"","title":"PHP","type":"tags"},{"content":"Následující krátký kód používám pro strojové zpracování příloh z emailu. Tento kód si neklade za cíl být univerzální. V mém případě zpracovává zprávy, které mají vždy stejnou strukturu.\nZprávy, ve kterých hledám informace nejprve třídí mailserver podle pravidel. V mém případě do podložky složky INBOX.\n\u0026lt;?php // Pripojeni k IMAP serveru. $mbox = imap_open(\u0026#39;{localhost:143/notls}INBOX/Data\u0026#39;, \u0026#39;username\u0026#39;, \u0026#39;password\u0026#39;); if ($mbox === false) { echo imap_last_error(); die(); } // Vyhledani vsech nesmazanych zprav v otevrene slozce. $mfound = imap_search($mbox, \u0026#39;ALL UNDELETED\u0026#39;, SE_UID); if ($mfound === FALSE) { echo \u0026#39;Zadne nesmazane zpravy ve slozce \u0026lt;strong\u0026gt;INBOX/Data\u0026lt;/strong\u0026gt;.\u0026#39;; } else { // Mame k dispozici pole s ID zprav. Pro kazdou nacteme jeji strukturu. foreach ($mfound as $msg_id) { $msg_struct = imap_fetchstructure($mbox, $msg_id, FT_UID); // Zajimaji nas pouze zpravy, ktere maji 2 a vice casti. // Tyto zpravy mohou obsahovat prilohy. if (isset($msg_struct-\u0026gt;parts) \u0026amp;\u0026amp; count($msg_struct-\u0026gt;parts) \u0026gt;= 2) { // Vyhledani priloh v kazde casti zpravy. for ($part_no = 0; $part_no \u0026lt; count($msg_struct-\u0026gt;parts); $part_no++) { // Kontrola, jestli tato cast zpravy obsahuje parametry pro dalsi hledani. if ($msg_struct-\u0026gt;parts[$part_no]-\u0026gt;ifdparameters) { // Prohledani parametru. Zajima nas atribut s nazvem \u0026#39;filename\u0026#39;. foreach ($msg_struct-\u0026gt;parts[$part_no]-\u0026gt;dparameters as $part_param) { // Tato cast obsahuje informaci o jmenu souboru v priloze. if (mb_strtolower($part_param-\u0026gt;attribute, \u0026#39;utf-8\u0026#39;) == \u0026#39;filename\u0026#39;) { // Kontrola, jestli ma soubor pozadovanou priponu. if (pathinfo($part_param-\u0026gt;value, PATHINFO_EXTENSION) == \u0026#39;zpt\u0026#39;) { // Nacteni obsahu casti mailu. $part_content = imap_fetchbody($mbox, $msg_id, $part_no + 1, FT_UID); // Dekodovani obsahu pokud je v BASE64 nebo jako QUOTED-PRINTABLE switch ($msg_struct-\u0026gt;parts[$part_no]-\u0026gt;encoding) { case 3: $part_content = base64_decode($part_content); break; case 4: $part_content = quoted_printable_decode($part_content); break; } // V promenne $part_content je obsah souboru v priloze. // Na tomto miste by melo byt volani funkce pro zpracovani dat. } } } } } } // Oznaceni zpravy ke smazani imap_setflag_full($mbox, $msg_id, \u0026#39;\\\\Deleted\u0026#39;, ST_UID); } } imap_close($mbox); ?\u0026gt; Po spuštění skript vyhledá ve složce všechny zprávy, které nejsou označeny ke smazání. U každé nalezené zprávy načte její strukturu. V případě, že zpráva obsahuje 2 nebo více částí, pokračuje v prohledání všech částí. Tento skript hledá data pouze v poli dparameters. Pokud nalezne parametr filename, načte jeho hodnotu, kterou je název souboru v příloze. V případě, že se jedná o hledaný typ souboru, načte obsah této části zprávy, kterou následně dekóduje, pokud je ve zprávě uložena jako BASE64 nebo QUOTED-PRINTABLE. Tento obsah následně předá třídě, která data dále zpracuje. Poslední věcí, kterou skript se zprávami provede, je jejich označení ke smazání.\n","date":"26. 12. 2009","externalUrl":null,"permalink":"/clanky/zpracovani-prilohy-emailu-v-php-pres-imap/","section":"Články","summary":"Následující krátký kód používám pro strojové zpracování příloh z emailu. Tento kód si neklade za cíl být univerzální. V mém případě zpracovává zprávy, které mají vždy stejnou strukturu.\n","title":"Zpracování přílohy emailu v PHP přes IMAP","type":"clanky"},{"content":"Imagick je rozšíření knihovny ImageMagick pro PHP. Podpora formátů závisí na konfiguraci knihovny ImageMagick. Například pro Gentoo mám v souboru package.use následující obsah.\nmedia-gfx/imagemagick png jpeg jpeg2k tiff gs lcms Pro změnu barevné palety obrázku nabízí Imagick metodu setImageColorspace. Pro její zjištění naopak metodu getImageColorspace.\nObě metody pracují s jednou z předdefinovaných konstant. Barevné paletě CMYK odpovídá konstanta Imagick::COLORSPACE_CMYK. Pouhé volání předchozích metod sice můžeme využít pro změnu palety, ovšem v některých případech může dojít k nepříjemné změně barev obrázků. Na následujících obrázcích je zdroj a výsledek pouhého volání metody setImageColorspace(Imagick::COLORSPACE_SRGB).\nProblém je způsoben absencí ICC profilu ve zdrojovém obrázku. Abychom zachovali barvy při změně palety, musíme nahrát CMYK profil metodou profileImage.\nNásledující kousek skriptu změní barevnou paletu ze CMYK na SRGB a zmenší obrázek na maximální velikost strany 600 bodů.\n\u0026lt;?php /** * Otevre obrazek, zmeni paletu na sRGB a prevede do JPEG. * * @param string $src_file Zdrojovy obrazek. * @param string $dst_file Cilovy obrazek. */ function ExportImage($src_file, $dst_file) { try { // Otevreni obrazku. $i = new Imagick($src_file); // Zjisteni palety. $cs = $i-\u0026gt;getImageColorspace(); // Zmena palety if ($cs == Imagick::COLORSPACE_CMYK) { // Nacteni profilu v obrazku. $profiles = $i-\u0026gt;getImageProfiles(\u0026#39;*\u0026#39;, false); // Kontrola, jestli obrazek obsahuje icc profil. $has_icc_profile = (array_search(\u0026#39;icc\u0026#39;, $profiles) !== false); // Obrazek icc profil neobsahuje. Nacteni cmyk profilu ze souboru. if ($has_icc_profile === false) { $icc_cmyk = file_get_contents(\u0026#39;USWebCoatedSWOP.icc\u0026#39;); $i-\u0026gt;profileImage(\u0026#39;icc\u0026#39;, $icc_cmyk); } // Zmena barevne palety, CMYK -\u0026gt; SRGB. $icc_rgb = file_get_contents(\u0026#39;sRGB_v4_ICC_preference.icc\u0026#39;); $i-\u0026gt;profileImage(\u0026#39;icc\u0026#39;, $icc_rgb); $i-\u0026gt;setImageColorspace(Imagick::COLORSPACE_SRGB); } // Zmena velikosti obrazku, pokud nektera // jeho strana presahuje 600 bodu. if ($i-\u0026gt;getImageWidth() \u0026gt; 600 || $i-\u0026gt;getImageHeight() \u0026gt; 600) { $i-\u0026gt;resizeImage(600, 600, Imagick::FILTER_LANCZOS, true, true); } // Nastaveni formatu. $i-\u0026gt;setImageCompression(Imagick::COMPRESSION_JPEG); $i-\u0026gt;setImageCompressionQuality(95); $i-\u0026gt;setImageFormat(\u0026#39;jpeg\u0026#39;); // Ulozeni obrazku. $i-\u0026gt;writeImage($dst_file); $i-\u0026gt;clear(); $i-\u0026gt;destroy(); $i = null; } catch (ImagickException $e) { echo \u0026#39;Chyba pri uprave obrazku: \u0026#39;.$e-\u0026gt;getMessage(); } } ?\u0026gt; Zdroje, ze kterých jsem čerpal:\nConvert Adobe CMYK Images to RGB on Linux Using PHP’s Imagick class to convert a CMYK jpeg to RGB Imagick::profileImage ","date":"10. 12. 2009","externalUrl":null,"permalink":"/clanky/imagick-prevod-palety-cmyk-na-rgb-v-php/","section":"Články","summary":"Imagick je rozšíření knihovny ImageMagick pro PHP. Podpora formátů závisí na konfiguraci knihovny ImageMagick. Například pro Gentoo mám v souboru package.use následující obsah.\nmedia-gfx/imagemagick png jpeg jpeg2k tiff gs lcms Pro změnu barevné palety obrázku nabízí Imagick metodu setImageColorspace. Pro její zjištění naopak metodu getImageColorspace.\n","title":"Imagick - převod palety CMYK na RGB v PHP","type":"clanky"},{"content":"","date":"10. 12. 2009","externalUrl":null,"permalink":"/tags/zmen%C5%A1en%C3%AD-fotek/","section":"Tags","summary":"","title":"Zmenšení Fotek","type":"tags"},{"content":"Pro případ, že by někdo řešil připojení sdíleného adresáře na My Book World přes CIFS, zde je ukázka záznamu z /etc/fstab.\n//ip.adresa.mybook/sdileny_adresar /mnt/pripojny_bod cifs username=uzivatel,password=heslo,IP=ip.adresa.mybook,iocharset=utf8,uid=xxx,gid=xxx,rw,noperm 0 0 Zdroje:\nPřipojení přes mount nebo fstab? Mount MyBookWorld in fstab ","date":"23. 8. 2009","externalUrl":null,"permalink":"/clanky/pripojeni-my-book-world-edition-z-fstab/","section":"Články","summary":"","title":"Připojení My Book World Edition z fstab","type":"clanky"},{"content":"V článku Hromadné zmenšení velikosti fotek je uveden postup, jak v dávkovém souboru použít program convert z knihovny ImageMagick pro hromadnou změnu rozměrů obrázků. Jednoduchosti a eleganci shellu se nic nevyrovná, ale přeci jen má toto řešení jednu nevýhodu. Nedokáže pracovat se soubory, které mají v názvu diakritiku. Naštěstí je součástí ImageMagick i program conjure. Program conjure se spouští s parametrem, kterým je název souboru v jazyce Magick Scripting Language (MSL). Tento soubor je ve formátu XML a obsahuje instrukce, jak pracovat s obrázky. Například: otevři soubor, uprav jeho rozměry, nastav barevnou paletu a ulož s novým názvem. Názvy souborů v tomto souboru již mohou obsahovat diakritiku.\nAbychom mohli conjure využít, musíme si nejprve připravit XML soubor, kterému bude conjure rozumět. Pro tento účel jsem napsal program mslgen, který dokáže vyhledat obrázky v adresáři, zobrazit jejich náhledy a nastavit parametry pro změnu velikosti, výsledný formát obrázků a masku, s jakou budou výsledné soubory pojmenovány. Samotný program mslgen obrázky nemění. Pouze vytvoří MSL soubor, který potom předá programu conjure.\nProgram mslgen je napsán v C# a pro spuštění potřebuje nainstalovaný Microsoft .NET Framework ve verzi 3.5. Pro změnu obrázků je nutné mít v počítači i knihovnu ImageMagick.\nInstalace mslgen # Prvním krokem pro instalaci programu bude stažení ImageMagick. Navštivte stránku https://imagemagick.org/script/download.php#windows a stáhněte archív ImageMagick-X.Y.Z-Q16-windows.zip. Písmena XYZ označují číslo verze. V čase psaní tohoto článku je aktuální verze ImageMagick-6.5.4-Q16-windows.zip. Obsah tohoto archívu rozbalte někam na disk.\nDalším krokem je instalace programu mslgen. Můžete si vybrat ze 2 způsobů.\nPrvní způsob je stažení souboru /files/mslgen/setup.exe a jeho spuštění. Tento instalační soubor při spuštění zkontroluje, jestli máte v počítači nainstalován .NET Framework správné verze a pokud tomu tak není, nabídne Vám možnost jeho instalace. Program mslgen je potom nainstalován a dostupný přes Start menu.\nDruhý způsob je stažení archívu /files/mslgen/mslgen_1.2.zip, který obsahuje 2 soubory (mslgen.exe a mslgen.exe.config). Obsah tohoto archívu je možné opět kamkoliv rozbalit a spustit soubor mslgen.exe.\nPro zájemce je na adrese /files/mslgen/mslgen_src_1.2.zip celý projekt se zdrojovými soubory.\nPrvní spuštění programu # Při 1. spuštění programu mslgen musíme nastavit cestu k programu conjure. Na obrázku je uvedená cesta D:\\ImageMagick-6.5.4-9\\conjure.exe. Pro výběr umístění souboru conjure.exe stiskněte tlačítko se 3 tečkami v části pojmenované Cesta k programu conjure a vyhledejte soubor conjure.exe v adresáři, kam jste rozbalili ImageMagick. Tento krok je nutný pouze pro 1. spuštění programu. Při jeho ukončení si mslgen cestu k programu conjure uloží.\nZměna rozměrů obrázků # Po spuštění programu nejprve v poli Vyhledat obrázky typů vyberte formáty, které chcete vyhledat. Potom se rozhodněte, jestli chcete, aby mslgen hledal vybrané formáty obrázků jen v adresáři, který vyberete a nebo i v jeho podadresářích. Podle toho zaškrtněte checkbox Vyhledat obrázky v podadresářích. Pro vyhledání samotných obrázků stiskněte tlačítko se 3 tečkami v poli Adresář s obrázky. Zobrazí se dialog pro výběr adresáře. Po výběru adresáře vyhledá program obrázky a začne s generováním náhledů. Generování náhledů je možné zastavit stiskem červeného tlačítka v pravé části statusbaru.\nV části Uložit obrázky jako vyberte formát, ve kterém budou obrázky uloženy. Výchozí hodnotou je volba Ponechat formát, kdy bude obrázek uložen ve stejném formátu. Ostatní volby přinutí conjure převést obrázek na vybraný typ. Hodnota v poli Kvalita pro JPG má význam pro soubory ukládané ve formátu JPEG. Číslo může být v rozsahu 1 - 100.\nDo oblasti pojmenované Max. rozměry obrázků zadejte rozměry výsledných obrázků. Hodnoty odpovídají šířce a výšce. Pokud vyplníte obě hodnoty a necháte aktivní přepínač px, bude výsledný obrázek zmenšen tak, že jeho delší strana bude mít zadanou hodnotu a druhý rozměr bude dopočítán, aby byl zachován poměr stran. V případě, že vyplníte pouze jeden rozměr, bude mít výsledný obrázek právě tento rozměr a druhá strana bude opět dopočítána.\nDalší možností je změna velikosti definovaná procenty z originálních rozměrů. Pro tento způsob aktivujte přepínač označený % a do prvního pole napište hodnotu, kolik procent mají mít nové rozměry.\nPříklad:\n600 x 600 px - obrázky budou mít delší stranu dlouhou 600 bodů a druhý rozměr bude dopočítán tak, aby zůstal zachován poměr stran. 600 x 0 px - obrázky budou široké 600 bodů a výška bude dopočítána. 0 x 600 px - obrázky budou vysoké 600 bodů a šířka bude dopočítána. 20 x 0 % - oba rozměry budou mít 20% z původní velikosti. 0 x 0 px - velikosti obrázků budou zachovány. Pro tento zápis je nutné vybrat formát souboru v poli Uložit obrázky jako. Tento zápis můžete použít, pokud chcete pouze převést obrázky z jednoho formátu do jiného. Checkbox Uložit v paletě RGB přinutí conjure, aby výsledné obrázky byly uloženy v paletě RGB. V opačném případě je paleta stejná, jako u originálu.\nPojmenování cílových obrázků # V oblasti pojmenované Maska pro uložení souboru se definuje název cílových obrázků. V tomto poli musí být vždy uvedeny proměnné [:NAME:] a [:EXT:]. Proměnná [:NAME:] odpovídá jménu souboru bez jeho přípony a adresáře, kde je uložený. Naopak proměnná [:EXT:] odpovídá příponě souboru včetně tečky. Celá maska odpovídá relativnímu umístění vůči adresáři, kde je uložen originální soubor. Pro následující příklady předpokládejme, že originální soubor je C:\\obrazky\\fotka01.jpg a nechceme měnit formát souboru.\nFormát masky:\n[:NAME:]-mini[:EXT:] - obrázek bude uložen jako C:\\obrazky\\fotka01-mini.jpg. Thumb_[:NAME:][:EXT:] - obrázek bude uložen jako C:\\obrazky\\Thumb_fotka01.jpg. nahledy\\[:NAME:][:EXT:] - obrázek bude uložen jako C:\\obrazky\\nahledy\\fotka01.jpg. d1\\d2\\tb_[:NAME:]-mini[:EXT:] - obrázek bude uložen jako C:\\obrazky\\d1\\d2\\tb_fotka01-mini.jpg. Spuštění zpracování obrázků # Po nastavení všech předchozích parametrů spustíte konverzi obrázků tlačítkem Spustit conjure. Po jeho stisknutí zobrazí mslgen dialog pro uložení MSL souboru. Tady pozor. V názvu souboru a celé jeho cestě NESMÍ být diakritika, jinak tento soubor conjure nenajde. Po uložení souboru je spuštěn program conjure v příkazovém řádku.\nPokud v názvu nebo cestě MSL souboru použijete diakritiku, skončíte s chybou conjure.exe: Extra content at the end of the document.\n","date":"12. 8. 2009","externalUrl":null,"permalink":"/clanky/mslgen/","section":"Články","summary":"V článku Hromadné zmenšení velikosti fotek je uveden postup, jak v dávkovém souboru použít program convert z knihovny ImageMagick pro hromadnou změnu rozměrů obrázků. Jednoduchosti a eleganci shellu se nic nevyrovná, ale přeci jen má toto řešení jednu nevýhodu. Nedokáže pracovat se soubory, které mají v názvu diakritiku. Naštěstí je součástí ImageMagick i program conjure. Program conjure se spouští s parametrem, kterým je název souboru v jazyce Magick Scripting Language (MSL). Tento soubor je ve formátu XML a obsahuje instrukce, jak pracovat s obrázky. Například: otevři soubor, uprav jeho rozměry, nastav barevnou paletu a ulož s novým názvem. Názvy souborů v tomto souboru již mohou obsahovat diakritiku.\n","title":"mslgen - hromadná úprava obrázků programem conjure","type":"clanky"},{"content":"Několik fotek z návštěvy přístavu ve městě Klaipeda.\n7 fotografií. Kliknutím otevřete prohlížeč, listovat můžete šipkami nebo tažením prstem.\n","date":"29. 7. 2009","externalUrl":null,"permalink":"/foto/pristav-klaipeda/","section":"Foto koutek","summary":"","title":"Přístav Klaipeda","type":"foto"},{"content":"DataGridView je třída pro zobrazení tabulkových dat. Samotná data můžou být přímo součástí tabulky v kolekcích Rows a Columns nebo mohou pocházet z jiného zdroje navázaného přes DataSource. V našem případě si ukážeme hledání dat z prvního případu, kdy jako motor hledání využijeme LINQ. Vytvoříme si malou aplikaci, která bude obsahovat tabulku DataGridView a jedno tlačítko. Po stisku tlačítka zobrazíme okno, kam může uživatel zadat hledaný text. Zároveň obsahuje volbu, jestli při hledání rozlišovat velikosti písmen.\nNaše tabulka bude mít 3 sloupce pro uložení kódu produktu, jeho názvu a ceny. Nejprve tedy tabulku naplníme daty v konstruktoru třídy.\n// Vychozi data. dataGridView1.Rows.Add(50); for (int Row = 0; Row \u0026lt; 50; Row++) { dataGridView1.Rows[Row].Cells[\u0026#34;KodProduktu\u0026#34;].Value = \u0026#34;PN\u0026#34; + (Row + 1).ToString(); dataGridView1.Rows[Row].Cells[\u0026#34;NazevProduktu\u0026#34;].Value = \u0026#34;Bezva produkt číslo \u0026#34; + (Row + 1).ToString(); dataGridView1.Rows[Row].Cells[\u0026#34;Cena\u0026#34;].Value = Math.Pow(Row + 2, 2); } Editace dat v tabulce # V naší ukázkové aplikaci je v DataGridView povolena editace hodnot. Data ve sloupci Cena jsou uloženy jako Double. Proto musíme ošetřit hodnoty zadané uživatelem do tohoto sloupce. Pro kontrolu hodnot zachytíme událost CellParsing, ve které se zadanou hodnotu pokusíme převést na Double. V případě, že převod na Double neuspěje, uložíme do editované buňky nulu.\n/// \u0026lt;summary\u0026gt;Prevede hodnotu zadanou ve sloupci Cena na typ /// Double, ktera bude ulozena v DataGridViewCell.Value. /// \u0026lt;/summary\u0026gt; private void dataGridView1_CellParsing(object sender, DataGridViewCellParsingEventArgs e) { if (e.ColumnIndex \u0026gt; -1 \u0026amp;\u0026amp; e.RowIndex \u0026gt; -1 \u0026amp;\u0026amp; e.Value != null) { // Jmeno sloupce, ve kterem je editovana bunka. string columnName = dataGridView1.Columns[e.ColumnIndex].Name; if (columnName == \u0026#34;Cena\u0026#34;) { try { // Prevedeni zadaneho textu na Double. string number = e.Value.ToString(); number = number.Replace(\u0026#39;,\u0026#39;, \u0026#39;.\u0026#39;); e.Value = Double.Parse(number); e.ParsingApplied = true; } catch (FormatException) { // Konverze selhala, ulozi se 0. e.Value = 0.0; e.ParsingApplied = true; } } } } Řazení dat ve sloupci # V našem případě mají sloupce v DataGridView vlastnost SortMode rovnu hodnotě Automatic. DataGridView umožňuje řadit zobrazené hodnoty po kliknutí na název sloupce. Protože s hodnotami ve sloupci Cena pracujeme jako s číslem, musíme zachytit událost SortCompare a porovnávat hodnoty ve sloupci Cena jako Double.\n/// \u0026lt;summary\u0026gt;Porovna data ze sloupce Cena jako cislo. /// Ostatni sloupce se porovnavaji jako text. /// \u0026lt;/summary\u0026gt; private void dataGridView1_SortCompare(object sender, DataGridViewSortCompareEventArgs e) { if (e.Column.Name == \u0026#34;Cena\u0026#34;) { double d1, d2; if (!Double.TryParse(e.CellValue1 == null ? \u0026#34;0\u0026#34; : e.CellValue1.ToString(), out d1)) d1 = 0.0; if (!Double.TryParse(e.CellValue2 == null ? \u0026#34;0\u0026#34; : e.CellValue2.ToString(), out d2)) d2 = 0.0; if (d1 \u0026gt; d2) e.SortResult = 1; else if (d1 \u0026lt; d2) e.SortResult = -1; else e.SortResult = 0; e.Handled = true; } } Zachycení stisku kláves Ctrl + F # Protože chceme uživateli nabídnout i trochu rychlejší cestu ke zobrazení okna pro zadání hledaného textu, zachytíme stisk kláves Control + F.\n/// \u0026lt;summary\u0026gt;Zachyti stisk klaves Ctrl+F a zobrazi okno pro hledani. /// \u0026lt;/summary\u0026gt; protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (keyData == (Keys.Control | Keys.F)) { ShowSearchTextForm(); return true; } return base.ProcessCmdKey(ref msg, keyData); } Implementace okna pro zadání hledaného textu # Naše okno pro zadání hledaného textu obsahuje jen 1 TextBox, 1 CheckBox a 1 tlačítko.\nSoučástí naší mini třídy FormSearchText je delegát, který zavoláme při stisku tlačítka Hledat. Při uzavření okna pouze odebereme instanci třídy FormSearchText z pole vlastněných oken rodiče. Pro uzavření okna můžeme stisknout klávesu Escape, kterou zachytíme opět ve funkci ProcessCmdKey. Stisk tlačítka Hledat pouze ověří, jestli je vyplněn text k hledání a pokud ano, zavolá kód spojený s delegátem delTextSearch.\npublic partial class FormSearchText : Form { /// \u0026lt;summary\u0026gt;Delegat volany pri stisku tlacitka Hledat. /// \u0026lt;/summary\u0026gt; public Action\u0026lt;string, bool\u0026gt; delTextSearch; public FormSearchText() { InitializeComponent(); } /// \u0026lt;summary\u0026gt;Pred zavrenim okna odebere nasi instanci z pole /// vlastnenych oken rodice. /// \u0026lt;/summary\u0026gt; private void FormSearchText_FormClosing(object sender, FormClosingEventArgs e) { Owner.RemoveOwnedForm(this); } /// \u0026lt;summary\u0026gt;Zachyti stisk klavesy Escape a zavola funkci Close(). /// \u0026lt;/summary\u0026gt; protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (keyData == Keys.Escape) { Close(); return true; } return base.ProcessCmdKey(ref msg, keyData); } /// \u0026lt;summary\u0026gt;Pri stisku tlacitka Hledat zavola delegata pro hledani /// dat v DataGridView. /// \u0026lt;/summary\u0026gt; private void buttonSearch_Click(object sender, EventArgs e) { // Uzivatel musi vyplnit hedany text. if (textBoxSearch.Text.Trim().Length \u0026gt; 0) { delTextSearch(textBoxSearch.Text, checkBoxCaseSensitive.Checked); } } } Zobrazení okna pro zadání textu a nastavení delegátů # Když máme hotovou třídu, která zobrazí pole pro zadání textu, můžeme se vrátit k naší hlavní třídě a zpracovat požadavek na hledání v DataGridView. Po stisku kláves Ctrl + F nebo stisku tlačítka Hledat voláme funkci ShowSearchTextForm, která přidá třídu FormSearchText mezi námi vlastněná okna a tak si zajistíme, že bude okno pro hledání vždy zobrazeno nad oknem s DataGridView. Pokud by již okno bylo mezi námi vlastněnými, pouze ho zobrazíme a předáme mu fokus.\n// Projde okna ktera vlastnime // a pokud je mezi nimi trida FormSearchText // pouze ji zobrazi a nastavi focus. foreach (Form ownedForm in OwnedForms) { if (ownedForm is FormSearchText) { ownedForm.Show(); ownedForm.Focus(); return; } } V případě, že předchozí kontrola neuspěje, vytvoříme novou instanci třídy FormSearchText, přidáme jí mezi námi vlastněná okna a inicializujeme delegáta delTextSearch. Celý kód přiřazený tomuto delegátovi bude spuštěn po stisku tlačítka Hledat ve třídě FormSearchText. Po inicializaci delegáta zobrazíme novou instanci FormSearchText.\nProtože je celý kód trochu delší, nejprve si vysvětlíme jeho části. Jako první věc, kterou zkontrolujeme je příznak, jestli máme při hledání textu rozlišovat malá a velká písmena. Pokud tomu tak není, převedeme hledaný text na malá písmena.\nDalší část kódu obsahuje definici nového delegáta CellValueMatch, který bude volán pro kontrolu textu v každé buňce v DataGridView. Tento kód kontroluje, jestli hodnota v textových buňkách obsahuje námi hledaný text. Hodnoty ve sloupci Cena naopak převádí na Double a porovnává s hledanou hodnotou převedenou také na Double. CellValueMatch vrací true, pokud najde v buňce hledaný text nebo pokud jsou číselné hodnoty shodné. V opačném případě vrací false. CellValueMatch je následně použitý v LINQ podmínce.\nNakonec se dostáváme k celému motoru hledání, kterým je v našem případě LINQ. Poslední část delegáta tedy zavolá dotaz, který najde 1. buňku v DataGridView, která obsahuje hledaný text. Celý dotaz nejprve převede kolekci Rows na IEnumerable typu DataGridViewRow. Z tohoto seznamu odfiltruje řádek pro zadání nové hodnoty a buňky ve všech ostatních řádcích opět převede na IEnumerable typu DataGridViewCell. Hodnotu každé buňky která není null potom porovná delegátem CellValueMatch. Celý dotaz vrátí 1. buňku, pro kterou CellValueMatch vrátí true.\nV případě, že LINQ nic nenajde, vyhodí volání dotazu vyjímku InvalidOperationException, ve které zobrazíme informaci o tom, že jsme nic nenalezli.\n/// \u0026lt;summary\u0026gt;Zkontroluje, jestli jiz neni okno pro hledani zobrazeno /// a pokud neni, tak ho vytvori a nastavi delegaty pro hledani /// v DataGridView. /// \u0026lt;/summary\u0026gt; private void ShowSearchTextForm() { // Projde okna ktera vlastnime // a pokud je mezi nimi trida FormSearchText // pouze ji zobrazi a nastavi focus. foreach (Form ownedForm in OwnedForms) { if (ownedForm is FormSearchText) { ownedForm.Show(); ownedForm.Focus(); return; } } // Vytvoreni nove instance FormSearchText a nastaveni // metod, pro hledani v datech. FormSearchText searchForm = new FormSearchText(); // Prida novou tridu do seznamu nami vlastnenych oken. AddOwnedForm(searchForm); searchForm.Owner = this; // Delegat spojeny s nasim novym oknem pro hledani. // Tento kod je volany pri stisku tlacitka Hledat // ve tride FormSearchText. searchForm.delTextSearch = (searchText, caseSensitive) =\u0026gt; { // Pokud nerozlisujeme velikost pismen, prevedeme hledany // text na mala pismena. if (!caseSensitive) searchText = searchText.ToLower(); // Porovani obsahu bunky s hledanym textem. Data ve sloupci Cena // se prevadi na Double a porovnavaji se s hledanou hodnotou, // ktera je take prevedena na Double. // Tento kod je volany pro kazdou DataGridViewCell // z nasledujiciho dotazu. Func\u0026lt;DataGridViewCell, bool, string, bool\u0026gt; CellValueMatch = (cell, cSensitive, sText) =\u0026gt; { if (cell.OwningColumn.Name == \u0026#34;Cena\u0026#34;) { try { if (Convert.ToDouble(sText) == Convert.ToDouble(cell.Value)) return true; else return false; } catch (FormatException) { return false; } } else { string cellValue = cell.Value.ToString(); if (!cSensitive) cellValue = cellValue.ToLower(); if (cellValue.IndexOf(sText) \u0026gt; -1) return true; else return false; } }; // Dotaz na data v DataGridView. Prohleda kazdou bunku v tabulce // krome radku pro novy zaznam a vrati 1. DataGridViewCell, // ktera obsahuje hledany text. // Pokud hledani nic nenajde, vyhodi vyjimku InvalidOperationException. try { dataGridView1.CurrentCell = (from dgRow in dataGridView1.Rows.Cast\u0026lt;DataGridViewRow\u0026gt;() where !dgRow.IsNewRow from dgCell in dgRow.Cells.Cast\u0026lt;DataGridViewCell\u0026gt;() where dgCell.Value != null \u0026amp;\u0026amp; CellValueMatch(dgCell, caseSensitive, searchText) select dgCell).First(); } catch (InvalidOperationException) { MessageBox.Show(\u0026#34;Hledaný text nebyl nalezen.\u0026#34;, Text); } }; // Zobrazeni okna pro hledani. searchForm.Show(); } searchdemo.zip ","date":"22. 7. 2009","externalUrl":null,"permalink":"/clanky/linq-a-hledani-v-datagridview/","section":"Články","summary":"DataGridView je třída pro zobrazení tabulkových dat. Samotná data můžou být přímo součástí tabulky v kolekcích Rows a Columns nebo mohou pocházet z jiného zdroje navázaného přes DataSource. V našem případě si ukážeme hledání dat z prvního případu, kdy jako motor hledání využijeme LINQ. Vytvoříme si malou aplikaci, která bude obsahovat tabulku DataGridView a jedno tlačítko. Po stisku tlačítka zobrazíme okno, kam může uživatel zadat hledaný text. Zároveň obsahuje volbu, jestli při hledání rozlišovat velikosti písmen.\n","title":"LINQ a hledání v DataGridView","type":"clanky"},{"content":"Několik fotek z Litvy, okolí města Siauliai.\n6 fotografií. Kliknutím otevřete prohlížeč, listovat můžete šipkami nebo tažením prstem.\n","date":"14. 7. 2009","externalUrl":null,"permalink":"/foto/lithuania-1/","section":"Foto koutek","summary":"","title":"Lithuania 1","type":"foto"},{"content":"Ukázka obrázků Zdendy Kutače. Foceno fotoaparátem Canon EOS 400d.\n4 fotografií. Kliknutím otevřete prohlížeč, listovat můžete šipkami nebo tažením prstem.\n","date":"28. 6. 2009","externalUrl":null,"permalink":"/foto/zdenduv-foto-mix/","section":"Foto koutek","summary":"","title":"Zdendův foto mix","type":"foto"},{"content":"K rozdělení souboru v linuxu můžeme využít program split. Nedávno jsem potřeboval rozdělit obraz DVD Mandrivy na menší kousky. Pro rozdělení na 700 MB části lze spustit split následujícím způsobem: split --bytes=700m mandriva-linux-free-2009.1-x86_64.iso /media/disk/iso/mandriva-linux-free-2009.1-x86_64.iso-\n--bytes=700m - části budou mít velikost max. 700 MB mandriva-linux-free-2009.1-x86_64.iso - zdrojový soubor. V tomto případě z aktuálního adresáře. /media/disk/iso/mandriva-linux-free-2009.1-x86_64.iso- - cesta, kam uložit výsledné části a jejich prefix. Prefix je mandriva-linux-free-2009.1-x86_64.iso- a každá výsledná část bude za tímto textem mít příponu aa, ab, ac … podle počtu částí. Obnovení programem copy ve Windows # Pokud potřebujeme výsledek programu split obnovit ve Windows, můžeme k tomu využít program copy s přepínačem /B. V mém případě vytvořil split 7 částí. Pro jejich spojení dohromady můžeme tedy v konzoli spustit copy následujícím způsobem: copy /B \u0026quot;mandriva-linux-free-2009.1-x86_64.iso-aa\u0026quot;+ \u0026quot;mandriva-linux-free-2009.1-x86_64.iso-ab\u0026quot;+ \u0026quot;mandriva-linux-free-2009.1-x86_64.iso-ac\u0026quot;+ \u0026quot;mandriva-linux-free-2009.1-x86_64.iso-ad\u0026quot;+ \u0026quot;mandriva-linux-free-2009.1-x86_64.iso-ae\u0026quot;+ \u0026quot;mandriva-linux-free-2009.1-x86_64.iso-af\u0026quot;+ \u0026quot;mandriva-linux-free-2009.1-x86_64.iso-ag\u0026quot; d:\\temp\\mandriva-linux-free-2009.1-x86_64.iso\nPůvodní obraz DVD bude uložen v adresáři d:\\temp.\n• Doplněno 5. dubna 2010\nJestli hledáte program pro rozdělení souboru s grafickým rozhraním pro Windows, přečtěte si článek dotsplit - program pro rozdělení souboru.\n","date":"20. 6. 2009","externalUrl":null,"permalink":"/clanky/rozdeleni-souboru-programem-split/","section":"Články","summary":"K rozdělení souboru v linuxu můžeme využít program split. Nedávno jsem potřeboval rozdělit obraz DVD Mandrivy na menší kousky. Pro rozdělení na 700 MB části lze spustit split následujícím způsobem: split --bytes=700m mandriva-linux-free-2009.1-x86_64.iso /media/disk/iso/mandriva-linux-free-2009.1-x86_64.iso-\n--bytes=700m - části budou mít velikost max. 700 MB mandriva-linux-free-2009.1-x86_64.iso - zdrojový soubor. V tomto případě z aktuálního adresáře. /media/disk/iso/mandriva-linux-free-2009.1-x86_64.iso- - cesta, kam uložit výsledné části a jejich prefix. Prefix je mandriva-linux-free-2009.1-x86_64.iso- a každá výsledná část bude za tímto textem mít příponu aa, ab, ac … podle počtu částí. ","title":"Rozdělení souboru programem split a obnovení programem copy","type":"clanky"},{"content":"Pro upload souboru na FTP server v .NET můžeme využít třídu WebClient, která sama zajišťuje komunikaci protokolem FTP. Samotný upload souboru lze potom zapsat pouze několika řádky kódu.\nTřída WebClient je definovaná ve jmenném prostoru System.Net. Následujících několik řádek v C# zajistí přenos souboru.\nusing (ftpClient = new WebClient()) { ftpClient.Proxy = null; ftpClient.Credentials = new NetworkCredential(textBoxJmeno.Text.Trim(), textBoxHeslo.Text.Trim()); try { ftpClient.UploadFile(ftpServerUri + \u0026#34;/\u0026#34; + new FileInfo(localFile).Name, localFile); } catch (Exception ex) { MessageBox.Show(ex.Message); } } Pro zájemce je k dispozici malá aplikace napsaná v C#, kterou lze použít pro upload souboru na FTP server. Zdrojový kód má pouze 104 řádek a většina z nich se stará o kontrolu údajů zadaných uživatelem.\nftpupload.zip ","date":"31. 5. 2009","externalUrl":null,"permalink":"/clanky/upload-souboru-na-ftp-server-tridou-webclient/","section":"Články","summary":"Pro upload souboru na FTP server v .NET můžeme využít třídu WebClient, která sama zajišťuje komunikaci protokolem FTP. Samotný upload souboru lze potom zapsat pouze několika řádky kódu.\n","title":"Upload souboru na FTP server třídou WebClient","type":"clanky"},{"content":"Další fotky ze Dne otevřených dveří v Čáslavi. Tentokrát v lepší kvalitě. :)\n59 fotografií. Kliknutím otevřete prohlížeč, listovat můžete šipkami nebo tažením prstem.\n","date":"24. 5. 2009","externalUrl":null,"permalink":"/foto/open-day-caslav-2009-pokracovani/","section":"Foto koutek","summary":"","title":"Den otevřených dveří v Čáslavi 2009 - pokračování","type":"foto"},{"content":"Několik fotek ze Dne otevřených dveří na letecké základně v Čáslavi z 23. května 2009.\nUkázka souboje se vzdušnou podporou Mi-24 Hind na YouTube.\n56 fotografií. Kliknutím otevřete prohlížeč, listovat můžete šipkami nebo tažením prstem.\n","date":"24. 5. 2009","externalUrl":null,"permalink":"/foto/open-day-caslav-2009/","section":"Foto koutek","summary":"Několik fotek ze Dne otevřených dveří na letecké základně v Čáslavi z 23. května 2009.\n","title":"Den otevřených dveří v Čáslavi 2009","type":"foto"},{"content":"Pro dávkovou změnu velikosti fotek můžeme využít open source knihovny ImageMagick. Ke stažení je na adrese https://imagemagick.org/. Součástí balíku je program convert, který umí převádět obrázky mezi velkým množstvím formátů, měnit jejich velikost, barevnou paletu nebo například vkládat text.\nPro změnu velikosti slouží parametr resize, za který lze uvést maximální rozměry výsledného obrázku. Například následující příkaz změní velikost obrázku foto1.jpg tak, že jeho šířka nebo výška bude maximálně 400 bodů a bude zachován poměr stran. Výsledný soubor bude uložen jako foto2.jpg.\nconvert -resize 400x400 foto1.jpg foto2.jpg Hodnotu parametru resize je možné zapsat jako 400x, kdy bude výsledný obrázek široký 400 bodů. Naopak zápisem x400 docílíme pevné výšky obrázku 400 bodů. Oba zápisy zachovávají poměr stran. Všechny způsoby, jak lze zapsat výsledné rozměry najdete na https://imagemagick.org/script/command-line-processing.php#geometry.\nDávková změna rozměrů ve Windows # Pokud máme v adresáři spoustu fotek, které chceme zmenšit, můžeme si napsat krátkou dávku, která najde obrázky a uloží jejich zmenšené kopie. Nejprve musíme stáhnout balík programů. Pro Windows je k dispozici několik verzí. Osobně doporučuji ImageMagick-6.5.2-Q16-windows.zip (číslo verze se může lišit), která se nemusí instalovat a stačí obsah archívu pouze rozbalit do adresáře. Našim záměrem bude najít všechny soubory s příponou jpg v adresáři, jejich zmenšení na max. rozměr 400 bodů a uložení v barevné paletě RGB. Pokud by zdrojové obrázky byly uloženy v paletě CMYK a chtěli bychom je zobrazit na webu, mohli bychom narazit na neschopnost Internet Exploreru je zobrazit. Zároveň snížíme kvalitu výsledných fotek na 90%, aby soubory zabíraly méně místa. V textovém editoru (například Poznámkový blok nebo Notepad++) napište následující text a soubor uložte do adresáře s fotkami jako convert.cmd.\n@for /r %%i in (*.jpg) do call :convert \u0026#34;%%~fi\u0026#34; @goto :EOF :convert @d:\\ImageMagick-6.5.2-4\\convert.exe -strip -resize 400x400 -quality 90 -colorspace rgb \u0026#34;%~f1\u0026#34; \u0026#34;%~f1.converted.jpg\u0026#34; @goto :EOF Tento skript vyhledá v adresáři, kde je uložen a v jeho podadresářích všechny soubory s příponou jpg a uloží zmenšené kopie ke zdrojovým fotkám, ale za jejich název přidá text converted.jpg. Cestu k programu convert upravte podle místa, kam jste rozbalili ImageMagick.\n• Doplněno 23. července 2009\nVolání programu convert z dávky v příkazovém řádku si neporadí se soubory nebo adresáři, které mají v názvu diakritiku. Jediný způsob jak výše uvedený postup použít, o kterém vím že funguje, je vyhození diakritiky z názvů souborů a adresářů.\n• Doplněno 13. srpna 2009\nPokud potřebujete hromadně změnit rozměry nebo formáty obrázků, které mají v názvu diakritiku, případně jen požadujete program s uživatelským rozhraním, přečtěte si článek mslgen - hromadná úprava obrázků programem conjure.\n","date":"16. 5. 2009","externalUrl":null,"permalink":"/clanky/hromadne-zmeneni-velikosti-fotek/","section":"Články","summary":"Pro dávkovou změnu velikosti fotek můžeme využít open source knihovny ImageMagick. Ke stažení je na adrese https://imagemagick.org/. Součástí balíku je program convert, který umí převádět obrázky mezi velkým množstvím formátů, měnit jejich velikost, barevnou paletu nebo například vkládat text.\n","title":"Hromadné zmenšení velikosti fotek","type":"clanky"},{"content":"Několik fotek z bývalého prostoru obývaného Sovětskou armádou.\nDatum pořízení 26. ledna 2008.\n54 fotografií. Kliknutím otevřete prohlížeč, listovat můžete šipkami nebo tažením prstem.\n","date":"25. 4. 2009","externalUrl":null,"permalink":"/foto/vojensky-prostor-milovice/","section":"Foto koutek","summary":"","title":"Vojenský prostor Milovice","type":"foto"},{"content":"Při psaní aplikací v C# jsem se ze začátku setkával s problémem, jak přistupovat k mySQL databázi z více tříd v programu. V C# neexistují globální proměnné, jako je tomu například v C++. Pokud máme v aplikaci například více oken odvozených od třídy Form a každé z nich musí komunikovat s databází, nemůžeme se spolehnout na globální instanci MySqlConnection, protože ve stylu C++ jí nevytvoříme. Jednou z možností, jak se spojit s databází je vytvořit si k ní nové spojení při každém otevření okna. Tento způsob ale asi nebude moc efektivní, přeci jen inicializace spojení k serveru stojí nějaký čas a asi je zbytečné, když bude mít jedna aplikace aktivní 3 spojení s databází. Pro tento problém si můžeme vytvořit singleton třídu, která bude uchovávat pole všech použitých MySqlConnection objektů.\nVytvoříme si tedy třídu ConnectionPool s následujícími vlastnostmi:\nposkytuje statickou metodu Instance, kterou stačí zavolat jen jednou před 1. použití a která vytvoří instanci samotné třídy nabízí metodu GetConnection, kterou získáme objekt třídy MySqlConnection z pole metodou AddConnection přidáme do pole nové spojení k databázi Třída ConnectionPool vnitřně pracuje s polem tříd SingleConnection, která si udržuje objekt MySqlConnection a která sama zajišťuje spojení s databázovým serverem. Při neúspěchu vrací zpět informaci o chybě Message z vyjímky MySqlException.\nNejprve tedy vytvoříme třídu SingleConnection, se kterou budeme následně pracovat. Obsahuje pouze konstruktor, vlastnost IsConnectionOpen a 2 proměnné. Proměnné, které budeme potřebovat jsou objekty tříd MySqlConnection, který udržuje spojení k mySQL a String který obsahuje popis chyby, pokud selže volání metody Open třídy MySqlConnection. Konstruktoru předáváme adresu mySQL serveru, jméno uživatele, heslo, název databáze, příkaz, který se má provést po úspěšném připojení k serveru a případný suffix, který se připojí ke ConnectionStringu.\nImplementace třídy SingleConnection # Parametry konstruktoru dbInitCommand a dbConnectionStringSuffix si zaslouží trochu vysvětlení.\ndbInitCommand se provede při úspěšném spojení s databází. Využít se může například pro určení znakové sady klienta. Například set names cp1250; dbConnectionStringSuffix se zase připojí ke ConnectionStringu ještě před voláním metody Open třídy MySqlConnection. Například CharSet=latin2; Výpis třídy SingleConnection:\nclass SingleConnection { public MySqlConnection Connection = null; public String ConnectionErrorString = \u0026#34;\u0026#34;; public SingleConnection(String dbServer, String dbUser, String dbPassword, String dbDatabase, String dbInitCommand, String dbConnectionStringSuffix) { if (IsConnectionOpen) Connection.Close(); ConnectionErrorString = \u0026#34;\u0026#34;; String connStr = String.Format(\u0026#34;server={0}; user id={1}; password={2}; database={3}; pooling=false;\u0026#34;, dbServer, dbUser, dbPassword, dbDatabase); connStr += dbConnectionStringSuffix; try { Connection = new MySqlConnection(connStr); Connection.Open(); if (dbInitCommand.Length \u0026gt; 0) { MySqlCommand cmdIniCP = new MySqlCommand(dbInitCommand, Connection); cmdIniCP.ExecuteNonQuery(); } } catch (MySqlException ex) { ConnectionErrorString = ex.Message; if (Connection != null) { Connection.Close(); Connection = null; } } } public bool IsConnectionOpen { get { if (Connection == null) return false; if (Connection.State == System.Data.ConnectionState.Open) return true; else return false; } } } Vlastnost IsConnectionOpen pouze zkontroluje, jestli existuje objekt MySqlConnection a jestli je jeho stav roven System.Data.ConnectionState.Open. Je následně využitá třídou ConnectionPool.\nImplementace třídy ConnectionPool # ConnectionPool udržuje seznam aktivních spojení k databázím v poli Connections, které je tvořeno třídou Dictionary.\nstatic Dictionary\u0026lt;String, SingleConnection\u0026gt; Connections = new Dictionary\u0026lt;String, SingleConnection\u0026gt;(); Před 1. použitím třídy musíme zavolat její metodu Instance, která vytvoří novou instanci ConnectionPool ale pouze v případě, že ještě neexistuje. Všechny metody třídy ConnectionPool jsou statické. Mimo Instance máme ještě k dispozici metodu GetConnection, která vrací objekt typu MySqlConnection z pole Connections. Další dostupnou metodou je AddConnection, která zajistí vytvoření nového spojení k databázi, pokud ještě neexistuje.\nVýpis třídy ConnectionPool:\npublic class ConnectionPool { static readonly object padlock = new object(); static ConnectionPool instance = null; static Dictionary\u0026lt;String, SingleConnection\u0026gt; Connections = new Dictionary\u0026lt;String, SingleConnection\u0026gt;(); // jedina instance tridy ConnectionPool spolecna celemu programu public static ConnectionPool Instance { get { lock (padlock) { if (instance == null) { instance = new ConnectionPool(); } return instance; } } } // konstruktor tridy volany pri 1. pouziti vlastnosti Instance private ConnectionPool() { // odstraneni vsech spojeni na databazi v poli Connections.Clear(); } // escape uvozovek a stredniku static public String EscapeData(String srcStr) { String retStr = srcStr.Trim(); retStr = retStr.Replace(\u0026#34;\\\\\u0026#34;, \u0026#34;\\\\\\\\\u0026#34;); retStr = retStr.Replace(\u0026#34;\u0026#39;\u0026#34;, \u0026#34;\\\\\u0026#39;\u0026#34;); retStr = retStr.Replace(\u0026#34;\\\u0026#34;\u0026#34;, \u0026#34;\\\\\\\u0026#34;\u0026#34;); return retStr; } // vraci MySqlConnection urciteho spojeni static public MySqlConnection GetConnection(String ConnectionName) { MySqlConnection conn = null; try { conn = Connections[ConnectionName].Connection; } catch (KeyNotFoundException) { return null; } return conn; } // vytvori nove spojeni s mySQL v poli static public MySqlConnection AddConnection(String ConnectionName, String ConnectionServer, String ConnectionUser, String ConnectionPassword, String ConnectionDatabase, String ConnectionInitCommand, String ConnectionConnectionStringSuffix, out String ErrorString) { ErrorString = \u0026#34;\u0026#34;; // test, jestli toto spojeni jiz existuje MySqlConnection conn = GetConnection(ConnectionName); if (conn == null) { // vytvoreni noveho SingleConnection singConn = new SingleConnection(ConnectionServer, ConnectionUser, ConnectionPassword, ConnectionDatabase, ConnectionInitCommand, ConnectionConnectionStringSuffix); // vyskytla se chyba? if (singConn.ConnectionErrorString.Length \u0026gt; 0) { // ulozeni popisu chyby ErrorString = singConn.ConnectionErrorString; // funkce vraci null (nastaveno vysledkem volani funkce GetConnection(ConnectionName)) } else { // pridani noveho spojeni do pole Connections.Add(ConnectionName, singConn); conn = GetConnection(ConnectionName); } } return conn; } } Použití v aplikaci # Mějme 2 WinFrom třídy Form1 a Form2. Form1 je hlavní okno aplikace a Form2 je z ní volán. Celá aplikace potřebuje spojení ke 2 databázím. Ve Form1 zavoláme při startu metodu Instance a Connect2Databases.\nusing Wiedemann; public class Form1 : Form { private ConnectionPool ConnectionPoolInstance = ConnectionPool.Instance; // konstruktor tridy public Form1() { InitializeComponent(); if (!Connect2Databases()) { throw new Wiedemann.ConnectionFailedException(); } LoadSomeRecordsFromDatabase(); } // spojeni k databazim bool Connect2Databases() { String ErrorString; MySqlConnection conn1 = ConnectionPool.AddConnection(\u0026#34;spojeni_k_databazi_1\u0026#34;, \u0026#34;server1\u0026#34;, \u0026#34;uzivatel1\u0026#34;, \u0026#34;heslo1\u0026#34;, \u0026#34;databaze1\u0026#34;, \u0026#34;\u0026#34;, \u0026#34;CharSet=latin2;\u0026#34;, out ErrorString); if (ErrorString.Length \u0026gt; 0) { MessageBox.Show(ErrorString); return false; } MySqlConnection conn2 = ConnectionPool.AddConnection(\u0026#34;spojeni_k_databazi_2\u0026#34;, \u0026#34;server2\u0026#34;, \u0026#34;uzivatel2\u0026#34;, \u0026#34;heslo2\u0026#34;, \u0026#34;databaze2\u0026#34;, \u0026#34;\u0026#34;, \u0026#34;\u0026#34;, out ErrorString); if (ErrorString.Length \u0026gt; 0) { MessageBox.Show(ErrorString); return false; } return true; } // nacteni zaznamu z databaze void LoadSomeRecordsFromDatabase() { MySqlConnection connection = ConnectionPool.GetConnection(\u0026#34;spojeni_k_databazi_1\u0026#34;); if (connection != null) { String query = \u0026#34;select bool_column, string_column from table\u0026#34;; MySqlCommand commLoad = new MySqlCommand(query, connection); MySqlDataReader reader = commLoad.ExecuteReader(); while (reader.Read()) { if (reader.GetBoolean(0)) MessageBox.Show(reader.GetString(1)); } reader.Close(); } } // funkce volana pri stisku tlacitka buttonForm2, ktera otevre nasi Form2 private void buttonForm2_Click(object sender, EventArgs e) { using (Form2 form2 = new Form2()) { form2.ShowDialog(this); } } } V naší třídě Form2 již Instance volat nemusíme. Následující příklad načte data z druhé databáze.\nusing Wiedemann; public class Form2 : Form { // konstruktor tridy public Form2() { InitializeComponent(); LoadOtherRecordsFromDatabase(); } // nacteni zaznamu z druhe databaze void LoadOtherRecordsFromDatabase() { MySqlConnection connection = ConnectionPool.GetConnection(\u0026#34;spojeni_k_databazi_2\u0026#34;); if (connection != null) { String query = \u0026#34;select bool_column, string_column from other_table\u0026#34;; MySqlCommand commLoad = new MySqlCommand(query, connection); MySqlDataReader reader = commLoad.ExecuteReader(); while (reader.Read()) { if (reader.GetBoolean(0)) MessageBox.Show(reader.GetString(1)); } reader.Close(); } } } Zdrojový soubor třídy:\nconnectionpool.zip ","date":"5. 4. 2009","externalUrl":null,"permalink":"/clanky/csharp-singleton-pro-mysql/","section":"Články","summary":"Při psaní aplikací v C# jsem se ze začátku setkával s problémem, jak přistupovat k mySQL databázi z více tříd v programu. V C# neexistují globální proměnné, jako je tomu například v C++. Pokud máme v aplikaci například více oken odvozených od třídy Form a každé z nich musí komunikovat s databází, nemůžeme se spolehnout na globální instanci MySqlConnection, protože ve stylu C++ jí nevytvoříme. Jednou z možností, jak se spojit s databází je vytvořit si k ní nové spojení při každém otevření okna. Tento způsob ale asi nebude moc efektivní, přeci jen inicializace spojení k serveru stojí nějaký čas a asi je zbytečné, když bude mít jedna aplikace aktivní 3 spojení s databází. Pro tento problém si můžeme vytvořit singleton třídu, která bude uchovávat pole všech použitých MySqlConnection objektů.\n","title":"C# singleton pro přístup k více mySQL databázím","type":"clanky"},{"content":"Nedávno se ke mě dostalo nařízení rady MěstNV z roku 1966 o zákazu vstupu vlasatců (mániček) do restaurací, divadla a jiných veřejných prostor.\nZN: 2380/K1/AB/66\nV Poděbradech dne 10. října 1966\nRada MěstNV v Poděbradech vedena snahou o zajištění veřejného pořádku a zdraví ve městě vydává toto rozhodnutí:\nZakazuje vstup vlasatcům (máničkám)\ndo všech restaurací, vináren a kaváren II. třídy, to znamená do podniků PRAHA, Bílá růže, SAVOY, HUBERT, KOLONÁDA, LIBENSKÝ, do všech ubytoven a hotelů ve městě, do všech objektů čs. státních lázní v Poděbradech, do prostor náměstí Míru a parku Julia Fučíka, do divadla, kina, knihovny a ostatních kulturních zařízení ve městě, pořadatelé kulturních a osvětových pořadů nebudou používat účinkující, jejichž vzhled připomíná osoby výše uvedeného popisu. Pokud nebudou někteří jedinci respektovat rozhodnutí, odmítne je personál obsluhovat a odpovědný vedoucí je požádá, aby opustili místnost. Neuposlechnou-li ani potom, požádá o zákrok Veřejnou bezpečnost.\nOdůvodnění:\nV poslední době některé skupiny mládeže i v našem městě s oblibou a provokativně nosí dlouhé neupravené vlasy, chodí v uměle opotřebovaném oděvu, bosí a špinaví. Jejich chování je bezohledné a hrubé a odporuje normám socialistického soužití. Občané, lázeňští hosté a cizinci poukazují s odporem na tento úchylný zjev, který nese sebou nebezpečí šíření některých nemocí a rušení veřejného pořádku. Za \u0026quot;máničky\u0026quot; - vlasatce - jsou považovány osoby s enormně dlouhými vlasy, neupraveným zevnějškem a jejichž chování je nevhodné a vulgární.\nPřitom nemusí splňovat všechny uvedené znaky současně.\nZa dodržování tohoto rozhodnutí odpovídají příslušní vedoucí objektů a pořadatelé kulturně osvětových akcí.\nRozhodnutí nabývá platnosti dnem 15.10.1966.\n","date":"21. 3. 2009","externalUrl":null,"permalink":"/clanky/manicky-v-podebradech/","section":"Články","summary":"Nedávno se ke mě dostalo nařízení rady MěstNV z roku 1966 o zákazu vstupu vlasatců (mániček) do restaurací, divadla a jiných veřejných prostor.\n","title":"Máničky v Poděbradech","type":"clanky"},{"content":"Bylo nebylo, ale asi bylo, jedno pěkné stavení se postavilo. Asi se tam i pěkně žilo. Prostor kolem, samá louka, co se stalo, vítr fouká. Mraky táhnou na to místo, bordel je tam, kde bylo čisto.\nDalší kouzelné místo, tak jak ho zachytil Kuris 20. října 2007.\n8 fotografií. Kliknutím otevřete prohlížeč, listovat můžete šipkami nebo tažením prstem.\n","date":"20. 3. 2009","externalUrl":null,"permalink":"/foto/opustene-staveni/","section":"Foto koutek","summary":"Bylo nebylo, ale asi bylo, jedno pěkné stavení se postavilo. Asi se tam i pěkně žilo. Prostor kolem, samá louka, co se stalo, vítr fouká. Mraky táhnou na to místo, bordel je tam, kde bylo čisto.\n","title":"Paradisus en terrester","type":"foto"},{"content":"","date":"15. 3. 2009","externalUrl":null,"permalink":"/tags/c/c++/","section":"Tags","summary":"","title":"C/C++","type":"tags"},{"content":"Potřeboval jsem napsat program, který bude stahovat stránky a hledat v nich informace. Když jsem přemýšlel o tom, jak zajistit stažení požadované stránky a její uložení do souboru, jako nejjednodušší řešení mi připadalo použít program wget. Je to vynikající nástroj pro neinteraktivní stahování obsahu z webu.\nPro moje účely bylo nutné spouštět wget i s parametrem, kam má obsah stránky ukládat, abych v něm mohl později hledat.\nwget -q -Oindex.html parametr q určuje, že wget nebude vypisovat informace o průběhu stahování parametr O říká, kam uložit obsah požadované stránky poslední parametr je požadovaná adresa OK, věděl jsem tedy, jak chci volat wget. Jenže jak to zajistit z programu, který je napsán v C++? Například funkcí execvp(). Funkce z rodiny exec() spustí požadovaný program a to tak, že volající proces nahradí volaným. Funkce execvp() má 2 parametry, kde 1. je jméno programu, který se má spustit a 2. je seznam parametrů, které mu budou předány. Poslední v seznamu parametrů musí být NULL. První v seznamu musí být jméno volaného programu. Pro tento program to potom bude argv[0].\nPoužití je tedy následující:\nchar *arg_list[5]; arg_list[0] = \u0026#34;wget\u0026#34;; arg_list[1] = \u0026#34;-q\u0026#34;; arg_list[2] = \u0026#34;-Oindex.html\u0026#34;; arg_list[3] = \u0026#34;\u0026#34;; arg_list[4] = NULL; execvp(\u0026#34;wget\u0026#34;, arg_list); Jenže je tady další problém. Funkce execvp() nahradí původní proces tím, který spouští. Proto se před jejím voláním musí udělat kopie hlavního procesu a z této kopie zavolat funkci execvp(). To zajistí funkce fork(). Funkce fork() vytvoří kopii procesu, ze kterého je volána. Program (rodič i potomek) pokračuje od místa volání. Rozdíl je pouze v návratové hodnotě z funkce fork(). Procesu rodiče vrátí PID potomka, procesu potomka vrací 0.\npid_t child_pid = fork(); if (child_pid != 0) cout \u0026lt;\u0026lt; \u0026#34;Tohle vypisuje rodic.\u0026#34; \u0026lt;\u0026lt; endl; else cout \u0026lt;\u0026lt; \u0026#34;Tohle vypisuje potomek.\u0026#34; \u0026lt;\u0026lt; endl; Poslední věc je synchronizace procesů rodiče a potomka. Po vytvoření nového procesu, musí rodič počkat, než proces potomka skončí. Čekání na dokončení procesu má za úkol funkce waitpid(). PID potomka vrací funkce fork(), takže rodič ví, na který proces má čekat.\npid_t child_pid = fork(); if (child_pid != 0) { int waitstatus; cout \u0026lt;\u0026lt; \u0026#34;Cekam na dokonceni procesu \u0026#34; \u0026lt;\u0026lt; child_pid \u0026lt;\u0026lt; endl; waitpid(child_pid, \u0026amp;waitstatus, 0); cout \u0026lt;\u0026lt; \u0026#34;OK, je po nem\u0026#34; \u0026lt;\u0026lt; endl; } A aby byl život jednodušší, vznikla třída Cwgethelper, která má za úkol spustit wget s parametry, co má kam uložit a počkat, než wget skončí.\nPříklad použití # Cwgethelper *pwgethelper; pwgethelper = new Cwgethelper; pwgethelper-\u0026gt;download(\u0026#34;index.html\u0026#34;, \u0026#34;\u0026#34;); delete pwgethelper; Pracující inteligence je ve třídě zastoupená funkcemi runwget() a download().\npid_t Cwgethelper::runwget(char **arg_list) { child_pid = fork(); if (child_pid != 0) return(child_pid); else { execvp(WGET, arg_list); cerr \u0026lt;\u0026lt; \u0026#34;Chyba pri volani funkce execvp()\u0026#34; \u0026lt;\u0026lt; endl; abort(); } } bool Cwgethelper::download(const char *saveto, const char *url) { strncpy(argv2, \u0026#34;-O\u0026#34;, MAX_BUFFER_SIZE - 1); strncat(argv2, saveto, MAX_BUFFER_SIZE - 3); strncpy(argv3, url, MAX_BUFFER_SIZE - 1); argv2[MAX_BUFFER_SIZE - 1] = 0; argv3[MAX_BUFFER_SIZE - 1] = 0; char *arg_list[5]; arg_list[0] = argv0; arg_list[1] = argv1; arg_list[2] = argv2; arg_list[3] = argv3; arg_list[4] = argv4; unlink(saveto); runwget(arg_list); while (waitpid(child_pid, \u0026amp;waitstatus, 0) \u0026lt; 0) { cerr \u0026lt;\u0026lt; \u0026#34;chyba : waitpid \u0026#34; \u0026lt;\u0026lt; child_pid \u0026lt;\u0026lt; endl; if (errno != EINTR) { waitstatus = -1; return false; } } return true; } Zdrojové soubory třídy:\nwgethelper.cpp wgethelper.h ","date":"15. 3. 2009","externalUrl":null,"permalink":"/clanky/cwgethelper-prace-s-programem-wget/","section":"Články","summary":"Potřeboval jsem napsat program, který bude stahovat stránky a hledat v nich informace. Když jsem přemýšlel o tom, jak zajistit stažení požadované stránky a její uložení do souboru, jako nejjednodušší řešení mi připadalo použít program wget. Je to vynikající nástroj pro neinteraktivní stahování obsahu z webu.\n","title":"Cwgethelper - práce s programem wget z C++","type":"clanky"},{"content":"Třída C2Darray vytváří dynamicky 2D pole objektů operátorem new. Může se použít pro číselné typy (long, int, double) nebo pro třídy. V souboru 2darray.h je definován datový typ ARRAY_TYPE, se kterým třída vnitřně pracuje. Například:typedef unsigned long ARRAY_TYPE;\nInicializace pole # Před začátkem práce s polem je nejprve nutné zajistit jeho inicializaci. Tím se rozumí vytvoření matice ukazatelů na objekty uložené v poli. To zajistí funkce SetSize(), které se předává počet řádků a sloupců v poli.\nvoid C2Darray::SetSize(unsigned long uRows, unsigned long uCols) { if (m_pRoot) Free(); unsigned long i, j; // 1. sloupec pointru m_pRoot = new ARRAY_TYPE**[uRows]; // radky v 1. sloupci pointru for (i = 0; i \u0026lt; uRows; i++) { m_pRoot[i] = new ARRAY_TYPE*[uCols]; for (j = 0; j \u0026lt; uCols; j++) { m_pRoot[i][j] = new ARRAY_TYPE; } } m_Rows = uRows; m_Cols = uCols; } Zrušení pole # Voláním funkce Free() se provede uvolnění objektů a matice ukazatelů z paměti. Tuto funkci volá destruktor třídy C2DArray. Stejně tak je volána ve funkci SetSize() v případě, že je již vytvořena matice ukazatelů.\nvoid C2Darray::Free() { unsigned long i, j; if (m_pRoot == NULL) return; for (i = 0; i \u0026lt; m_Rows; i++) { for (j = 0; j \u0026lt; m_Cols; j++) { delete m_pRoot[i][j]; } delete m_pRoot[i]; } delete m_pRoot; m_pRoot = NULL; m_Rows = 0; m_Cols = 0; } Přístup k prvkům v poli # Pro přístup k objektům uloženým v poli slouží funkce GetAt() a GetAtPtr(). Funkce GetAt() vrací samotný objekt, takže její použití doporučuji v případě, pokud třída vnitřně pracuje s číselnými typy jako jsou int nebo double. Naopak v případech, kdy je ARRAY_TYPE struktura nebo jiná třída, doporučuji použít funkci GetAtPtr(), která vrací ukazatel na požadovaný objekt.\nARRAY_TYPE C2Darray::GetAt(unsigned long uRow, unsigned long uCol) { assert(uRow \u0026lt; m_Rows); assert(uCol \u0026lt; m_Cols); return *(m_pRoot[uRow][uCol]); } ARRAY_TYPE* C2Darray::GetAtPtr(unsigned long uRow, unsigned long uCol) { assert(uRow \u0026lt; m_Rows); assert(uCol \u0026lt; m_Cols); return (m_pRoot[uRow][uCol]); } Změna hodnoty objektu # Změnit hodnotu objektu je možné funkcí SetAt(). Její použití doporučuji pouze v případě, kdy je ARRAY_TYPE číselný typ (int, long, double). V ostatních případech doporučuji použít GetAtPtr() pro získání ukazatele na objekt a měnit jeho členy přes tento ukazatel.\nvoid C2Darray::SetAt(unsigned long uRow, unsigned long uCol, ARRAY_TYPE value) { assert(uRow \u0026lt; m_Rows); assert(uCol \u0026lt; m_Cols); *(m_pRoot[uRow][uCol]) = value; } Zdrojové soubory třídy:\n2darray.cpp 2darray.h ","date":"15. 3. 2009","externalUrl":null,"permalink":"/clanky/c2darray-dynamicke-2d-pole/","section":"Články","summary":"Třída C2Darray vytváří dynamicky 2D pole objektů operátorem new. Může se použít pro číselné typy (long, int, double) nebo pro třídy. V souboru 2darray.h je definován datový typ ARRAY_TYPE, se kterým třída vnitřně pracuje. Například:typedef unsigned long ARRAY_TYPE;\n","title":"C2Darray - dynamické 2D pole v C++","type":"clanky"},{"content":"CNetworkCommunication je třída odvozená z CAsyncSocket, napsaná pro příjem a vysílání paketů protokolem UDP. Je závislá na funkcích MFC. Před jejím použitím je třeba zavolat funkci AfxSocketInit(), například při spuštění aplikace ve funkci InitInstance().\nK použití jsou funkce:\nbool InitializeInterface(UINT port); int ReceiveData(BYTE *p_buffer, DWORD bufferSize, DWORD *p_readed); int TransmitData(BYTE *p_buffer, DWORD n_count, CString address, UINT port, DWORD *p_wrote); V souboru NetworkCommunication.h jsou definovány hodnoty pro maximální čas (ms), který čeká funkce ReceiveData na příchozí data a jejich návratové hodnoty.\n#define NW_MAX_RESPONSE_TIME 500 #define NW_ALL_OK 0x00 #define NW_NO_DATA_IN_QUEUE 0x01 #define NW_IO_ERROR 0x03 Pro příjem a posílání dat je nejprve nutné zavolat funkci InitializeInterface, která inicializuje sokety pro příjem a vysílání. Parametr port určuje, ze kterého portu budou čtena data.\nbool CNetworkCommunication::InitializeInterface(UINT port) { // vytvoreni soketu this (prijem) if(!Create(port, SOCK_DGRAM, FD_READ)) return false; BOOL bMultipleApps = TRUE; SetSockOpt(SO_REUSEADDR, (void*)\u0026amp;bMultipleApps, sizeof(BOOL), SOL_SOCKET); // nastaveni velikosti prichoziho bufferu int iBufferSize = 131072; BOOL bRet = SetSockOpt(SO_RCVBUF, (void*)\u0026amp;iBufferSize, sizeof(int), SOL_SOCKET); ASSERT(bRet); // vytvoreni soketu pro vysilani if(!send.Create(0, SOCK_DGRAM, 0)) { return false; } return true; } Příjem nových dat # Pro získání nových dat slouží funkce ReceiveData se 3 parametry: BYTE *p_buffer, DWORD bufferSize, DWORD *p_readed.\nBYTE *p_buffer - buffer, kam se uloží nová data DWORD bufferSize - velikost p_buffer DWORD *p_readed - počet dat, uložených v p_buffer Výpis funkce:\nint CNetworkCommunication::ReceiveData(BYTE *p_buffer, DWORD bufferSize, DWORD *p_readed) { DWORD dwLen; DWORD dwTick1 = GetTickCount(); l_read_again: #ifdef LOGGING FormatLog(fLogStatus, _T(\u0026#34;CNetworkCommunication::ReceiveData - l_read_again label\u0026#34;), LOG_NEWLINE | LOG_LOGTIME); #endif if (!IOCtl(FIONREAD, \u0026amp;dwLen)) return NW_IO_ERROR; // test, jestli buffer obsahuje data // pokud nejsou data k dispozici, zkousi nacitat max. cas NW_MAX_RESPONSE_TIME if (dwLen \u0026lt; 1) { if ((GetTickCount() - dwTick1) \u0026gt; NW_MAX_RESPONSE_TIME) return NW_NO_DATA_IN_QUEUE; else { Sleep(1); goto l_read_again; } } // nacteni dat int error = ReceiveFrom (p_buffer, bufferSize, senderip, senderport); #ifdef LOGGING // logovani nactenych dat DWORD log_counter; CString str, str_temp; if (error \u0026gt; 0) { str = _T(\u0026#34;CNetworkCommunication::ReceiveData data in -\u0026gt;\u0026#34;); for (log_counter = 0; log_counter \u0026lt; (DWORD)error; log_counter++) { str_temp.Format(_T(\u0026#34; 0x%02X\u0026#34;), p_buffer[log_counter]); str += str_temp; if (iswprint((wint_t)p_buffer[log_counter])) { str_temp.Format(_T(\u0026#34; (%c)\u0026#34;), p_buffer[log_counter]); str += str_temp; } } FormatLog(fLogStatus, str, LOG_NEWLINE | LOG_LOGTIME); } else { FormatLog(fLogStatus, _T(\u0026#34;CNetworkCommunication::ReceiveData data in -\u0026gt; no data\u0026#34;), LOG_NEWLINE | LOG_LOGTIME); } #endif if(error == SOCKET_ERROR) { return NW_IO_ERROR; } else { // pocet nactenych dat *p_readed = error; return NW_ALL_OK; } } Odesílání dat # Pro odeslání dat je k dispozici funkce TransmitData s 5 parametry: BYTE *p_buffer, DWORD n_count, CString address, UINT port, DWORD *p_wrote.\nBYTE *p_buffer - buffer, kde jsou data k vyslání DWORD n_count - počet dat v p_buffer CString address - adresa počítače, na který mají být data vyslána UINT port - port, na kterém cílový počítač naslouchá DWORD *p_wrote - počet skutečně vyslaných dat Výpis funkce:\nint CNetworkCommunication::TransmitData(BYTE *p_buffer, DWORD n_count, CString address, UINT port, DWORD *p_wrote) { // vyslani dat int error = send.SendTo((BYTE*)p_buffer, n_count, port, address); if (error == SOCKET_ERROR) return NW_IO_ERROR; #ifdef LOGGING // logovani vyslanych dat DWORD log_counter; CString str, str_temp; str = _T(\u0026#34;CNetworkCommunication::TransmitData data out -\u0026gt;\u0026#34;); for (log_counter = 0; log_counter \u0026lt; n_count; log_counter++) { str_temp.Format(_T(\u0026#34; 0x%02X\u0026#34;), p_buffer[log_counter]); str += str_temp; } FormatLog(fLogStatus, str.GetBuffer(1024), LOG_NEWLINE | LOG_LOGTIME); str.ReleaseBuffer(); #endif // pocet odeslanych dat *p_wrote = error; return NW_ALL_OK; } Třídu jsem použil v aplikaci, kde se o síťovou komunikaci staralo samostatné vlákno, takže případné zpoždění ve funkci ReceiveData tolik nevadilo. Hlavní vlákno aplikace potom bylo informováno o dostupnosti nových dat pomocí zpráv (SendMessage). Třída samotná asi moc využití nenajde, snad ale poslouží jako příklad pro posílání a příjem dat přes UDP.\nNetworkCommunication.cpp NetworkCommunication.h ","date":"14. 3. 2009","externalUrl":null,"permalink":"/clanky/cnetworkcommunication-casyncsocket-a-udp/","section":"Články","summary":"CNetworkCommunication je třída odvozená z CAsyncSocket, napsaná pro příjem a vysílání paketů protokolem UDP. Je závislá na funkcích MFC. Před jejím použitím je třeba zavolat funkci AfxSocketInit(), například při spuštění aplikace ve funkci InitInstance().\nK použití jsou funkce:\nbool InitializeInterface(UINT port); int ReceiveData(BYTE *p_buffer, DWORD bufferSize, DWORD *p_readed); int TransmitData(BYTE *p_buffer, DWORD n_count, CString address, UINT port, DWORD *p_wrote);","title":"CNetworkCommunication - UDP v MFC","type":"clanky"},{"content":"CSQLWrapper je třída pro zjednodušení práce s mySQL. Volá funkce z libmysql. Pracuje nad jedním spojením se serverem, takže lze s tímto spojením pracovat jako s objektem.\nPříklad použití:\nCSQLWrapper *pSQLWrapper = new CSQLWrapper; MYSQL *pmysql = pSQLWrapper-\u0026gt;MakeRealConnect(\u0026#34;server\u0026#34;, \u0026#34;username\u0026#34;, \u0026#34;password\u0026#34;); // spojeni OK if (pmysql) { // vyber pracovni databaze if (pSQLWrapper-\u0026gt;SelectDatabase(\u0026#34;database\u0026#34;)) { // spusteni dotazu if (pSQLWrapper-\u0026gt;Query(\u0026#34;select column from table;\u0026#34;)) { MYSQL_ROW row; pSQLWrapper-\u0026gt;StoreResult(); // projde vsechny vracene radky a sloupce while (row = pSQLWrapper-\u0026gt;FetchRow()) { for (int i = 0; i \u0026lt; pSQLWrapper-\u0026gt;GetNumFields(); i++) { cout \u0026lt;\u0026lt; row[i] \u0026lt;\u0026lt; endl; } } pSQLWrapper-\u0026gt;FreeResult(); } else cout \u0026lt;\u0026lt; pSQLWrapper-\u0026gt;GetLastErrorString() \u0026lt;\u0026lt; endl; // ukonceni spojeni pSQLWrapper-\u0026gt;CloseConnection(); } // chyba pri vyberu databaze else cout \u0026lt;\u0026lt; pSQLWrapper-\u0026gt;GetLastErrorString() \u0026lt;\u0026lt; endl; } // chyba pri otevirani spojeni else cout \u0026lt;\u0026lt; pSQLWrapper-\u0026gt;GetLastErrorString() \u0026lt;\u0026lt; endl; delete pSQLWrapper; K dispozici je verze pro MFC, která používá třídu CString a verze využívající std::string. Pro Windows bude pravděpodobně třeba vložit do souboru stdafx.h\n#include \u0026lt;winsock.h\u0026gt; std namespace verze\nSQLWrapper.cpp SQLWrapper.h MFC verze\nSQLWrapper.cpp SQLWrapper.h ","date":"8. 3. 2009","externalUrl":null,"permalink":"/clanky/csqlwrapper/","section":"Články","summary":"CSQLWrapper je třída pro zjednodušení práce s mySQL. Volá funkce z libmysql. Pracuje nad jedním spojením se serverem, takže lze s tímto spojením pracovat jako s objektem.\n","title":"CSQLWrapper - C++ wrapper pro mySQL","type":"clanky"},{"content":"Následující program čte řádky z logu Apache a ukládá je do mySQL databáze. Řádky logu očekává ve formátu\nLogFormat \u0026#34;%h %l %u %t \\\u0026#34;%r\\\u0026#34; %\u0026gt;s %b \\\u0026#34;%{Referer}i\\\u0026#34; \\\u0026#34;%{User-Agent}i\\\u0026#34;\u0026#34; Data jsou vkládána uloženou procedurou sp_insert_record_to_http_accesslog do tabulky http_accesslog. Protože program využívá uložené procedury, je nutné použít mySQL od verze 5.\nZačněme vytvořením tabulky pro uložení výsledků a uložené procedury.\ncreate table http_accesslog ( ip varchar(255) NOT NULL, client varchar(255) NOT NULL, user varchar(255) NOT NULL, time datetime NOT NULL default \u0026#39;2007-01-01 00:00:00\u0026#39;, request text NOT NULL, error_code varchar(255) NOT NULL, data_size int(11) NOT NULL default \u0026#39;0\u0026#39;, refer text NOT NULL, browser text NOT NULL, KEY ip (ip), KEY error_code (error_code), KEY time (time) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; delimiter $$ drop procedure if exists sp_insert_record_to_http_accesslog$$ create procedure sp_insert_record_to_http_accesslog (in_ip varchar(255), in_client varchar(255), in_user varchar(255), in_time datetime, in_request text, in_error_code varchar(255), in_data_size int(11), in_refer text, in_browser text) begin if not exists(select * from http_accesslog where ip = in_ip and time = in_time and request = in_request) then insert into http_accesslog (ip, client, user, time, request, error_code, data_size, refer, browser) values (in_ip, in_client, in_user, in_time, in_request, in_error_code, in_data_size, in_refer, in_browser); end if; end$$ delimiter ; Program je napsán v C a pro přeložení je nutné mít nainstalovanou knihovnu libmysqlclient. Dalším krokem je tedy zkopírování zdrojáku a uložení do souboru httplog.c.\n#include \u0026lt;stdlib.h\u0026gt; #include \u0026lt;stdio.h\u0026gt; #include \u0026lt;assert.h\u0026gt; #include \u0026lt;string.h\u0026gt; #include \u0026lt;mysql/mysql.h\u0026gt; #include \u0026lt;unistd.h\u0026gt; #define LOCK_FILE \u0026#34;/tmp/httplog.lock\u0026#34; #define LOG_ACCESS \u0026#34;/var/log/apache/access_log\u0026#34; #define LINE_SIZE 32768 #define SQL_CALL_INSERT_RECORD \u0026#34;call sp_insert_record_to_http_accesslog \\ (\u0026#39;%s\u0026#39;, \u0026#39;%s\u0026#39;, \u0026#39;%s\u0026#39;, \u0026#39;%s\u0026#39;, \u0026#39;%s\u0026#39;, \u0026#39;%s\u0026#39;, \u0026#39;%s\u0026#39;, \u0026#39;%s\u0026#39;, \u0026#39;%s\u0026#39;);\u0026#34; typedef struct { char *ip; char *client; char *user; char *time; char *request; char *error_code; char *data_size; char *refer; char *browser; } st_accesslog_line; st_accesslog_line accesslog_line; MYSQL *myData = NULL; static const char *months[] = { \u0026#34;Jan\u0026#34;, \u0026#34;-01-\u0026#34;, \u0026#34;Feb\u0026#34;, \u0026#34;-02-\u0026#34;, \u0026#34;Mar\u0026#34;, \u0026#34;-03-\u0026#34;, \u0026#34;Apr\u0026#34;, \u0026#34;-04-\u0026#34;, \u0026#34;May\u0026#34;, \u0026#34;-05-\u0026#34;, \u0026#34;Jun\u0026#34;, \u0026#34;-06-\u0026#34;, \u0026#34;Jul\u0026#34;, \u0026#34;-07-\u0026#34;, \u0026#34;Aug\u0026#34;, \u0026#34;-08-\u0026#34;, \u0026#34;Sep\u0026#34;, \u0026#34;-09-\u0026#34;, \u0026#34;Oct\u0026#34;, \u0026#34;-10-\u0026#34;, \u0026#34;Nov\u0026#34;, \u0026#34;-11-\u0026#34;, \u0026#34;Dec\u0026#34;, \u0026#34;-12-\u0026#34;, NULL, NULL }; int connect2db() { int ret = 0; MYSQL *myRealConnectResult; myData = mysql_init((MYSQL*) 0); assert(myData); myRealConnectResult = mysql_real_connect(myData, \u0026#34;localhost\u0026#34;, \u0026#34;user\u0026#34;, \u0026#34;password\u0026#34;, NULL, MYSQL_PORT, NULL, 0 ); if (!myRealConnectResult) { printf(\u0026#34;%s\\n\u0026#34;, mysql_error(myData)); ret = 1; } if (mysql_select_db(myData, \u0026#34;pristupy\u0026#34;)) { printf(\u0026#34;%s\\n\u0026#34;, mysql_error(myData)); mysql_close(myData); myData = NULL; ret = 1; } return ret; } void addescapes(char *line) { int srcpos = 0, dstpos = 0; int size = strlen(line); if (!size) return; char *buffer = malloc(size*2); assert(buffer); while (line[srcpos]) { if ((line[srcpos] == \u0026#39;\\\\\u0026#39;) || (line[srcpos] == \u0026#39;\\\u0026#39;\u0026#39;) || (line[srcpos] == \u0026#39;\u0026#34;\u0026#39;)) buffer[dstpos++] = \u0026#39;\\\\\u0026#39;; buffer[dstpos++] = line[srcpos++]; } buffer[dstpos++] = 0; if (dstpos \u0026lt; LINE_SIZE) strcpy(line, buffer); free(buffer); } // z textu ve formatu [05/Aug/2007:10:21:12 +0200] // vrati 2007-08-05 10:21:12 void extractdate(char *src, char *dst) { int i, dstpos = 0; char month[4]; // rok for (i = 8; i \u0026lt; 12; i++) dst[dstpos++] = src[i]; dst[dstpos++] = 0; // mesic for (i = 0; i \u0026lt; 3; i++) month[i] = src[i+4]; month[i] = 0; i = 0; while (months[i] != NULL) { if (!strcmp(months[i], month)) { strcat(dst, months[i+1]); break; } else i += 2; } // den dstpos = strlen(dst); for (i = 1; i \u0026lt; 3; i++) dst[dstpos++] = src[i]; dst[dstpos++] = \u0026#39; \u0026#39;; // cas for (i = 13; i \u0026lt; 21; i++) dst[dstpos++] = src[i]; dst[dstpos++] = 0; } // rozseka radek na casti, oddelene mezerami. // texty v uvozovkach jsou brany jako jedna cast. void parseline_accesslog(char *line) { int stop = 0, linepos = 0, part = 0, bufferpos = 0; char inquotation = 0, firstquote = 0, inparent = 0; char *buffer = malloc(LINE_SIZE); assert(buffer); while (!stop) { if (line[linepos] == 0) stop = 1; else { // kontrola uvozovek if ((line[linepos] == \u0026#39;\u0026#34;\u0026#39;) \u0026amp;\u0026amp; line[linepos-1] != \u0026#39;\\\\\u0026#39;) { if (inquotation == 0) firstquote = 1; inquotation = ~inquotation \u0026amp; 1; } // zkopirovani znaku v textu mezi uvozovkami if (inquotation) { // vyhozeni prvnich uvozovek if (firstquote) firstquote = 0; else buffer[bufferpos++] = line[linepos]; } else { if (((line[linepos] == \u0026#39; \u0026#39;) || (line[linepos+1] == 0)) \u0026amp;\u0026amp; !inparent) { buffer[bufferpos++] = 0; // ulozeni hodnot z radku logu switch (part) { case 0: strcpy(accesslog_line.ip, buffer); break; case 1: strcpy(accesslog_line.client, buffer); break; case 2: strcpy(accesslog_line.user, buffer); break; case 3: extractdate(buffer, accesslog_line.time); break; case 4: strcpy(accesslog_line.request, buffer); break; case 5: strcpy(accesslog_line.error_code, buffer); break; case 6: strcpy(accesslog_line.data_size, buffer); break; case 7: strcpy(accesslog_line.refer, buffer); break; case 8: strcpy(accesslog_line.browser, buffer); break; } bufferpos = 0; part++; } else { if (line[linepos] != \u0026#39;\u0026#34;\u0026#39;) { if ((line[linepos] == \u0026#39;[\u0026#39;) \u0026amp;\u0026amp; !inparent) inparent = 1; buffer[bufferpos++] = line[linepos]; if ((line[linepos] == \u0026#39;]\u0026#39;) \u0026amp;\u0026amp; inparent) inparent = 0; } } } } linepos++; } free(buffer); } void process_accesslog(FILE *f) { char *line = malloc(LINE_SIZE); assert(line); while(fgets(line, LINE_SIZE, f) != NULL) { // pro jistotu line[LINE_SIZE-1] = 0; int linelen = strlen(line); if (linelen \u0026gt; 4096) continue; parseline_accesslog(line); addescapes(accesslog_line.ip); addescapes(accesslog_line.client); addescapes(accesslog_line.user); addescapes(accesslog_line.time); addescapes(accesslog_line.request); addescapes(accesslog_line.error_code); addescapes(accesslog_line.data_size); addescapes(accesslog_line.refer); addescapes(accesslog_line.browser); sprintf(line, SQL_CALL_INSERT_RECORD, accesslog_line.ip, accesslog_line.client, accesslog_line.user, accesslog_line.time, accesslog_line.request, accesslog_line.error_code, accesslog_line.data_size, accesslog_line.refer, accesslog_line.browser); if (mysql_query(myData, line)) printf(\u0026#34;%s\\n\u0026#34;, mysql_error(myData)); } free(line); } int main(int argc, char *argv[]) { int ret = EXIT_SUCCESS; FILE *f_access, *f_lock; // kontrola, jestli jiz neni program spusten f_lock = fopen(LOCK_FILE, \u0026#34;r\u0026#34;); if (f_lock) { // soubor se podarilo otevrit // program se ukonci fclose(f_lock); printf(\u0026#34;httplog: lockfile already exists\\n\u0026#34;); return EXIT_FAILURE; } else { // lockfile nebyl otevren. zkusime ho vytvorit f_lock = fopen(LOCK_FILE, \u0026#34;w\u0026#34;); if (f_lock) { // lockfile vytvoren fclose(f_lock); } else { // chyba pri vytvareni lockfile printf(\u0026#34;httplog: can\u0026#39;t create lockfile\\n\u0026#34;); return EXIT_FAILURE; } } // spojeni na mySQL databazi if (connect2db()) return(EXIT_FAILURE); // alokace promenych pro ulozeni informaci z logu char *accessline_ip = malloc(LINE_SIZE); assert(accessline_ip); char *accessline_client = malloc(LINE_SIZE); assert(accessline_client); char *accessline_user = malloc(LINE_SIZE); assert(accessline_user); char *accessline_time = malloc(LINE_SIZE); assert(accessline_time); char *accessline_request = malloc(LINE_SIZE); assert(accessline_request); char *accessline_error_code = malloc(LINE_SIZE); assert(accessline_error_code); char *accessline_data_size = malloc(LINE_SIZE); assert(accessline_data_size); char *accessline_refer = malloc(LINE_SIZE); assert(accessline_refer); char *accessline_browser = malloc(LINE_SIZE); assert(accessline_browser); // prirazeni do struktury accesslog_line accesslog_line.ip = accessline_ip; accesslog_line.client = accessline_client; accesslog_line.user = accessline_user; accesslog_line.time = accessline_time; accesslog_line.request = accessline_request; accesslog_line.error_code = accessline_error_code; accesslog_line.data_size = accessline_data_size; accesslog_line.refer = accessline_refer; accesslog_line.browser = accessline_browser; f_access = fopen(LOG_ACCESS, \u0026#34;r\u0026#34;); if (f_access) { process_accesslog(f_access); fclose(f_access); } else { printf(\u0026#34;can\u0026#39;t open file %s\\n\u0026#34;, LOG_ACCESS); ret = EXIT_FAILURE; } if (myData) mysql_close(myData); free(accessline_ip); free(accessline_client); free(accessline_user); free(accessline_time); free(accessline_request); free(accessline_error_code); free(accessline_data_size); free(accessline_refer); free(accessline_browser); // smazani lockfile unlink(LOCK_FILE); return ret; } V konzoli spustit gcc -Wall -lmysqlclient -o httplog httplog.c a tím vytvořit spustitelný soubor. Ten potom stačí periodicky spouštět, například každou hodinu.\n","date":"8. 3. 2009","externalUrl":null,"permalink":"/clanky/ulozeni-logu-apache-do-mysql/","section":"Články","summary":"Následující program čte řádky z logu Apache a ukládá je do mySQL databáze. Řádky logu očekává ve formátu\nLogFormat \"%h %l %u %t \\\"%r\\\" %\u003es %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" Data jsou vkládána uloženou procedurou sp_insert_record_to_http_accesslog do tabulky http_accesslog. Protože program využívá uložené procedury, je nutné použít mySQL od verze 5.\n","title":"Uložení logu Apache do mySQL","type":"clanky"},{"content":"Poděbrady a okolí, jak je zachytil Kuris při jedné fotovýpravě :)\n12 fotografií. Kliknutím otevřete prohlížeč, listovat můžete šipkami nebo tažením prstem.\n","date":"8. 3. 2009","externalUrl":null,"permalink":"/foto/kuris-foti-v-podebradech-1/","section":"Foto koutek","summary":"","title":"Kuris fotí v Poděbradech a okolí 1","type":"foto"},{"content":"Při povodních v roce 2006 zachytil Kuris zámek a jeho okolí na několika pěkných snímcích.\n6 fotografií. Kliknutím otevřete prohlížeč, listovat můžete šipkami nebo tažením prstem.\n","date":"1. 3. 2009","externalUrl":null,"permalink":"/foto/zamek-pri-povodnich-v-roce-2006/","section":"Foto koutek","summary":"","title":"Poděbradský zámek při povodních v roce 2006","type":"foto"},{"content":"Funkce GetOpenFileName a GetSaveFileName z knihovny commdlg.dll slouží ke zobrazení dialogu pro výběr souborů. Při psaní aplikací ve Visual Studiu 6 se mi ale nikdy nelíbil vzhled dialogu otevřeného třídou CFileDialog. Použití této třídy je jednodušší, ale na rozdíl od ní jsou dialogy funkcí GetOpenFileName a GetSaveFileName přímo součástí knihoven operačního systému a jejich vzhled je s každou verzí Windows trochu odlišný. Chování funkcí je ovlivněno strukturou OPENFILENAME. Následující krátké ukázky slouží pro výběr souboru k otevření a uložení.\nPro určení vlastníka dialogu je nutné vyplnit ofn.hwndOwner ukazatelem okna, ze kterého je funkce volána. Může být i NULL, potom ale zobrazený dialog neví, komu patří a okno, ze kterého je volaný je možné aktivovat i při zobrazeném dialogu pro výběr souboru.\nGetOpenFileName # BOOL getopenname(char *filename, HWND hwndOwner) { OPENFILENAME ofn; TCHAR chFile[_MAX_PATH]; lstrcpy(chFile, \u0026#34;\u0026#34;); ZeroMemory(\u0026amp;ofn, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.lpstrFile = chFile; ofn.hwndOwner = hwndOwner; ofn.nMaxFile = sizeof(chFile); ofn.lpstrFilter = TEXT(\u0026#34;Textové soubory (*.txt)\\0*.txt\\0Všechny soubory (*.*)\\0*.*\\0\u0026#34;); ofn.nFilterIndex = 1; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; if(GetOpenFileName(\u0026amp;ofn)) { lstrcpy(filename, chFile); return TRUE; } return FALSE; } GetSaveFileName # BOOL getsavename(char *filename, HWND hwndOwner) { OPENFILENAME ofn; TCHAR szFileName[MAX_PATH] = TEXT(\u0026#34;\u0026#34;); szFileName[0] = \u0026#39;\\0\u0026#39;; ZeroMemory(\u0026amp;ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwndOwner; ofn.lpstrFilter = TEXT(\u0026#34;Textové soubory (*.txt)\\0*.txt\\0Všechny soubory (*.*)\\0*.*\\0\u0026#34;); ofn.lpstrFile = szFileName; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_OVERWRITEPROMPT; ofn.lpstrDefExt = \u0026#34;txt\u0026#34;; if(GetSaveFileName(\u0026amp;ofn)) { lstrcpy(filename, szFileName); return TRUE; } return FALSE; }","date":"27. 2. 2009","externalUrl":null,"permalink":"/clanky/pouziti-win32-funkci-getopenfilename-a-getsavefilename/","section":"Články","summary":"Funkce GetOpenFileName a GetSaveFileName z knihovny commdlg.dll slouží ke zobrazení dialogu pro výběr souborů. Při psaní aplikací ve Visual Studiu 6 se mi ale nikdy nelíbil vzhled dialogu otevřeného třídou CFileDialog. Použití této třídy je jednodušší, ale na rozdíl od ní jsou dialogy funkcí GetOpenFileName a GetSaveFileName přímo součástí knihoven operačního systému a jejich vzhled je s každou verzí Windows trochu odlišný. Chování funkcí je ovlivněno strukturou OPENFILENAME. Následující krátké ukázky slouží pro výběr souboru k otevření a uložení.\n","title":"Použití funkcí GetOpenFileName a GetSaveFileName","type":"clanky"},{"content":"Toto mini howto popisuje kompilaci SeaMonkey v 64 bitové distribuci Mandrivy 2006. Nejprve je třeba stáhnout archív se zdrojáky z ftp://ftp.mozilla.org/pub/mozilla.org/seamonkey/releases/ a jeho obsah rozbalit. V adresáři mozilla vytvořit soubor .mozconfig (na začátku je tečka). Do souboru vložit tento text:\nmk_add_options MOZ_CO_PROJECT=suite ac_add_options --enable-application=suite mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/suite-opt ac_add_options --enable-optimize ac_add_options --disable-debug Potom v adresáři mozilla spustit make -f client.mk build a počkat, až se vše přeloží. Po dokončení kompilace spustit make -C suite-opt/xpinstall/packager installer a tím vytvořit instalátor. Vznikne soubor suite-opt/installer/sea/seamonkey-1.0.6.en-US.linux-x86_64.installer.tar.gz , který lze potom kamkoliv nahrát, rozbalit a aplikaci z něj nainstalovat. Obsah tohoto archívu je zároveň v adresáři suite-opt/installer/raw. Takže cd suite-opt/installer/raw a tam spustit ./seamonkey-installer (pravděpodobně jako root, podle toho, do jakého adresáře se má instalovat). Tím se spustí grafický instalátor … pak už je snad všechno jasný :)\nPostup pro konfiguraci a instalaci na mozilla.org\nhttps://firefox-source-docs.mozilla.org/setup/configuring_build_options.html\nhttps://firefox-source-docs.mozilla.org/setup/\nPo spuštění make -f client.mk build se proces možná zastaví při kontrole dostupnosti knihoven, které jsou potřeba. Pokud se to stane, musí se doinstalovat jejich devel balíčky. Všechny potřebné jsou k dispozici ve správci instalací.\nJestli kontrola proběhne v pohodě, může se ještě kompilace zastavit a psát podobnou chybu: relocation R_X86_64_PC32 against memcpy@@GLIBC_2.2.5 can not be used. Potom se musí do souboru .mozconfig přidat na začátek řádek ac_cv_visibility_pragma=no takže soubor .mozconfig bude vypadat takhle:\nac_cv_visibility_pragma=no mk_add_options MOZ_CO_PROJECT=suite ac_add_options --enable-application=suite mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/suite-opt ac_add_options --enable-optimize ac_add_options --disable-debug Potom doporučuju ještě spustit v adresáři mozilla: ./configure \u0026amp;\u0026amp; gmake distclean tím zdrojáky pročistit od případnýho bordelu z předchozího maku a potom opět make -f client.mk build\nŘešení tohoto problému je na https://benjamin.smedbergs.us/blog/2005-10-27/gcc-40-workaround/\n","date":"14. 2. 2009","externalUrl":null,"permalink":"/clanky/kompilace-seamonkey-v-mandrive-2006/","section":"Články","summary":"Toto mini howto popisuje kompilaci SeaMonkey v 64 bitové distribuci Mandrivy 2006. Nejprve je třeba stáhnout archív se zdrojáky z ftp://ftp.mozilla.org/pub/mozilla.org/seamonkey/releases/ a jeho obsah rozbalit. V adresáři mozilla vytvořit soubor .mozconfig (na začátku je tečka). Do souboru vložit tento text:\nmk_add_options MOZ_CO_PROJECT=suite ac_add_options --enable-application=suite mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/suite-opt ac_add_options --enable-optimize ac_add_options --disable-debug","title":"Kompilace SeaMonkey v Mandrivě 2006","type":"clanky"},{"content":"","date":"14. 2. 2009","externalUrl":null,"permalink":"/tags/seamonkey/","section":"Tags","summary":"","title":"SeaMonkey","type":"tags"},{"content":"Zase jsem udělal chybu. Bolí mě to u mého malého srdíčka. Pokorně se klaním před Systémem, který pouze suše oznamuje: Program provedl neplatnou operaci a bude ukončen. Ach, ta bolest nad rozdělanou prací. Ach, ten smutek. Ale tak to musí být. Jsem smířeny s osudem a šlapu blátivými uličkami ke zpovědi. Uživatelíčkové, žijící v blátivých slumech, vidí mé roucho novice a ustupují z cesty.\n\u0026quot;Sluha Páně Billa! Nepadavost jeho duši!\u0026quot; Pouze jeden stařík se drží v koutku. Mračí se. Že by Jablíčkář?... Ale ne..., inkvizice již dávno všechny Jablíčkáře upálila.\n\u0026quot;Chyboval jsem, Otče Pavle.\u0026quot;\n\u0026quot;Spadl ti Systém,synu?\u0026quot;\nKatedrála je úžasná: ty obláčky při startu, ta krásná modrá okýnka, která jdou otevírat, zavírat, minimalizovat, maximalizovat... V okýnkach jsou maximalizovány obrazy svatých: Svatý Jack, který pokorně čekal na start Windows a přitom umřel hlady, Svatý Tom, který tak dlouho načítal stránku z https://www.microsoft.com, až se dostal do Extáze...\n\u0026quot;Co mi radíte, Otče? Jak mám zabránit Modré Smrti, která mě sužuje dnem i nocí?\u0026quot;\n\u0026quot;Pokání, modlitby, Reinstalace!\u0026quot;\n\u0026quot;Svatá Reinstalace? Znovu, Otče? Ušetřete nehodného syna nejhoršího!\u0026quot;\n\u0026quot;Víš synu, že Bill pravil: jedině systém Windows míti budeš. Chceš snad odporovat Svaté Autoritě Tech Supportu?!\u0026quot;\n\u0026quot;To bych si nikdy nedovolil!\u0026quot;\n\u0026quot;Tak dobře, synu. Desetkrát si zahraj Solitaire a patnáctkrát Miny a tvá duše bude očištěna. Již žádné pády!\u0026quot;\nLíbám prsten svatého muže a jsem propuštěn do věčně zablácených ulic Města.\nDruhý den ráno mě vzbudila sousedka:\n\u0026quot;Modrá smrt, chlapče! Modrá smrt v mém domě! Co jsem provedla?\u0026quot;\n\u0026quot;Já jsem pouhý novic. Jděte do Katedrály TechSupportu, jedině přes Billa dojdete k osvícení.\u0026quot;\nPoradil jsem jí to nejlepší dle mého vědomí a svědomí.\n\u0026quot;Slyšela jsem od báby kořenářky nějaké magické formule proti kleknutí Systému.\u0026quot;\n\u0026quot;Jaképak?\u0026quot;, to mě zajímalo. Sice byla černá magie - editace Svaté Registrační Databáze - zakázána kněžími TechSupportu, vždy se ale našlo něco, co pomohlo. \u0026quot;No... když si pustíte třikrát Malování, dvakrát Notepad, a jedny Miny a u toho říkáte 'city moje proradné, Wokno dneska nespadne' tak se neobjevují Neplatné operace. Chtěl jsem jí oponovat, že jsou to babské pověry, ale radši jsem nic neřekl. Co kdyby na tom bylo něco pravdy? U Svatého Systému človek nikdy neví.\nNáhle zaklepal na dveře Zdenek, kolega novic.\n\u0026quot;Zdar Bill. Zlikvidovali další sektu. Chceš se tam mrknout?\u0026quot;\n\u0026quot;Zdar Bill. Dobře brachu. Vyrazíme.\u0026quot;\nLůza jako vždy ustoupila při pohledu na naše roucha. Tentokrát se jich srotilo hodně. Slyšel jsem v zástupu nějaké hlasy:\n\u0026quot;Apokalypsa! Drak DOS přichází zpátky! Síly Příkazového Řádku se opět probouzejí!\u0026quot;\nNevěděl jsem, co je Příkazový Řádek, ale určitě to je něco hodně temného. Kolegovi Kamilovi, který se o něm zmínil v semináři, napařili celý měsíc klášterní vězení, přísnou askezi a zákaz hraní počítačových her.\nBlátivé stany, které lůza používala místo domků, byly vypáleny. Bill dal, Bill vzal. Sektáři zaplatili za svou herezi životem. Ale vtom jsem zahlédl uprostřed popela záblesk bílého světla. Kousíček papíru a na něm: \u0026quot;/usr/bin/perl\u0026quot; ... Hieroglyfy jsem si zapamatoval a papírek ihned zmačkal a spolknul. Nějaká magie, určitě.\nPříští den jdu opět ke zpovědi. Musel jsem asi chybovat, neboť mě Modrá Smrt navštívila znovu. Znovu procházím davem k Chrámu.\n\u0026quot;Sluha Páně Billa! Nepadavost jeho duši!\u0026quot; Stařík, který se mračil, je nyní přívětivější. Stále zasmušilý, ale dívá se na mě, jako by na něco čekal.\n\u0026quot;/usr/bin/perl\u0026quot;, šeptám mu.\n\u0026quot;Takže ty taky...\u0026quot;, na staříkově tváři rozkvetl úsměv. Vtom se přiblížili biřicové. Obrátil jsem svou pozornost znova na starého muže, ale ten zmizel jako by se do země propadl.\n\u0026quot;Chyboval jsem, Otče.\u0026quot;\n\u0026quot;Snad jsi nepouštěl Internet Explorer, přehrávač MP3 a ICQ naráz, bezbillníku?!\u0026quot;\n\u0026quot;Nikoliv, Otče. Přesto mne, ubohého, navštívila Modrá smrt.\u0026quot;\n\u0026quot;To není všechno, viď, synu!\u0026quot;, pronikavé oči kněze našly nejistotu v mém pohledu.\n\u0026quot;Taky jsem... jsem\u0026quot;\n\u0026quot;CO jsi, při Ovládacích panelech, CO?\u0026quot;\n\u0026quot;Taky jsem viděl... ale ne\u0026quot;\n\u0026quot;Svěř se svému pastýři.\u0026quot;\n\u0026quot;Ta... ta sekta,... včera\u0026quot;\n\u0026quot;Bajty jsou a v bajty se obrátili, synu.\u0026quot;\n\u0026quot;Byl tam ... papírek... nechtěl jsem se na něj dívat, opravdu ne...\u0026quot; třásl jsem se po celém těle.\n\u0026quot;Co stálo na tom papírku? Zaklínám tě Instalací, Reinstalací a Zálohou...\u0026quot;\n\u0026quot;Stálo tam.... /usr/bin/perl\u0026quot;\nZorničky Otce Pavla se rozšířily. \u0026quot;Cože?!\u0026quot;\n\u0026quot;/usr/bin/perl, Otče...\u0026quot;\nCela byla chladivá a nehostinná. Kat s devítiocasou kočkou byl v pohotovosti. Biskup a Otec Pavel stáli nade mnou.\n\u0026quot;Takový papírek jsi nikdy neviděl. Opakuj to po mne.\u0026quot;\n\u0026quot;Takový papírek jsem nikdy neviděl.\u0026quot; \u0026quot;Hmmm... to nezní dost přesvědčivě.\u0026quot;, namítl biskup. \u0026quot;Devět ran!\u0026quot;\nšvih! \u0026quot;Windows gracias.\u0026quot;\nšvih! \u0026quot;Windows gracias.\u0026quot;\nšvih! \u0026quot;Windows gracias.\u0026quot;\nšvih! \u0026quot;Windows gracias.\u0026quot;\nšvih! \u0026quot;Windows gracias.\u0026quot;\nšvih! \u0026quot;Windows gracias.\u0026quot;\nšvih! \u0026quot;Windows gracias.\u0026quot;\nšvih! \u0026quot;Windows gracias.\u0026quot;\nšvih! \u0026quot;Windows gracias.\u0026quot;\nPo absolvování trestu jsem odešel, již zcela očišten, k domovu. Začal jsem ale pochybovat. Ty stálé pády? Musí tomu tak opravdu být? Pokud je Bill všemocný, proč jsou tu sekty? Co znamenala ta tajná šifra? Kdo byl ten stařík?\n\u0026quot;Hledáš, panáčku, hledáš? DOSová moudrost Příkazového Řádku je tu stále. Neotupená. Čistá.\u0026quot;\n\u0026quot;Běž pryč, ty stará čarodějnice!\u0026quot; odsekávám.\nJdu domu a tam jsem zjistil, že všechny mé Wordové dokumenty mají přeházené formátování. Asi jsem zhřešil. Nebo ne? Červík pochybnosti hlodá a hlodá...\nRáno se opět brodím davem.\n\u0026quot;Nyní můžete bez obav počítač vypnout!\u0026quot; volají svíčkové báby své ozdravné litanie. Stařík je tu zas.\n\u0026quot;Dostal's výprask, chlapče?\u0026quot;\n\u0026quot;Co je Příkazový Řádek?\u0026quot; ptám se rychle.\n\u0026quot;Ach, tak ty víš i tohle! Tam se zadávají příkazy pro systém v čisté textové podobě, hochu. Při všech bitech a bajtech, on nám zraje pro Tuč...\u0026quot;\nLomoz. Jízda. Rytíři řádu Velkého Excelu projeli náměstím. Stařík opět zmizel. Ach jo.\nV semináři se učíme Excelové tabulky. Neodvažuji se zeptat kněze, ale bratr Mirek toho ví hodně \u0026quot;Mirku, co je to \u0026quot;čistý text?\u0026quot;\nMirek zbledl \u0026quot;Pouze text v MS Wordu je opravdu čistý, příteli.\u0026quot;\n\u0026quot;Kterou verzi Wordu máš na mysli, bratře?\u0026quot; zeptal se Kamil.\nMěstem chodí zvěsti o Čistém Textu a Otevřených Formátech. Otevřené Formáty! Další kamínek do mozaiky. Ale jak s tím souvisí \u0026quot;Čistý text?\u0026quot; a \u0026quot;/usr/bin/perl\u0026quot;?\n\u0026quot;Bill ví\u0026quot; odpověděl bych donedávna. Ale nyní mám pochybnosti. Je jen jediný Systém? Jediný Bill? Jediná Windows?\n\u0026quot;Chlapče, za mých mladých let to bylo všechno jednodušší. Žádná blyštivá Okna, pouze textové příkazy. Nepadalo to.\u0026quot; lamentuje kořenářka.\n\u0026quot;Ale celá naše víra je založena na koncepci Pádu a Očištění!\u0026quot;, odsekl jsem.\n\u0026quot;Nebo... že by... Otevřené formáty?\u0026quot;\n\u0026quot;Jé, chlapče, jak je to dávno, co jsem toto slovo naposledy slyšela... Už nevím co znamená... odpusť sklerózu staré ženy, musím si asi koupit více operační paměti...\u0026quot;\nStařík na trhu. Skrýval se v davu, ale jakmile mě uviděl, hned s jásotem přistoupil blíže.\n\u0026quot;Chlapče, při všech zdrojácích a debuggerech, tebe ještě nedostali? Stále žiješ?\u0026quot;\n\u0026quot;Ano, starý pane.\u0026quot;\n\u0026quot;Systém nemusí padat. Přesněji řečeno je tu původně od toho aby programy nepadaly!\u0026quot;\nTo bylo přesně opakem toho, co jsme brali v semináři. Rdím se až do krve. Taková blasfemie!\n\u0026quot;Za chvíli tu budou strážní na obchůzce, takže ti dám jednu radu: následuj...\u0026quot;\nVtom se ozval řev. Drak MS Office, domácí mazlíček Páně Billa, přeletěl nad Městem. Davu se zmocnil neklid, lidé začali zvedat ochranné amulety proti Jablíčkám. Stařec zmizel jako pára nad hrncem.\nV semináři jsem zjistil, že je nás o jednoho méně. Bratr Mirek, ten nejchytřejší.\n\u0026quot;Ten hříšník spustil regedit.exe. Pošpinil Registrační Databázi výplody svého chorého mozku. Na mučidlech se přiznal dokonce k tomu, ze instaloval Nelegální software.\u0026quot;\n\u0026quot;KOPÍROVAL SOFTWARE?\u0026quot; zeptali jsme se všichni jako jeden muž. Ó, Start Menu, ochraňuj nás. Biskup pokračoval \u0026quot;a byla u něho nalezena publikace o Disassemblingu a Crackingu.\u0026quot; Libri prohibiti!\nČerná učení! Udělal jsem si na hrudi znamení Okna.\nProbudil jsem se a všude velký shon.\n\u0026quot;Bude se upalovat!\u0026quot;, oznámila mi sousedka \u0026quot;nějaký bezbillník se konečně setká s Věčnou Modrou Smrtí!\u0026quot;\nLůza v podhradí se sbíhala k Náměstí ovládacích panelů.\n\u0026quot;Odvolej své temné učení!\u0026quot; hřímal biskup.\nKohopak to nevidím na hranici - vždyť je to tajemný stařík, který mi šuškal své moudrosti!\n\u0026quot;Neodvolám! Lidé, prohlédněte! Bill z vás tahá peníze! Při Céčku a Assembleru, při Perlu, XWindow Systému a Shellu, nebuďte jako ovce!\u0026quot;\nVtom mě zahlédl. V jeho očích jsem zahlédl jiskřičku účasti.\n\u0026quot;Všichni, kteří pochybují, pochybují právem! Nepoužívejte Word! Nepoužívejte uzavřené formáty dokumentu!\nHledejte Tučňáka! Tučňákááááá\u0026quot;\nPlanoucí oheň spálil tělo hříšníka. V hlavě mám spoustu otazníků. Budu pátrat. Budu skládat střípky a jednou snad všechno bude jinak.\n\u0026quot;Tfuj, kacíř!\u0026quot; odplivla si bába u hranice.\n","date":"14. 2. 2009","externalUrl":null,"permalink":"/clanky/spasitel-bill/","section":"Články","summary":"Zase jsem udělal chybu. Bolí mě to u mého malého srdíčka. Pokorně se klaním před Systémem, který pouze suše oznamuje: Program provedl neplatnou operaci a bude ukončen. Ach, ta bolest nad rozdělanou prací. Ach, ten smutek. Ale tak to musí být. Jsem smířeny s osudem a šlapu blátivými uličkami ke zpovědi. Uživatelíčkové, žijící v blátivých slumech, vidí mé roucho novice a ustupují z cesty.\n","title":"Spasitel Bill","type":"clanky"},{"content":"Následující skript uložit do souboru, např. jako mailfrompetr.sh, nastavit mu atribut pro spouštění a zavolat tímto způsobem:\nmailfrompetr.sh \u0026#34;tohle je predmet mailu\u0026#34; \u0026#34;tohle je obsah mailu\u0026#34; nekdo@nekde.cz Parametr č. 2 může být název souboru. V takovém případě bude v textu mailu obsah tohoto souboru. Je snad každýmu jasný, že soubor musí obsahovat text. :)\n#!/bin/bash # SND=\u0026#34;/usr/sbin/sendmail -f ja@example.com -t\u0026#34; SUB=$1 MSG=$2 TO=$3 CAT=cat if test -z \u0026#34;$TO\u0026#34;; then TO=ja@example.com fi if test -f \u0026#34;$MSG\u0026#34;; then $SND \u0026lt;\u0026lt;EOM1 From: ja@example.com To: $TO Subject: $SUB `$CAT $MSG` EOM1 else $SND \u0026lt;\u0026lt;EOM2 From: ja@example.com To: $TO Subject: $SUB $MSG EOM2 fi Odeslání souboru v příloze mailu # Pro odeslání přílohy ze skriptu můžeme zkombinovat programy uuencode a mailx. Následující příkaz zakóduje soubor priloha.txt pomocí BASE64 a tento výstup předá programu mailx. uuencode priloha.txt priloha.txt | mailx -s predmet_mailu ja@example.com\n","date":"31. 1. 2009","externalUrl":null,"permalink":"/clanky/jak-poslat-mail-skriptem-shellu/","section":"Články","summary":"Následující skript uložit do souboru, např. jako mailfrompetr.sh, nastavit mu atribut pro spouštění a zavolat tímto způsobem:\nmailfrompetr.sh \"tohle je predmet mailu\" \"tohle je obsah mailu\" nekdo@nekde.cz","title":"Jak poslat mail skriptem shellu","type":"clanky"},{"content":"Možná někdo řešil situaci, jak přistupovat ke sdílenému disku v doméně z Windows Vista Home. Tuto verzi Windows do domény přihlásit nelze. Pokud je někde v síti sdílen adresář, který je ale ověřován pomocí řadiče domény, je sice možné takové sdílení vyhledat pomocí prohledání místní sítě a po zadání uživatelského jména a hesla k tomuto sdílení přistupovat, pouze ale do odhlášení uživatele. Při novém přihlášení uživatele se už toto sdílení nepodaří automaticky připojit. K relativně rychlému připojení sdílení je možné použít následující příkaz. Je sice pravda, že se musí ručně spustit, ale pouze jednou pro relaci uživatele.\nV příkazovém řádku je možné tímto příkazem připojit sdílený adresář:\nnet use x: \\\\server\\sdileny_adresar heslo /user:DOMENA\\uzivatel /PERSISTENT:no Tímto způsobem je možné k disku X: připojit sdílený adresář. Přepínač PERSISTENT určuje, jestli má být toto připojení obnoveno při dalším přihlášení uživatele. Tento příkaz je možné uložit do dávky a vytvořit si například zástupce na plochu, odkud se dá snadno spustit.\n","date":"31. 1. 2009","externalUrl":null,"permalink":"/clanky/pripojeni-sdileneho-disku-z-windows-vista-home/","section":"Články","summary":"","title":"Připojení sdíleného disku z Windows Vista Home","type":"clanky"},{"content":"","date":"31. 1. 2009","externalUrl":null,"permalink":"/tags/windows-vista/","section":"Tags","summary":"","title":"Windows Vista","type":"tags"},{"content":"Moje BOINC statistiky ze všech projektů.\nhttps://boincstats.com ","date":"1. 1. 2009","externalUrl":null,"permalink":"/clanky/boinc-statistiky/","section":"Články","summary":"","title":"BOINC statistiky","type":"clanky"}]