diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | BUILD.md | 134 | ||||
-rw-r--r-- | MAKE.bat | 1 | ||||
-rw-r--r-- | MAKE.ps1 | 9 | ||||
-rw-r--r-- | README.md | 48 | ||||
-rw-r--r-- | bidding_data.spec | 17 | ||||
-rw-r--r-- | bundle/.gitignore | 0 | ||||
-rw-r--r-- | bundle/bidding_data-1.0.zip | bin | 0 -> 6039445 bytes | |||
-rw-r--r-- | res/css/bidding.css (renamed from css/bidding.css) | 0 | ||||
-rw-r--r-- | res/images/link.png (renamed from images/link.png) | bin | 384 -> 384 bytes | |||
-rw-r--r-- | res/javas/bidding.js (renamed from javas/bidding.js) | 0 | ||||
-rw-r--r-- | src/.gitignore | 1 | ||||
-rw-r--r-- | src/bidding_data.py (renamed from bidding_data.py) | 0 | ||||
-rw-r--r-- | src/icon.ico | bin | 0 -> 50862 bytes | |||
-rw-r--r-- | src/icon.xcf | bin | 0 -> 12001 bytes | |||
-rw-r--r-- | src/version | 39 |
16 files changed, 231 insertions, 20 deletions
@@ -1 +1 @@ -*.pyc +dist/* diff --git a/BUILD.md b/BUILD.md new file mode 100644 index 0000000..ffe215c --- /dev/null +++ b/BUILD.md @@ -0,0 +1,134 @@ + +JFR Pary - dane licytacji: Informacje dla programistów +====================================================== + +Struktura repozytorium kodu +--------------------------- + +Katalog [`src`](src) zawiera komponenty źródłowe programu: + +* [kod skryptu Pythona](src/bidding_data.py), który wykonuje całą robotę +* [ikonę programu](src/icon.ico) wraz ze [źródłami](src/icon.xcf) +* [metadane programu](src/version) dla PyInstallera + +Katalog [`res`](res) zawiera pliki dołączane do programu: style, skrypty JS i grafikę. + +Katalogi `dist` i `build` są domyślnie puste i są katalogami roboczymi +PyInstallera. + +Katalog [`bundle`](bundle) zawiera wynikowe paczki ZIP z kolejnymi wersjami programu. + +W katalogu głównym znajdują się rozmaite README oraz skrypty budujące program. + +Od zera do bohatera - proces budowania programu +----------------------------------------------- + +Jedynym wymaganym do działania narzędzia elementem repozytorium jest źródłowy +skrypt [`bidding_data.py`](src/bidding_data.py). Cała reszta to tylko +fajerwerki i opakowanie w plik wykonywalny. + +Skrypt można uruchomić w dowolnym środowisku, w którym działa Python, a jego +wymagania wymienione są poniżej. `bidding_data.py` przyjmuje parametry +identycznie do wynikowego pliku wykonywalnego. + +Wersja z głównej gałęzi repozytorium działa jedynie pod Windowsem, z racji +używania podłączania się bezpośrednio do pliku BWS poprzez Accessowe ODBC. +Gałąź `csv` zawiera kompatybilną między systemami operacyjnymi wersję operującą +na danych podanych w plikach CSV, do których można wyeksportować dane z BWS. + +Skrypt z gałęzi `csv` jest w pełni funkcjonalny, acz obdarty z fajerwerków. +Może również nie być dalej rozwijany, w zależności od upierdliwości scalania +zmian. + +--- + +Pliku źródłowego można użyć jako modułu, jeśli kogoś to kręci, importując go +do swojej aplikacji poprzez: +``` +from bidding_data import JFRBidding +``` + +--- + +Skrypt można samodzielnie skompilować do pliku wykonywalnego, używając do tego +PyInstallera. Można to zrobić z pomocą dołączonego pliku [`bidding_data.spec`](bidding_data.spec): +``` +pyinstaller bidding_data.spec +``` +lub samodzielnie, podając odpowiednie parametry do PyInstallera: +``` +pyinstaller --one-file --version=[src\version](src/version) --icon=[src\icon.ico](src/icon.ico) src\bidding_data.py +``` +Zarówno metadane z pliku `src/version`, jak i ikona programu są w 100% opcjonalne. + +Wynik działania PyInstallera (pojedynczy plik wykonywalny) znajdzie się w katalogu `dist`. + +--- + +Skrypt wsadowy [`MAKE.bat`](MAKE.bat) pakuje potrzebne do dystrybucji programu dane +w jedną, zgrabną paczkę. Uruchamia on jedynie skrypt Windows PowerShell [`MAKE.ps1`](MAKE.ps1), +który, kolejno: + +* kompiluje EXE przy użyciu PyInstallera +* kopiuje README do katalogu `dist` +* kopiuje zasoby z `res` do katalogu `dist` +* odczytuje metadane utworzonego EXE +* tworzy z nich nazwę dla paczki +* pakuje cały katalog `dist` do paczki i umieszcza ją w `bundle` + +Wymagania systemowe +------------------- + +Skrypt [`bidding_data.py`](src/bidding_data.py): + +* python 2.x (testowane i tworzone w wersji 2.7.10) +* BeautifulSoup4 +* lxml (jako parser dla BS4) +* argparse +* pypyodbc + +Kompilacja do EXE: + +* [PyInstaller](http://pythonhosted.org/PyInstaller/) +* PyWin32 + +Zbudowanie paczki z [`bundle`](bundle): + +* Windows PowerShell +* .NET 4.5 + +Kod żródłowy +------------ + +Kod źródłowy stara się, z grubsza: + +* zgadzać ze standardami [PEP8](https://www.python.org/dev/peps/pep-0008/) +* nie robić [głupich rzeczy](http://stackoverflow.com/a/1732454) +* nie psuć raz przekształconej strony przy próbie ponownego przekształcenia +* komentować rzeczy nieoczywiste + +Operacje na stronach JFR +------------------------ + +Ramowy algorytm działania programu: + +1. Wczytać dane z BWS: tabela `BiddingData` zawiera dane licytacji, tabela +`RoundData` zawiera dane rund (numery rozdań, numery par itp.). +2. Zmapować numery rozdań JFR Pary (jedna, ciągła numeracja dla całego turnieju) +na numery rozdań fizycznych pudełek na sali (numery rozdań w BWS). +3. Skompilować tabele z licytacjami i zapisać je do osobnych plików. Format +nazwy pliku to `[PREFIX_JFR]_bidding_[NUMER_JFR]_[NUMERY_PAR].txt`. Numery par +w nazwie pliku posortowane są rosnąco. Każdy plik zawiera gotowy kod HTML +z licytacją. +4. Dołączyć do plików protokołów (`[PREFIX_JFR][NUMER_JFR].html`) skrypty JS +niezbędne do pokazania licytacji w protokole (jQuery i [`bidding.js`](res/javas/bidding.js)). +5. W plikach zawartości protokołów (`[PREFIX_JFR][NUMER_JFR].txt`), do każdego wiersza, +dla którego dysponujemy licytacją, dołączyć link pokazujący licytację. + +Program obsługuje wiele rozdań o tym samym numerze w jednym BWS i mapuje +rozdania na odpowiednie numery JFR na podstawie zestawu danych: nr stołu +(z sektorem), nr rundy, nr pudełka rozdaniowego. + +~~~ + +`Hello image, sing me a line from your favourite song.` diff --git a/MAKE.bat b/MAKE.bat new file mode 100644 index 0000000..f9c4987 --- /dev/null +++ b/MAKE.bat @@ -0,0 +1 @@ +powershell -NoProfile -ExecutionPolicy bypass -File MAKE.ps1 diff --git a/MAKE.ps1 b/MAKE.ps1 new file mode 100644 index 0000000..d0ddd47 --- /dev/null +++ b/MAKE.ps1 @@ -0,0 +1,9 @@ +& pyinstaller bidding_data.spec +Copy-Item '*.md' -Destination 'dist' -Force +Copy-Item 'res\*' -Destination 'dist' -Force -Recurse +Set-Variable -Name VersionInfo -Value (Get-Item 'dist\bidding_data.exe').VersionInfo +Set-Variable -Name FileVersion -Value $VersionInfo.FileVersion.Split(',') +Set-Variable -Name BundleName -Value ('bundle\\' + $VersionInfo.InternalName + '-' + $FileVersion[0].Trim() + '.' + $FileVersion[1].Trim() + '.zip') +Remove-Item $BundleName -ErrorAction SilentlyContinue +Add-Type -Assembly 'System.IO.Compression.FileSystem' +[System.IO.Compression.ZipFile]::CreateFromDirectory('dist', $BundleName) @@ -12,39 +12,49 @@ Przykładowe efekty działania: Wymagania systemowe ------------------- -* python 2.x (testowane i tworzone w wersji 2.7.10) -* BeautifulSoup4 -* lxml (jako parser dla BS4) -* argparse -* pypyodbc +* system opearcyjny MS Windows (testowane na Win7 i Win8.1) +* sterownik ODBC dla plików MS Access (zwykle obecny domyślnie z Windows, +weryfikowalny w Panelu Sterowania -> Narzędziach Administracyjnych -> +Żródła danych ODBC) Instalacja ---------- -Ściągnij zawartość tego repozytorium. +Ściągnij paczkę z programem, dostępną w katalogu [`bundle`](bundle) tego +repozytorium i rozpakuj ją do wybranego przez siebie katalogu roboczego +programu. -W katalogu WWW Par skonfiguruj JS i CSS niezbędny do prezentacji danych +W katalogu WWW Par skonfiguruj zasoby niezbędnę do prezentacji danych licytacji: -* skopiuj [`css/bidding.css`](css/bidding.css) do katalogu WWW -* dołącz plik [`css/bidding.css`](css/bidding.css) gdzieś w arkuszach stylów turnieju -(np. poprzez `@import` w `kolorki.css`) -* skopiuj [`javas/bidding.js`](javas/bidding.js) do podkatalogu javas katalogu WWW (plik dołączany -jest automatycznie do stron z wynikami) -* skopiuj [`images/link.png`](images/link.png) do podkatalogu images katalogu WWW +* skopiuj [`css/bidding.css`](res/css/bidding.css) do katalogu WWW +* dołącz plik [`css/bidding.css`](res/css/bidding.css) gdzieś w arkuszach +stylów turnieju (np. poprzez `@import` w `kolorki.css`) +* skopiuj [`javas/bidding.js`](res/javas/bidding.js) do podkatalogu javas +katalogu WWW (plik dołączany jest automatycznie do stron z wynikami) +* skopiuj [`images/link.png`](res/images/link.png) do podkatalogu images +katalogu WWW Już, gotowe. +Kompilacja i praca z kodem narzędzia +------------------------------------ + +Patrz: [`BUILD.md`](BUILD.md) + Użycie ------ -Skrypt [`bidding_data.py`](bidding_data.py) operuje na następujących +Program skłąda się ze skompilowanego skryptu języka Python, dostępnego +w katalogu [`src`](src) tego repozytorium. + +Skrypt [`bidding_data.py`](src/bidding_data.py) operuje na następujących danych wejściowych: * plikach HTML wygenerowanych po zakończeniu turnieju stron statycznych * pliku BWS sesji -Skrypt przyjmuje parametry w sposób następujący: +Program przyjmuje parametry w sposób następujący: ``` -python bidding_data.py DANE_SESJI.bws PLIK_TURNIEJU.html +bidding_data.exe DANE_SESJI.bws PLIK_TURNIEJU.html ``` `DANE_SESJI.bws` to plik BWS z zebranymi danymi sesji. @@ -54,13 +64,13 @@ python bidding_data.py DANE_SESJI.bws PLIK_TURNIEJU.html Narzędzie obsługuje niestandardowe zakresy numeracji rozdań w turnieju. -Mapowanie numeru rozdań z Par na numer rozdania w BWS (numer fizycznego pudełka) -odbywa się automatycznie (na podstawie danych z BWS). +Mapowanie numeru rozdań z Par na numer rozdania w BWS (numer fizycznego +pudełka) odbywa się automatycznie (na podstawie danych z BWS). Kompatybilność -------------- -Narzędzie łączy się przez ODBC do bazy MSAccess, więc działa jedynie +Narzędzie łączy się przez ODBC do bazy MS Access, więc działa jedynie pod Windowsem. Wersja operująca na wyeksportowanych plikach CSV (np. przez `mdb-export`), diff --git a/bidding_data.spec b/bidding_data.spec new file mode 100644 index 0000000..6fb6c0b --- /dev/null +++ b/bidding_data.spec @@ -0,0 +1,17 @@ +import os +a = Analysis(['src\\bidding_data.py'], + pathex=[os.path.abspath('.')], + hiddenimports=[], + hookspath=None, + runtime_hooks=None) +pyz = PYZ(a.pure) +exe = EXE(pyz, + a.scripts, + a.binaries, + a.zipfiles, + a.datas, + name='bidding_data.exe', + debug=False, + strip=None, + upx=True, + console=True , version='src\\version', icon='src\\icon.ico') diff --git a/bundle/.gitignore b/bundle/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/bundle/.gitignore diff --git a/bundle/bidding_data-1.0.zip b/bundle/bidding_data-1.0.zip Binary files differnew file mode 100644 index 0000000..2ffa8b6 --- /dev/null +++ b/bundle/bidding_data-1.0.zip diff --git a/css/bidding.css b/res/css/bidding.css index ea4ef4a..ea4ef4a 100644 --- a/css/bidding.css +++ b/res/css/bidding.css diff --git a/images/link.png b/res/images/link.png Binary files differindex e417d59..e417d59 100644 --- a/images/link.png +++ b/res/images/link.png diff --git a/javas/bidding.js b/res/javas/bidding.js index 5932e66..5932e66 100644 --- a/javas/bidding.js +++ b/res/javas/bidding.js diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..0d20b64 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/bidding_data.py b/src/bidding_data.py index ae789f1..ae789f1 100644 --- a/bidding_data.py +++ b/src/bidding_data.py diff --git a/src/icon.ico b/src/icon.ico Binary files differnew file mode 100644 index 0000000..ffc9601 --- /dev/null +++ b/src/icon.ico diff --git a/src/icon.xcf b/src/icon.xcf Binary files differnew file mode 100644 index 0000000..b625556 --- /dev/null +++ b/src/icon.xcf diff --git a/src/version b/src/version new file mode 100644 index 0000000..03aad11 --- /dev/null +++ b/src/version @@ -0,0 +1,39 @@ +# UTF-8 +VSVersionInfo( + ffi=FixedFileInfo( + filevers=(1, 0, 0, 0), + prodvers=(1, 0, 0, 0), + # Contains a bitmask that specifies the valid bits 'flags' + mask=0x3f, + # Contains a bitmask that specifies the Boolean attributes of the file. + flags=0x0, + # The operating system for which this file was designed. + # 0x4 - NT and there is no need to change it. + OS=0x4, + # The general type of file. + # 0x1 - the file is an application. + fileType=0x1, + # The function of the file. + # 0x0 - the function is not defined for this fileType + subtype=0x0, + # Creation date and time stamp. + date=(0, 0) + ), + kids=[ + StringFileInfo( + [ + StringTable( + u'040904b0', # 0x0409 = 1033 = English, 0x04b0 = 1200 = UTF-8 + [StringStruct(u'CompanyName', u'emkael.info'), + StringStruct(u'ProductName', u'bidding_data'), + StringStruct(u'ProductVersion', u'1, 0, 0, 0'), + StringStruct(u'InternalName', u'bidding_data'), + StringStruct(u'OriginalFilename', u'bidding_data.exe'), + StringStruct(u'FileVersion', u'1, 0, 0, 0'), + StringStruct(u'FileDescription', u'Bidding data display for JFR Pary result pages'), + StringStruct(u'LegalCopyright', u'© 2015 mkl (Michał Klichowicz)'), + StringStruct(u'LegalTrademarks', u''),]) + ]), + VarFileInfo([VarStruct(u'Translation', [1033, 1200])]) + ] +) |