Compare commits
13 commits
7934babad2
...
6dd98f5984
Author | SHA1 | Date | |
---|---|---|---|
|
6dd98f5984 | ||
|
198038b1c9 | ||
|
52eeb40942 | ||
|
acbf11de31 | ||
|
45f8c312a4 | ||
|
81432ef353 | ||
|
1b89ae2346 | ||
|
0b5698dff0 | ||
|
dba230b40a | ||
|
6d4a1191cc | ||
|
c9de855dd8 | ||
|
9a51c55402 | ||
|
3e873a3fde |
|
@ -8,7 +8,7 @@ install:
|
||||||
- choco install strawberryperl
|
- choco install strawberryperl
|
||||||
- copy %PYTHON%\python.exe %PYTHON%\python3.exe
|
- copy %PYTHON%\python.exe %PYTHON%\python3.exe
|
||||||
- SET PATH=%PYTHON%;C:\strawberry\c\bin;C:\strawberry\perl\site\bin;C:\strawberry\perl\bin;%PATH%
|
- SET PATH=%PYTHON%;C:\strawberry\c\bin;C:\strawberry\perl\site\bin;C:\strawberry\perl\bin;%PATH%
|
||||||
- python3 -mpip install Pillow attrs flake8 flake8-import-order py2exe pycotap pygame pysol-cards random2 six
|
- python3 -mpip install Pillow attrs configobj flake8 flake8-import-order py2exe pycotap pygame pysol-cards random2 setuptools six
|
||||||
- perl -v
|
- perl -v
|
||||||
- copy C:\msys64\mingw64\bin\mingw32-make.exe C:\msys64\mingw64\bin\make.exe
|
- copy C:\msys64\mingw64\bin\mingw32-make.exe C:\msys64\mingw64\bin\make.exe
|
||||||
- SET PATH=C:\strawberry\c\bin;C:\strawberry\perl\site\bin;C:\strawberry\perl\bin;%PATH%
|
- SET PATH=C:\strawberry\c\bin;C:\strawberry\perl\site\bin;C:\strawberry\perl\bin;%PATH%
|
||||||
|
|
1
.gitignore
vendored
|
@ -10,6 +10,7 @@
|
||||||
/html-src/html/*
|
/html-src/html/*
|
||||||
/images
|
/images
|
||||||
/locale/*
|
/locale/*
|
||||||
|
/po/de.po
|
||||||
/po/it.po
|
/po/it.po
|
||||||
/po/pl.po
|
/po/pl.po
|
||||||
/po/ru.po
|
/po/ru.po
|
||||||
|
|
|
@ -39,7 +39,7 @@ before_install:
|
||||||
install:
|
install:
|
||||||
- sudo cpanm --notest Capture::Tiny
|
- sudo cpanm --notest Capture::Tiny
|
||||||
- sudo cpanm Code::TidyAll::Plugin::Flake8 Perl::Tidy Test::Code::TidyAll Test::Differences Test::TrailingSpace
|
- sudo cpanm Code::TidyAll::Plugin::Flake8 Perl::Tidy Test::Code::TidyAll Test::Differences Test::TrailingSpace
|
||||||
- export PY_MODS='attrs pycotap pysol-cards random2 six'
|
- export PY_MODS='attrs configobj pycotap pysol-cards random2 setuptools six'
|
||||||
- "`which python3` -m pip install --upgrade flake8 flake8-import-order $PY_MODS"
|
- "`which python3` -m pip install --upgrade flake8 flake8-import-order $PY_MODS"
|
||||||
- "sudo /usr/bin/python3 -m pip install --upgrade $PY_MODS || true"
|
- "sudo /usr/bin/python3 -m pip install --upgrade $PY_MODS || true"
|
||||||
- "sudo `which python2` -m pip install --upgrade $PY_MODS"
|
- "sudo `which python2` -m pip install --upgrade $PY_MODS"
|
||||||
|
|
|
@ -7,7 +7,7 @@ include pysol.py setup.py setup_osx.py setup.cfg MANIFEST.in Makefile
|
||||||
include COPYING README.md AUTHORS.md README.android README.kivy
|
include COPYING README.md AUTHORS.md README.android README.kivy
|
||||||
include NEWS.asciidoc
|
include NEWS.asciidoc
|
||||||
#recursive-include pysollib *.py
|
#recursive-include pysollib *.py
|
||||||
include pysollib/*.py pysollib/macosx/*.py pysollib/configobj/*.py
|
include pysollib/*.py pysollib/macosx/*.py
|
||||||
include pysollib/winsystems/*.py
|
include pysollib/winsystems/*.py
|
||||||
include pysollib/tk/*.py pysollib/tile/*.py pysollib/pysolgtk/*.py
|
include pysollib/tk/*.py pysollib/tile/*.py pysollib/pysolgtk/*.py
|
||||||
include pysollib/game/*.py
|
include pysollib/game/*.py
|
||||||
|
@ -19,7 +19,7 @@ include data/pysolfc.glade
|
||||||
graft data/themes
|
graft data/themes
|
||||||
recursive-exclude data/themes *.py
|
recursive-exclude data/themes *.py
|
||||||
include scripts/build.bat scripts/create_iss.py scripts/mahjongg_utils.py
|
include scripts/build.bat scripts/create_iss.py scripts/mahjongg_utils.py
|
||||||
include scripts/pygettext.py scripts/all_games.py scripts/cardset_viewer.py
|
include scripts/all_games.py scripts/cardset_viewer.py
|
||||||
include scripts/cardconv scripts/cardsetsgiftobmp
|
include scripts/cardconv scripts/cardsetsgiftobmp
|
||||||
include scripts/gen_individual_importing_tests.py
|
include scripts/gen_individual_importing_tests.py
|
||||||
include tests/individually-importing/PLACEHOLDER
|
include tests/individually-importing/PLACEHOLDER
|
||||||
|
|
69
Makefile
|
@ -1,76 +1,65 @@
|
||||||
# Makefile for PySolFC
|
# Makefile for PySolFC
|
||||||
|
|
||||||
override LANG=C
|
ifeq ($(OS),Windows_NT)
|
||||||
override PYSOL_DEBUG=1
|
path_sep = ;
|
||||||
|
else
|
||||||
|
path_sep = :
|
||||||
|
endif
|
||||||
|
export PYTHONPATH := $(PYTHONPATH)$(path_sep)$(CURDIR)
|
||||||
|
|
||||||
PYSOLLIB_FILES=pysollib/tk/*.py pysollib/tile/*.py pysollib/*.py \
|
.PHONY: all install dist rpm all_games_html rules pot mo pretest test runtest
|
||||||
pysollib/games/*.py pysollib/games/special/*.py \
|
|
||||||
pysollib/games/ultra/*.py pysollib/games/mahjongg/*.py \
|
|
||||||
pysollib/kivy/*.py
|
|
||||||
|
|
||||||
.PHONY : all install dist all_games_html rules pot mo
|
|
||||||
|
|
||||||
all:
|
all:
|
||||||
@echo "No default target"
|
@echo "No default target"
|
||||||
|
|
||||||
install:
|
install:
|
||||||
python setup.py install
|
python3 setup.py install
|
||||||
|
|
||||||
dist: all_games_html rules mo
|
dist: all_games_html rules mo
|
||||||
python3 setup.py sdist
|
python3 setup.py sdist
|
||||||
|
|
||||||
rpm: all_games_html rules mo
|
rpm: all_games_html rules mo
|
||||||
python setup.py bdist_rpm
|
python3 setup.py bdist_rpm
|
||||||
|
|
||||||
all_games_html:
|
all_games_html: rules
|
||||||
PYTHONPATH=`pwd` ./scripts/all_games.py html id doc/rules bare > docs/all_games.html
|
cd data/html && $(CURDIR)/scripts/all_games.py html id rules > all_games.html
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
export PYTHONPATH=`pwd`; (cd html-src && ./gen-html.py)
|
cd html-src && ./gen-html.py
|
||||||
cp -r html-src/images html-src/html
|
cp -r html-src/images html-src/html
|
||||||
rm -rf data/html
|
rm -rf data/html
|
||||||
mv html-src/html data
|
mv html-src/html data
|
||||||
|
|
||||||
pot:
|
pot:
|
||||||
PYTHONPATH=`pwd` ./scripts/all_games.py gettext > po/games.pot
|
./scripts/all_games.py gettext > po/games.pot
|
||||||
PYTHONPATH=`pwd` ./scripts/pygettext.py -k n_ --ngettext-keyword ungettext -o po/pysol-1.pot $(PYSOLLIB_FILES)
|
xgettext --keyword=n_ -o po/pysol.pot \
|
||||||
xgettext -L C --keyword=N_ -o po/pysol-2.pot data/glade-translations
|
pysollib/*.py pysollib/*/*.py pysollib/*/*/*.py data/pysolfc.glade
|
||||||
msgcat po/pysol-1.pot po/pysol-2.pot > po/pysol.pot
|
set -e; \
|
||||||
rm -f po/pysol-1.pot po/pysol-2.pot
|
for lng in ru de pl it; do \
|
||||||
for lng in ru pl; do \
|
msgmerge --update --quiet --backup=none po/$${lng}_pysol.po po/pysol.pot; \
|
||||||
mv -f po/$${lng}_pysol.po po/$${lng}_pysol.old.po; \
|
msgmerge --update --quiet --backup=none po/$${lng}_games.po po/games.pot; \
|
||||||
msgmerge po/$${lng}_pysol.old.po po/pysol.pot > po/$${lng}_pysol.po; \
|
|
||||||
rm -f po/$${lng}_pysol.old.po; \
|
|
||||||
mv -f po/$${lng}_games.po po/$${lng}_games.old.po; \
|
|
||||||
msgmerge po/$${lng}_games.old.po po/games.pot > po/$${lng}_games.po; \
|
|
||||||
rm -f po/$${lng}_games.old.po; \
|
|
||||||
done
|
done
|
||||||
|
|
||||||
mo:
|
mo:
|
||||||
for loc in ru de pl it; do \
|
set -e; \
|
||||||
test -d locale/$${loc}/LC_MESSAGES || mkdir -p locale/$${loc}/LC_MESSAGES; \
|
|
||||||
done
|
|
||||||
for lang in ru pl it; do \
|
|
||||||
msgcat --use-first po/$${lang}_games.po po/$${lang}_pysol.po > po/$${lang}.po 2>/dev/null; \
|
|
||||||
done
|
|
||||||
for lang in ru de pl it; do \
|
for lang in ru de pl it; do \
|
||||||
msgfmt -o locale/$${lang}/LC_MESSAGES/pysol.mo po/$${lang}.po; \
|
mkdir -p locale/$${lang}/LC_MESSAGES; \
|
||||||
|
msgcat --use-first po/$${lang}_games.po po/$${lang}_pysol.po > po/$${lang}.po; \
|
||||||
|
msgfmt --check -o locale/$${lang}/LC_MESSAGES/pysol.mo po/$${lang}.po; \
|
||||||
done
|
done
|
||||||
|
|
||||||
pretest:
|
pretest:
|
||||||
@rm -f tests/individually-importing/*.py # To avoid stray files
|
rm -f tests/individually-importing/*.py # To avoid stray files
|
||||||
python3 scripts/gen_individual_importing_tests.py
|
python3 scripts/gen_individual_importing_tests.py
|
||||||
|
|
||||||
TEST_ENV_PATH = "`pwd`:`pwd`/tests/lib"
|
TEST_ENV_PATH = $(CURDIR)$(path_sep)$(CURDIR)/tests/lib
|
||||||
TEST_ENV = PYTHONPATH="$$PYTHONPATH:"$(TEST_ENV_PATH) PERL5LIB="$$PERL5LIB:"$(TEST_ENV_PATH)
|
|
||||||
TEST_FILES = tests/style/*.t tests/unit-generated/*.py tests/individually-importing/*.py
|
TEST_FILES = tests/style/*.t tests/unit-generated/*.py tests/individually-importing/*.py
|
||||||
|
|
||||||
define RUN_TESTS
|
test runtest: export PYTHONPATH := $(PYTHONPATH)$(path_sep)$(TEST_ENV_PATH)
|
||||||
$(TEST_ENV) $1 $(TEST_FILES)
|
test runtest: export PERL5LIB := $(PERL5LIB)$(path_sep)$(TEST_ENV_PATH)
|
||||||
endef
|
|
||||||
|
|
||||||
test: pretest
|
test: pretest
|
||||||
$(call RUN_TESTS,prove)
|
prove $(TEST_FILES)
|
||||||
|
|
||||||
runtest: pretest
|
runtest: pretest
|
||||||
$(call RUN_TESTS,runprove)
|
runprove $(TEST_FILES)
|
||||||
|
|
|
@ -27,6 +27,6 @@ python3 -m pythonforandroid.toolchain apk \
|
||||||
--version ${version} \
|
--version ${version} \
|
||||||
--orientation sensor \
|
--orientation sensor \
|
||||||
--color=always \
|
--color=always \
|
||||||
--icon ${tmpdir}/data/images/misc/pysol01.png \
|
--icon ${tmpdir}/data/images/icons/48x48/pysol.png \
|
||||||
--presplash ${tmpdir}/data/images/misc/pysol06.png \
|
--presplash ${tmpdir}/data/images/icons/1024x1024/pysol.png \
|
||||||
--copy-libs
|
--copy-libs
|
||||||
|
|
|
@ -52,8 +52,8 @@ python3 -m pythonforandroid.toolchain apk \
|
||||||
--version ${version} \
|
--version ${version} \
|
||||||
--orientation sensor \
|
--orientation sensor \
|
||||||
--color=always \
|
--color=always \
|
||||||
--icon ${tmpdir}/data/images/misc/pysol01.png \
|
--icon ${tmpdir}/data/images/icons/48x48/pysol.png \
|
||||||
--presplash ${tmpdir}/data/images/misc/pysol06.png \
|
--presplash ${tmpdir}/data/images/icons/1024x1024/pysol.png \
|
||||||
--copy-libs
|
--copy-libs
|
||||||
|
|
||||||
# keystore options (instead environment vars):
|
# keystore options (instead environment vars):
|
||||||
|
|
|
@ -39,8 +39,8 @@ python3 -m pythonforandroid.toolchain apk \
|
||||||
--version ${version} \
|
--version ${version} \
|
||||||
--orientation sensor \
|
--orientation sensor \
|
||||||
--color=always \
|
--color=always \
|
||||||
--icon ${tmpdir}/data/images/misc/pysol01.png \
|
--icon ${tmpdir}/data/images/icons/48x48/pysol.png \
|
||||||
--presplash ${tmpdir}/data/images/misc/pysol06.png \
|
--presplash ${tmpdir}/data/images/icons/1024x1024/pysol.png \
|
||||||
--copy-libs
|
--copy-libs
|
||||||
|
|
||||||
# python3 -m pythonforandroid.toolchain apk
|
# python3 -m pythonforandroid.toolchain apk
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
/*
|
|
||||||
* Translatable strings file generated by Glade.
|
|
||||||
* Add this file to your project's POTFILES.in.
|
|
||||||
* DO NOT compile it as part of your application.
|
|
||||||
*/
|
|
||||||
|
|
||||||
gchar *s = N_("Game Statistics");
|
|
||||||
gchar *s = N_("Game:");
|
|
||||||
gchar *s = N_("Won:");
|
|
||||||
gchar *s = N_("Total:");
|
|
||||||
gchar *s = N_("Lost:");
|
|
||||||
gchar *s = N_("Current session");
|
|
||||||
gchar *s = N_("Won:");
|
|
||||||
gchar *s = N_("Lost:");
|
|
||||||
gchar *s = N_("Total:");
|
|
||||||
gchar *s = N_("Total");
|
|
||||||
gchar *s = N_("Current game");
|
|
||||||
gchar *s = N_("Playing time:");
|
|
||||||
gchar *s = N_("Moves:");
|
|
||||||
gchar *s = N_("Total moves:");
|
|
||||||
gchar *s = N_("Minimum");
|
|
||||||
gchar *s = N_("Maximum");
|
|
||||||
gchar *s = N_("Average");
|
|
||||||
gchar *s = N_("Summary");
|
|
||||||
gchar *s = N_("Playing time");
|
|
||||||
gchar *s = N_("Moves");
|
|
||||||
gchar *s = N_("Total moves");
|
|
||||||
gchar *s = N_("Game:");
|
|
||||||
gchar *s = N_("Top 10");
|
|
||||||
gchar *s = N_("All games");
|
|
||||||
gchar *s = N_("Full log");
|
|
||||||
gchar *s = N_("Session log");
|
|
||||||
gchar *s = N_("Set timeouts");
|
|
||||||
gchar *s = N_("Demo:");
|
|
||||||
gchar *s = N_("Hint:");
|
|
||||||
gchar *s = N_("Raise card:");
|
|
||||||
gchar *s = N_("Highlight piles:");
|
|
||||||
gchar *s = N_("Highlight cards:");
|
|
||||||
gchar *s = N_("Highlight same rank:");
|
|
||||||
gchar *s = N_("Set colors");
|
|
||||||
gchar *s = N_("Highlight piles:");
|
|
||||||
gchar *s = N_("Highlight cards 1:");
|
|
||||||
gchar *s = N_("Highlight cards 2:");
|
|
||||||
gchar *s = N_("Highlight same rank 1:");
|
|
||||||
gchar *s = N_("Highlight same rank 2:");
|
|
||||||
gchar *s = N_("Hint arrow:");
|
|
||||||
gchar *s = N_("Highlight not matching:");
|
|
||||||
gchar *s = N_("Change...");
|
|
||||||
gchar *s = N_("Change...");
|
|
||||||
gchar *s = N_("Change...");
|
|
||||||
gchar *s = N_("Change...");
|
|
||||||
gchar *s = N_("Change...");
|
|
||||||
gchar *s = N_("Change...");
|
|
||||||
gchar *s = N_("Change...");
|
|
||||||
gchar *s = N_("Change...");
|
|
||||||
gchar *s = N_("Text foreground:");
|
|
||||||
gchar *s = N_("Set font");
|
|
||||||
gchar *s = N_("HTML: ");
|
|
||||||
gchar *s = N_("Small: ");
|
|
||||||
gchar *s = N_("Fixed: ");
|
|
||||||
gchar *s = N_("Tableau default: ");
|
|
||||||
gchar *s = N_("Tableau fixed: ");
|
|
||||||
gchar *s = N_("Tableau small: ");
|
|
||||||
gchar *s = N_("Tableau large: ");
|
|
||||||
gchar *s = N_("Change...");
|
|
||||||
gchar *s = N_("Change...");
|
|
||||||
gchar *s = N_("Change...");
|
|
||||||
gchar *s = N_("Change...");
|
|
||||||
gchar *s = N_("Change...");
|
|
||||||
gchar *s = N_("Change...");
|
|
||||||
gchar *s = N_("Change...");
|
|
||||||
gchar *s = N_("Sound settings");
|
|
||||||
gchar *s = N_("Sound enabled");
|
|
||||||
gchar *s = N_("Sample volume:");
|
|
||||||
gchar *s = N_("Music volume:");
|
|
||||||
gchar *s = N_("Enable samles");
|
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
@ -7,4 +7,4 @@ Terminal=false
|
||||||
Type=Application
|
Type=Application
|
||||||
Categories=Game;CardGame;
|
Categories=Game;CardGame;
|
||||||
Keywords=solitaire;patience;cards;pysolfc;klondike;
|
Keywords=solitaire;patience;cards;pysolfc;klondike;
|
||||||
Icon=/usr/share/icons/pysol01.png
|
Icon=pysol
|
||||||
|
|
4587
po/de_pysol.po
Normal file
11
po/games.pot
|
@ -5,7 +5,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PySol 0.0.1\n"
|
"Project-Id-Version: PySol 0.0.1\n"
|
||||||
"POT-Creation-Date: Mon Mar 7 21:38:07 2011\n"
|
"POT-Creation-Date: Thu Jul 18 19:36:14 2019\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -702,6 +702,9 @@ msgstr ""
|
||||||
msgid "Czarina"
|
msgid "Czarina"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Daddy Longlegs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Danda"
|
msgid "Danda"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1272,6 +1275,12 @@ msgstr ""
|
||||||
msgid "FreeCell"
|
msgid "FreeCell"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "FreeCell with Two Reserves"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "FreeCell with Zero Reserves"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Frog"
|
msgid "Frog"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,16 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: it_games\n"
|
"Project-Id-Version: it_games\n"
|
||||||
"POT-Creation-Date: Thu Sep 6 15:06:46 2007\n"
|
"POT-Creation-Date: Thu Jul 18 18:43:59 2019\n"
|
||||||
"PO-Revision-Date: 2011-05-12 18:46+0200\n"
|
"PO-Revision-Date: 2011-05-12 18:46+0200\n"
|
||||||
"Last-Translator: Giuliano Colla <giuliano.colla@gmail.com>\n"
|
"Last-Translator: Giuliano Colla <giuliano.colla@gmail.com>\n"
|
||||||
"Language-Team: Italiano <it@li.org>\n"
|
"Language-Team: Italiano <it@li.org>\n"
|
||||||
|
"Language: it\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Generated-By: ./scripts/all_games.py 0.1\n"
|
"Generated-By: ./scripts/all_games.py 0.1\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"X-Generator: KBabel 1.11.4\n"
|
"X-Generator: KBabel 1.11.4\n"
|
||||||
|
|
||||||
msgid " 3x3 Matrix"
|
msgid " 3x3 Matrix"
|
||||||
|
@ -75,6 +77,9 @@ msgstr "Conoscenti"
|
||||||
msgid "Adela"
|
msgid "Adela"
|
||||||
msgstr "Adelina"
|
msgstr "Adelina"
|
||||||
|
|
||||||
|
msgid "Aglet"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Agnes Bernauer"
|
msgid "Agnes Bernauer"
|
||||||
msgstr "Agnese Bernauer"
|
msgstr "Agnese Bernauer"
|
||||||
|
|
||||||
|
@ -243,6 +248,12 @@ msgstr ""
|
||||||
msgid "Bavarian Patience"
|
msgid "Bavarian Patience"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Bayan"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Beacon"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Beak and Flipper"
|
msgid "Beak and Flipper"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -522,6 +533,9 @@ msgstr ""
|
||||||
msgid "Cat's Tail"
|
msgid "Cat's Tail"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Catherine the Great"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Cavalier"
|
msgid "Cavalier"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -690,6 +704,9 @@ msgstr ""
|
||||||
msgid "Czarina"
|
msgid "Czarina"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Daddy Longlegs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Danda"
|
msgid "Danda"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -804,6 +821,9 @@ msgstr ""
|
||||||
msgid "Double Bisley"
|
msgid "Double Bisley"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Double Blue Moon"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Double Canfield"
|
msgid "Double Canfield"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -876,12 +896,18 @@ msgstr ""
|
||||||
msgid "Double Measure"
|
msgid "Double Measure"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Double Montana"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Double Pyramid"
|
msgid "Double Pyramid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Double Rail"
|
msgid "Double Rail"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Double Red Moon"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Double Russian Solitaire"
|
msgid "Double Russian Solitaire"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -942,6 +968,9 @@ msgstr ""
|
||||||
msgid "Dutch Solitaire"
|
msgid "Dutch Solitaire"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Dutchess"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Eagle Wing"
|
msgid "Eagle Wing"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -972,6 +1001,9 @@ msgstr ""
|
||||||
msgid "Eight Off"
|
msgid "Eight Off"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Eight Packs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Eight Sages"
|
msgid "Eight Sages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1158,6 +1190,9 @@ msgstr ""
|
||||||
msgid "Flying Dragon"
|
msgid "Flying Dragon"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Foothold"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Footling"
|
msgid "Footling"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1242,6 +1277,12 @@ msgstr ""
|
||||||
msgid "FreeCell"
|
msgid "FreeCell"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "FreeCell with Two Reserves"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "FreeCell with Zero Reserves"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Frog"
|
msgid "Frog"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1425,6 +1466,9 @@ msgstr ""
|
||||||
msgid "Hanoi Puzzle 6"
|
msgid "Hanoi Puzzle 6"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Hanoi Sequence"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Happy New Year"
|
msgid "Happy New Year"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1638,6 +1682,9 @@ msgstr ""
|
||||||
msgid "Katrina's Game Relaxed"
|
msgid "Katrina's Game Relaxed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Kentish"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Khadga"
|
msgid "Khadga"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -2310,7 +2357,7 @@ msgstr ""
|
||||||
msgid "Mahjongg Stargate"
|
msgid "Mahjongg Stargate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Mahjongg Step Pyramid"
|
msgid "Mahjongg Steps Pyramid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Mahjongg Stonehenge"
|
msgid "Mahjongg Stonehenge"
|
||||||
|
@ -2652,6 +2699,15 @@ msgstr ""
|
||||||
msgid "Northwest Territory"
|
msgid "Northwest Territory"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Not Shisen-Sho 14x6"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Not Shisen-Sho 18x8"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Not Shisen-Sho 24x12"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Number Ten"
|
msgid "Number Ten"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -2904,6 +2960,9 @@ msgstr ""
|
||||||
msgid "Puss in the Corner"
|
msgid "Puss in the Corner"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Putt Putt"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Pyramid"
|
msgid "Pyramid"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -2925,12 +2984,18 @@ msgstr ""
|
||||||
msgid "Quadrangle"
|
msgid "Quadrangle"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Quadrille"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Quadruple Alliance"
|
msgid "Quadruple Alliance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Quads"
|
msgid "Quads"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Quads +"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Quartets"
|
msgid "Quartets"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3000,6 +3065,10 @@ msgstr ""
|
||||||
msgid "Relax"
|
msgid "Relax"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
|
msgid "Relaxed Accordion"
|
||||||
|
msgstr "Fisarmonica"
|
||||||
|
|
||||||
msgid "Relaxed FreeCell"
|
msgid "Relaxed FreeCell"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3015,6 +3084,9 @@ msgstr ""
|
||||||
msgid "Relaxed Spider"
|
msgid "Relaxed Spider"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Relaxed Three Fir-trees"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Repair"
|
msgid "Repair"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3228,13 +3300,13 @@ msgstr ""
|
||||||
msgid "Shifting"
|
msgid "Shifting"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Shisen-Sho (No Gra) 14x6"
|
msgid "Shisen-Sho (No Gravity) 14x6"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Shisen-Sho (No Gra) 18x8"
|
msgid "Shisen-Sho (No Gravity) 18x8"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Shisen-Sho (No Gra) 24x12"
|
msgid "Shisen-Sho (No Gravity) 24x12"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Shisen-Sho 14x6"
|
msgid "Shisen-Sho 14x6"
|
||||||
|
@ -3423,15 +3495,15 @@ msgstr ""
|
||||||
msgid "Stargate"
|
msgid "Stargate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Step Pyramid"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Step-Up"
|
msgid "Step-Up"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Steps"
|
msgid "Steps"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Steps Pyramid"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Steve"
|
msgid "Steve"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3597,6 +3669,9 @@ msgstr ""
|
||||||
msgid "Thieves of Egypt"
|
msgid "Thieves of Egypt"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Thirteen Packs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Thirteen Up"
|
msgid "Thirteen Up"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3864,6 +3939,9 @@ msgstr ""
|
||||||
msgid "Waning Moon"
|
msgid "Waning Moon"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Wasatch"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Washington's Favorite"
|
msgid "Washington's Favorite"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3968,4 +4046,3 @@ msgstr ""
|
||||||
|
|
||||||
msgid "Zodiac"
|
msgid "Zodiac"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
6337
po/it_pysol.po
|
@ -4,10 +4,11 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PySol 0.0.1\n"
|
"Project-Id-Version: PySol 0.0.1\n"
|
||||||
"POT-Creation-Date: Mon Mar 7 21:38:07 2011\n"
|
"POT-Creation-Date: Thu Jul 18 18:43:59 2019\n"
|
||||||
"PO-Revision-Date: 2010-12-16 23:56+0100\n"
|
"PO-Revision-Date: 2010-12-16 23:56+0100\n"
|
||||||
"Last-Translator: Jerzy Trzeciak <artusek@wp.pl>\n"
|
"Last-Translator: Jerzy Trzeciak <artusek@wp.pl>\n"
|
||||||
"Language-Team: Polish <pl@li.org>\n"
|
"Language-Team: Polish <pl@li.org>\n"
|
||||||
|
"Language: pl\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
@ -705,6 +706,9 @@ msgstr ""
|
||||||
msgid "Czarina"
|
msgid "Czarina"
|
||||||
msgstr "Czarina"
|
msgstr "Czarina"
|
||||||
|
|
||||||
|
msgid "Daddy Longlegs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Danda"
|
msgid "Danda"
|
||||||
msgstr "Danda"
|
msgstr "Danda"
|
||||||
|
|
||||||
|
@ -1277,6 +1281,12 @@ msgstr "Free Napoleon"
|
||||||
msgid "FreeCell"
|
msgid "FreeCell"
|
||||||
msgstr "FreeCell"
|
msgstr "FreeCell"
|
||||||
|
|
||||||
|
msgid "FreeCell with Two Reserves"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "FreeCell with Zero Reserves"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Frog"
|
msgid "Frog"
|
||||||
msgstr "Żaba"
|
msgstr "Żaba"
|
||||||
|
|
||||||
|
|
6012
po/pl_pysol.po
5659
po/pysol.pot
|
@ -5,14 +5,17 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PySol 0.0.1\n"
|
"Project-Id-Version: PySol 0.0.1\n"
|
||||||
"POT-Creation-Date: Mon Mar 7 21:38:07 2011\n"
|
"POT-Creation-Date: Thu Jul 18 18:43:59 2019\n"
|
||||||
"PO-Revision-Date: 2007-09-05 17:43+0400\n"
|
"PO-Revision-Date: 2007-09-05 17:43+0400\n"
|
||||||
"Last-Translator: Скоморох <skomoroh@gmail.com>\n"
|
"Last-Translator: Скоморох <skomoroh@gmail.com>\n"
|
||||||
"Language-Team: Russian <ru@li.org>\n"
|
"Language-Team: Russian <ru@li.org>\n"
|
||||||
|
"Language: ru\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: utf-8\n"
|
"Content-Transfer-Encoding: utf-8\n"
|
||||||
"Generated-By: ./scripts/all_games.py 0.1\n"
|
"Generated-By: ./scripts/all_games.py 0.1\n"
|
||||||
|
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||||
|
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||||
|
|
||||||
msgid " 3x3 Matrix"
|
msgid " 3x3 Matrix"
|
||||||
msgstr "Матрица 3x3"
|
msgstr "Матрица 3x3"
|
||||||
|
@ -707,6 +710,10 @@ msgstr "Творог и сыворотка"
|
||||||
msgid "Czarina"
|
msgid "Czarina"
|
||||||
msgstr "Царевна"
|
msgstr "Царевна"
|
||||||
|
|
||||||
|
#, fuzzy
|
||||||
|
msgid "Daddy Longlegs"
|
||||||
|
msgstr "Тенистые аллеи"
|
||||||
|
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
msgid "Danda"
|
msgid "Danda"
|
||||||
msgstr "Алмаз"
|
msgstr "Алмаз"
|
||||||
|
@ -1289,6 +1296,12 @@ msgstr "Свободный Наполеон"
|
||||||
msgid "FreeCell"
|
msgid "FreeCell"
|
||||||
msgstr "Свободная ячейка"
|
msgstr "Свободная ячейка"
|
||||||
|
|
||||||
|
msgid "FreeCell with Two Reserves"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "FreeCell with Zero Reserves"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Frog"
|
msgid "Frog"
|
||||||
msgstr "Лягушка"
|
msgstr "Лягушка"
|
||||||
|
|
||||||
|
|
6322
po/ru_pysol.po
|
@ -65,6 +65,7 @@ from pysollib.pysoltk import bind, wm_map
|
||||||
from pysollib.settings import DEBUG
|
from pysollib.settings import DEBUG
|
||||||
from pysollib.settings import PACKAGE, TITLE, TOOLKIT, TOP_TITLE
|
from pysollib.settings import PACKAGE, TITLE, TOOLKIT, TOP_TITLE
|
||||||
from pysollib.settings import VERSION, VERSION_TUPLE
|
from pysollib.settings import VERSION, VERSION_TUPLE
|
||||||
|
from pysollib.struct_new import NewStruct
|
||||||
|
|
||||||
import six
|
import six
|
||||||
from six import BytesIO
|
from six import BytesIO
|
||||||
|
@ -259,7 +260,7 @@ def _highlightCards__calc_item(canvas, delta, cw, ch, s, c1, c2, color):
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@attr.s
|
||||||
class StackGroups(object):
|
class StackGroups(NewStruct):
|
||||||
dropstacks = attr.ib(factory=list)
|
dropstacks = attr.ib(factory=list)
|
||||||
hp_stacks = attr.ib(factory=list) # for getHightlightPilesStacks()
|
hp_stacks = attr.ib(factory=list) # for getHightlightPilesStacks()
|
||||||
openstacks = attr.ib(factory=list)
|
openstacks = attr.ib(factory=list)
|
||||||
|
@ -280,7 +281,7 @@ class StackGroups(object):
|
||||||
|
|
||||||
|
|
||||||
@attr.s
|
@attr.s
|
||||||
class StackRegions(object):
|
class StackRegions(NewStruct):
|
||||||
# list of tuples(stacks, rect)
|
# list of tuples(stacks, rect)
|
||||||
info = attr.ib(factory=list)
|
info = attr.ib(factory=list)
|
||||||
# list of stacks in no region
|
# list of stacks in no region
|
||||||
|
@ -317,6 +318,37 @@ class StackRegions(object):
|
||||||
self.init_info = self.info
|
self.init_info = self.info
|
||||||
|
|
||||||
|
|
||||||
|
@attr.s
|
||||||
|
class GameStacks(NewStruct):
|
||||||
|
talon = attr.ib(default=None)
|
||||||
|
waste = attr.ib(default=None)
|
||||||
|
foundations = attr.ib(factory=list)
|
||||||
|
rows = attr.ib(factory=list) # for getHightlightPilesStacks()
|
||||||
|
reserves = attr.ib(factory=list)
|
||||||
|
internals = attr.ib(factory=list)
|
||||||
|
|
||||||
|
def to_tuples(self):
|
||||||
|
self.foundations = tuple(self.foundations)
|
||||||
|
self.rows = tuple(self.rows)
|
||||||
|
self.reserves = tuple(self.reserves)
|
||||||
|
self.internals = tuple(self.internals)
|
||||||
|
|
||||||
|
|
||||||
|
@attr.s
|
||||||
|
class GameDrag(NewStruct):
|
||||||
|
event = attr.ib(default=None)
|
||||||
|
timer = attr.ib(default=None)
|
||||||
|
start_x = attr.ib(default=0)
|
||||||
|
start_y = attr.ib(default=0)
|
||||||
|
index = attr.ib(default=-1)
|
||||||
|
stack = attr.ib(default=None)
|
||||||
|
shade_stack = attr.ib(default=None)
|
||||||
|
shade_img = attr.ib(default=None)
|
||||||
|
cards = attr.ib(factory=list)
|
||||||
|
canshade_stacks = attr.ib(factory=list)
|
||||||
|
noshade_stacks = attr.ib(factory=list)
|
||||||
|
|
||||||
|
|
||||||
class Game(object):
|
class Game(object):
|
||||||
# for self.gstats.updated
|
# for self.gstats.updated
|
||||||
U_PLAY = 0
|
U_PLAY = 0
|
||||||
|
@ -358,14 +390,7 @@ class Game(object):
|
||||||
self.stackdesc_list = []
|
self.stackdesc_list = []
|
||||||
self.demo_logo = None
|
self.demo_logo = None
|
||||||
self.pause_logo = None
|
self.pause_logo = None
|
||||||
self.s = Struct( # stacks
|
self.s = GameStacks()
|
||||||
talon=None,
|
|
||||||
waste=None,
|
|
||||||
foundations=[],
|
|
||||||
rows=[],
|
|
||||||
reserves=[],
|
|
||||||
internals=[],
|
|
||||||
)
|
|
||||||
self.sg = StackGroups()
|
self.sg = StackGroups()
|
||||||
self.regions = StackRegions()
|
self.regions = StackRegions()
|
||||||
self.init_size = (0, 0)
|
self.init_size = (0, 0)
|
||||||
|
@ -389,11 +414,8 @@ class Game(object):
|
||||||
self.createSnGroups()
|
self.createSnGroups()
|
||||||
# convert stackgroups to tuples (speed)
|
# convert stackgroups to tuples (speed)
|
||||||
self.allstacks = tuple(self.allstacks)
|
self.allstacks = tuple(self.allstacks)
|
||||||
self.s.foundations = tuple(self.s.foundations)
|
|
||||||
self.s.rows = tuple(self.s.rows)
|
|
||||||
self.s.reserves = tuple(self.s.reserves)
|
|
||||||
self.s.internals = tuple(self.s.internals)
|
|
||||||
self.sg.to_tuples()
|
self.sg.to_tuples()
|
||||||
|
self.s.to_tuples()
|
||||||
# init the stack view
|
# init the stack view
|
||||||
for stack in self.allstacks:
|
for stack in self.allstacks:
|
||||||
stack.prepareStack()
|
stack.prepareStack()
|
||||||
|
@ -528,20 +550,7 @@ class Game(object):
|
||||||
self.top = app.top
|
self.top = app.top
|
||||||
self.canvas = app.canvas
|
self.canvas = app.canvas
|
||||||
self.filename = ""
|
self.filename = ""
|
||||||
self.drag = Struct(
|
self.drag = GameDrag()
|
||||||
event=None, # current event
|
|
||||||
timer=None, # current event timer
|
|
||||||
start_x=0, # X coord of initial drag event
|
|
||||||
start_y=0, # Y coord of initial drag event
|
|
||||||
stack=None, #
|
|
||||||
cards=[], #
|
|
||||||
index=-1, #
|
|
||||||
shadows=[], # list of canvas images
|
|
||||||
shade_stack=None, # stack currently shaded
|
|
||||||
shade_img=None, # canvas image
|
|
||||||
canshade_stacks=[], # list of stacks already tested
|
|
||||||
noshade_stacks=[], # for this drag
|
|
||||||
)
|
|
||||||
if self.gstats.start_player is None:
|
if self.gstats.start_player is None:
|
||||||
self.gstats.start_player = self.app.opt.player
|
self.gstats.start_player = self.app.opt.player
|
||||||
# optional MfxCanvasText items
|
# optional MfxCanvasText items
|
||||||
|
|
|
@ -1168,7 +1168,7 @@ class LMenu(ActionView, LBase):
|
||||||
class MyActionPrev(ActionPrevious, LBase):
|
class MyActionPrev(ActionPrevious, LBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
kw['app_icon'] = 'data/images/misc/pysol01.png'
|
kw['app_icon'] = 'data/images/icons/48x48/pysol.png'
|
||||||
kw['with_previous'] = prev
|
kw['with_previous'] = prev
|
||||||
kw['size_hint'] = (.01, 1)
|
kw['size_hint'] = (.01, 1)
|
||||||
self.ap = MyActionPrev(**kw)
|
self.ap = MyActionPrev(**kw)
|
||||||
|
|
|
@ -25,9 +25,9 @@ import os
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
import configobj
|
||||||
|
|
||||||
import pysollib.settings
|
import pysollib.settings
|
||||||
from pysollib.configobj import configobj, validate
|
|
||||||
from pysollib.mfxutil import print_err
|
from pysollib.mfxutil import print_err
|
||||||
from pysollib.mygettext import _
|
from pysollib.mygettext import _
|
||||||
from pysollib.pysoltk import TOOLBAR_BUTTONS, TOOLKIT
|
from pysollib.pysoltk import TOOLBAR_BUTTONS, TOOLKIT
|
||||||
|
@ -35,6 +35,8 @@ from pysollib.resource import CSI
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
import validate
|
||||||
|
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
# * Options
|
# * Options
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
|
|
|
@ -35,6 +35,7 @@ except ImportError:
|
||||||
"https://pypi.python.org/pypi/random2 using pip or similar.")
|
"https://pypi.python.org/pypi/random2 using pip or similar.")
|
||||||
|
|
||||||
from pysol_cards.random_base import RandomBase # noqa: I100
|
from pysol_cards.random_base import RandomBase # noqa: I100
|
||||||
|
from pysol_cards.random import match_ms_deal_prefix # noqa: I100
|
||||||
|
|
||||||
|
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
|
@ -55,9 +56,6 @@ class BasicRandom(RandomBase):
|
||||||
ORIGIN_SELECTED = 3 # manually entered
|
ORIGIN_SELECTED = 3 # manually entered
|
||||||
ORIGIN_NEXT_GAME = 4 # "Next game number"
|
ORIGIN_NEXT_GAME = 4 # "Next game number"
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.seed_as_string = None
|
|
||||||
|
|
||||||
def getSeedStr(self):
|
def getSeedStr(self):
|
||||||
return str(self.initial_seed)
|
return str(self.initial_seed)
|
||||||
|
|
||||||
|
@ -85,15 +83,6 @@ class BasicRandom(RandomBase):
|
||||||
t = (t ^ (t >> 24)) % (self.MAX_SEED + 1)
|
t = (t ^ (t >> 24)) % (self.MAX_SEED + 1)
|
||||||
return t
|
return t
|
||||||
|
|
||||||
def setSeedAsStr(self, new_s):
|
|
||||||
self.seed_as_string = new_s
|
|
||||||
|
|
||||||
def getSeedAsStr(self):
|
|
||||||
if self.seed_as_string:
|
|
||||||
return self.seed_as_string
|
|
||||||
else:
|
|
||||||
return str(self)
|
|
||||||
|
|
||||||
|
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
# * Mersenne Twister random number generator
|
# * Mersenne Twister random number generator
|
||||||
|
@ -233,7 +222,9 @@ class LCRandom31(MFXRandom):
|
||||||
return "ms" + str(self.initial_seed)
|
return "ms" + str(self.initial_seed)
|
||||||
|
|
||||||
def str(self, seed):
|
def str(self, seed):
|
||||||
return "%05d" % int(seed) if not _match_ms(seed) else seed
|
if match_ms_deal_prefix(seed) is None:
|
||||||
|
return "%05d" % int(seed)
|
||||||
|
return seed
|
||||||
|
|
||||||
def setSeed(self, seed):
|
def setSeed(self, seed):
|
||||||
seed = int(seed)
|
seed = int(seed)
|
||||||
|
@ -275,18 +266,14 @@ PysolRandom = MTRandom
|
||||||
# * PySol support code
|
# * PySol support code
|
||||||
# ************************************************************************
|
# ************************************************************************
|
||||||
|
|
||||||
def _match_ms(s):
|
|
||||||
"""match an ms based seed string."""
|
|
||||||
return re.match(r"ms([0-9]+)\n?\Z", str(s))
|
|
||||||
|
|
||||||
|
|
||||||
# construct Random from seed string
|
# construct Random from seed string
|
||||||
def constructRandom(s):
|
def constructRandom(s):
|
||||||
if s == 'Custom':
|
if s == 'Custom':
|
||||||
return CustomRandom()
|
return CustomRandom()
|
||||||
m = _match_ms(s)
|
m = match_ms_deal_prefix(s)
|
||||||
if m:
|
if m is not None:
|
||||||
seed = int(m.group(1))
|
seed = m
|
||||||
if 0 <= seed <= LCRandom31.MAX_SEED:
|
if 0 <= seed <= LCRandom31.MAX_SEED:
|
||||||
ret = LCRandom31(seed)
|
ret = LCRandom31(seed)
|
||||||
ret.setSeedAsStr(s)
|
ret.setSeedAsStr(s)
|
||||||
|
@ -307,9 +294,9 @@ def constructRandom(s):
|
||||||
def random__str2long(s):
|
def random__str2long(s):
|
||||||
if s == 'Custom':
|
if s == 'Custom':
|
||||||
return CUSTOM_BIT | MS_LONG_BIT
|
return CUSTOM_BIT | MS_LONG_BIT
|
||||||
m = _match_ms(s)
|
m = match_ms_deal_prefix(s)
|
||||||
if m:
|
if m is not None:
|
||||||
return (int(m.group(1)) | MS_LONG_BIT)
|
return (m | MS_LONG_BIT)
|
||||||
else:
|
else:
|
||||||
return int(s)
|
return int(s)
|
||||||
|
|
||||||
|
|
19
pysollib/struct_new.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#! /usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim:fenc=utf-8
|
||||||
|
#
|
||||||
|
# Copyright © 2019 Shlomi Fish <shlomif@cpan.org>
|
||||||
|
#
|
||||||
|
# Distributed under terms of the MIT license.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class NewStruct(object):
|
||||||
|
"""docstring for NewStruct"""
|
||||||
|
def copy(self):
|
||||||
|
ret = self.__class__()
|
||||||
|
ret.__dict__.update(self.__dict__)
|
||||||
|
return ret
|
|
@ -1,725 +0,0 @@
|
||||||
#! /usr/bin/env python3
|
|
||||||
# -*- coding: iso-8859-1 -*-
|
|
||||||
# Originally written by Barry Warsaw <barry@zope.com>
|
|
||||||
#
|
|
||||||
# Minimally patched to make it even more xgettext compatible
|
|
||||||
# by Peter Funk <pf@artcom-gmbh.de>
|
|
||||||
#
|
|
||||||
# 2002-11-22 Jürgen Hermann <jh@web.de>
|
|
||||||
# Added checks that _() only contains string literals, and
|
|
||||||
# command line args are resolved to module lists, i.e. you
|
|
||||||
# can now pass a filename, a module or package name, or a
|
|
||||||
# directory (including globbing chars, important for Win32).
|
|
||||||
# Made docstring fit in 80 chars wide displays using pydoc.
|
|
||||||
#
|
|
||||||
# 2007-05-11 Scomoroh <scomoroh@gmail.com>
|
|
||||||
# Added very simple support for ngettext
|
|
||||||
#
|
|
||||||
|
|
||||||
import functools
|
|
||||||
import getopt
|
|
||||||
import glob
|
|
||||||
import imp
|
|
||||||
import operator
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
import token
|
|
||||||
import tokenize
|
|
||||||
|
|
||||||
from six import PY2, print_
|
|
||||||
# for selftesting
|
|
||||||
try:
|
|
||||||
import fintl
|
|
||||||
_ = fintl.gettext
|
|
||||||
except ImportError:
|
|
||||||
def _(s):
|
|
||||||
return s
|
|
||||||
|
|
||||||
__doc__ = _("""pygettext -- Python equivalent of xgettext(1)
|
|
||||||
|
|
||||||
Many systems (Solaris, Linux, Gnu) provide extensive tools that ease the
|
|
||||||
internationalization of C programs. Most of these tools are independent of
|
|
||||||
the programming language and can be used from within Python programs.
|
|
||||||
Martin von Loewis' work[1] helps considerably in this regard.
|
|
||||||
|
|
||||||
There's one problem though; xgettext is the program that scans source code
|
|
||||||
looking for message strings, but it groks only C (or C++). Python
|
|
||||||
introduces a few wrinkles, such as dual quoting characters, triple quoted
|
|
||||||
strings, and raw strings. xgettext understands none of this.
|
|
||||||
|
|
||||||
Enter pygettext, which uses Python's standard tokenize module to scan
|
|
||||||
Python source code, generating .pot files identical to what GNU xgettext[2]
|
|
||||||
generates for C and C++ code. From there, the standard GNU tools can be
|
|
||||||
used.
|
|
||||||
|
|
||||||
A word about marking Python strings as candidates for translation. GNU
|
|
||||||
xgettext recognizes the following keywords: gettext, dgettext, dcgettext,
|
|
||||||
and gettext_noop. But those can be a lot of text to include all over your
|
|
||||||
code. C and C++ have a trick: they use the C preprocessor. Most
|
|
||||||
internationalized C source includes a #define for gettext() to _() so that
|
|
||||||
what has to be written in the source is much less. Thus these are both
|
|
||||||
translatable strings:
|
|
||||||
|
|
||||||
gettext("Translatable String")
|
|
||||||
_("Translatable String")
|
|
||||||
|
|
||||||
Python of course has no preprocessor so this doesn't work so well. Thus,
|
|
||||||
pygettext searches only for _() by default, but see the -k/--keyword flag
|
|
||||||
below for how to augment this.
|
|
||||||
|
|
||||||
[1] http://www.python.org/workshops/1997-10/proceedings/loewis.html
|
|
||||||
[2] http://www.gnu.org/software/gettext/gettext.html
|
|
||||||
|
|
||||||
NOTE: pygettext attempts to be option and feature compatible with GNU
|
|
||||||
xgettext where ever possible. However some options are still missing or are
|
|
||||||
not fully implemented. Also, xgettext's use of command line switches with
|
|
||||||
option arguments is broken, and in these cases, pygettext just defines
|
|
||||||
additional switches.
|
|
||||||
|
|
||||||
Usage: pygettext [options] inputfile ...
|
|
||||||
|
|
||||||
Options:
|
|
||||||
|
|
||||||
-a
|
|
||||||
--extract-all
|
|
||||||
Extract all strings.
|
|
||||||
|
|
||||||
-d name
|
|
||||||
--default-domain=name
|
|
||||||
Rename the default output file from messages.pot to name.pot.
|
|
||||||
|
|
||||||
-E
|
|
||||||
--escape
|
|
||||||
Replace non-ASCII characters with octal escape sequences.
|
|
||||||
|
|
||||||
-D
|
|
||||||
--docstrings
|
|
||||||
Extract module, class, method, and function docstrings. These do
|
|
||||||
not need to be wrapped in _() markers, and in fact cannot be for
|
|
||||||
Python to consider them docstrings. (See also the -X option).
|
|
||||||
|
|
||||||
-h
|
|
||||||
--help
|
|
||||||
Print this help message and exit.
|
|
||||||
|
|
||||||
-k word
|
|
||||||
--keyword=word
|
|
||||||
Keywords to look for in addition to the default set, which are:
|
|
||||||
%(DEFAULTKEYWORDS)s
|
|
||||||
|
|
||||||
You can have multiple -k flags on the command line.
|
|
||||||
|
|
||||||
-K
|
|
||||||
--no-default-keywords
|
|
||||||
Disable the default set of keywords (see above). Any keywords
|
|
||||||
explicitly added with the -k/--keyword option are still recognized.
|
|
||||||
|
|
||||||
--no-location
|
|
||||||
Do not write filename/lineno location comments.
|
|
||||||
|
|
||||||
-n
|
|
||||||
--add-location
|
|
||||||
Write filename/lineno location comments indicating where each
|
|
||||||
extracted string is found in the source. These lines appear before
|
|
||||||
each msgid. The style of comments is controlled by the -S/--style
|
|
||||||
option. This is the default.
|
|
||||||
|
|
||||||
-o filename
|
|
||||||
--output=filename
|
|
||||||
Rename the default output file from messages.pot to filename. If
|
|
||||||
filename is `-' then the output is sent to standard out.
|
|
||||||
|
|
||||||
-p dir
|
|
||||||
--output-dir=dir
|
|
||||||
Output files will be placed in directory dir.
|
|
||||||
|
|
||||||
-S stylename
|
|
||||||
--style stylename
|
|
||||||
Specify which style to use for location comments. Two styles are
|
|
||||||
supported:
|
|
||||||
|
|
||||||
Solaris # File: filename, line: line-number
|
|
||||||
GNU #: filename:line
|
|
||||||
|
|
||||||
The style name is case insensitive. GNU style is the default.
|
|
||||||
|
|
||||||
-v
|
|
||||||
--verbose
|
|
||||||
Print the names of the files being processed.
|
|
||||||
|
|
||||||
-V
|
|
||||||
--version
|
|
||||||
Print the version of pygettext and exit.
|
|
||||||
|
|
||||||
-w columns
|
|
||||||
--width=columns
|
|
||||||
Set width of output to columns.
|
|
||||||
|
|
||||||
-x filename
|
|
||||||
--exclude-file=filename
|
|
||||||
Specify a file that contains a list of strings that are not be
|
|
||||||
extracted from the input files. Each string to be excluded must
|
|
||||||
appear on a line by itself in the file.
|
|
||||||
|
|
||||||
-X filename
|
|
||||||
--no-docstrings=filename
|
|
||||||
Specify a file that contains a list of files (one per line) that
|
|
||||||
should not have their docstrings extracted. This is only useful in
|
|
||||||
conjunction with the -D option above.
|
|
||||||
|
|
||||||
If `inputfile' is -, standard input is read.
|
|
||||||
""")
|
|
||||||
|
|
||||||
__version__ = '1.6con'
|
|
||||||
|
|
||||||
default_keywords = ['_']
|
|
||||||
DEFAULTKEYWORDS = ', '.join(default_keywords)
|
|
||||||
default_ngettext_keywords = ['ngettext']
|
|
||||||
|
|
||||||
EMPTYSTRING = ''
|
|
||||||
|
|
||||||
# The normal pot-file header. msgmerge and Emacs's po-mode work better if it's
|
|
||||||
# there.
|
|
||||||
pot_header = _('''\
|
|
||||||
# SOME DESCRIPTIVE TITLE.
|
|
||||||
# Copyright (C) YEAR ORGANIZATION
|
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: PACKAGE VERSION\\n"
|
|
||||||
"POT-Creation-Date: %(time)s\\n"
|
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
|
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
|
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\\n"
|
|
||||||
"MIME-Version: 1.0\\n"
|
|
||||||
"Content-Type: text/plain; charset=CHARSET\\n"
|
|
||||||
"Content-Transfer-Encoding: ENCODING\\n"
|
|
||||||
"Generated-By: pygettext.py %(version)s\\n"
|
|
||||||
|
|
||||||
''')
|
|
||||||
|
|
||||||
|
|
||||||
def usage(code, msg=''):
|
|
||||||
print_(__doc__ % globals(), file=sys.stderr)
|
|
||||||
if msg:
|
|
||||||
print_(msg, file=sys.stderr)
|
|
||||||
sys.exit(code)
|
|
||||||
|
|
||||||
|
|
||||||
escapes = []
|
|
||||||
|
|
||||||
|
|
||||||
def make_escapes(pass_iso8859):
|
|
||||||
global escapes
|
|
||||||
if pass_iso8859:
|
|
||||||
# Allow iso-8859 characters to pass through so that e.g. 'msgid
|
|
||||||
# "Höhe"' would result not result in 'msgid "H\366he"'. Otherwise we
|
|
||||||
# escape any character outside the 32..126 range.
|
|
||||||
mod = 128
|
|
||||||
else:
|
|
||||||
mod = 256
|
|
||||||
for i in range(256):
|
|
||||||
if 32 <= (i % mod) <= 126:
|
|
||||||
escapes.append(chr(i))
|
|
||||||
else:
|
|
||||||
escapes.append("\\%03o" % i)
|
|
||||||
escapes[ord('\\')] = '\\\\'
|
|
||||||
escapes[ord('\t')] = '\\t'
|
|
||||||
escapes[ord('\r')] = '\\r'
|
|
||||||
escapes[ord('\n')] = '\\n'
|
|
||||||
escapes[ord('\"')] = '\\"'
|
|
||||||
|
|
||||||
|
|
||||||
def escape(s):
|
|
||||||
global escapes
|
|
||||||
s = list(s)
|
|
||||||
for i in range(len(s)):
|
|
||||||
s[i] = escapes[ord(s[i])]
|
|
||||||
return EMPTYSTRING.join(s)
|
|
||||||
|
|
||||||
|
|
||||||
def safe_eval(s):
|
|
||||||
# unwrap quotes, safely
|
|
||||||
return eval(s, {'__builtins__': {}}, {})
|
|
||||||
|
|
||||||
|
|
||||||
def normalize(s):
|
|
||||||
# This converts the various Python string types into a format that is
|
|
||||||
# appropriate for .po files, namely much closer to C style.
|
|
||||||
lines = s.split('\n')
|
|
||||||
if len(lines) == 1:
|
|
||||||
s = '"' + escape(s) + '"'
|
|
||||||
else:
|
|
||||||
if not lines[-1]:
|
|
||||||
del lines[-1]
|
|
||||||
lines[-1] = lines[-1] + '\n'
|
|
||||||
for i in range(len(lines)):
|
|
||||||
lines[i] = escape(lines[i])
|
|
||||||
lineterm = '\\n"\n"'
|
|
||||||
s = '""\n"' + lineterm.join(lines) + '"'
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
|
||||||
def containsAny(str, set):
|
|
||||||
"""Check whether 'str' contains ANY of the chars in 'set'"""
|
|
||||||
return 1 in [c in str for c in set]
|
|
||||||
|
|
||||||
|
|
||||||
def _visit_pyfiles(list, dirname, names):
|
|
||||||
"""Helper for getFilesForName()."""
|
|
||||||
# get extension for python source files
|
|
||||||
if '_py_ext' not in globals():
|
|
||||||
global _py_ext
|
|
||||||
_py_ext = [triple[0] for triple in imp.get_suffixes()
|
|
||||||
if triple[2] == imp.PY_SOURCE][0]
|
|
||||||
|
|
||||||
# don't recurse into CVS directories
|
|
||||||
if 'CVS' in names:
|
|
||||||
names.remove('CVS')
|
|
||||||
|
|
||||||
# add all *.py files to list
|
|
||||||
list.extend(
|
|
||||||
[os.path.join(dirname, file) for file in names
|
|
||||||
if os.path.splitext(file)[1] == _py_ext]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_modpkg_path(dotted_name, pathlist=None):
|
|
||||||
"""Get the filesystem path for a module or a package.
|
|
||||||
|
|
||||||
Return the file system path to a file for a module, and to a directory for
|
|
||||||
a package. Return None if the name is not found, or is a builtin or
|
|
||||||
extension module.
|
|
||||||
"""
|
|
||||||
# split off top-most name
|
|
||||||
parts = dotted_name.split('.', 1)
|
|
||||||
|
|
||||||
if len(parts) > 1:
|
|
||||||
# we have a dotted path, import top-level package
|
|
||||||
try:
|
|
||||||
file, pathname, description = imp.find_module(parts[0], pathlist)
|
|
||||||
if file:
|
|
||||||
file.close()
|
|
||||||
except ImportError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# check if it's indeed a package
|
|
||||||
if description[2] == imp.PKG_DIRECTORY:
|
|
||||||
# recursively handle the remaining name parts
|
|
||||||
pathname = _get_modpkg_path(parts[1], [pathname])
|
|
||||||
else:
|
|
||||||
pathname = None
|
|
||||||
else:
|
|
||||||
# plain name
|
|
||||||
try:
|
|
||||||
file, pathname, description = imp.find_module(
|
|
||||||
dotted_name, pathlist)
|
|
||||||
if file:
|
|
||||||
file.close()
|
|
||||||
if description[2] not in [imp.PY_SOURCE, imp.PKG_DIRECTORY]:
|
|
||||||
pathname = None
|
|
||||||
except ImportError:
|
|
||||||
pathname = None
|
|
||||||
|
|
||||||
return pathname
|
|
||||||
|
|
||||||
|
|
||||||
def getFilesForName(name):
|
|
||||||
"""Get a list of module files for a filename, a module or package name,
|
|
||||||
or a directory.
|
|
||||||
"""
|
|
||||||
if not os.path.exists(name):
|
|
||||||
# check for glob chars
|
|
||||||
if containsAny(name, "*?[]"):
|
|
||||||
files = glob.glob(name)
|
|
||||||
list = []
|
|
||||||
for file in files:
|
|
||||||
list.extend(getFilesForName(file))
|
|
||||||
return list
|
|
||||||
|
|
||||||
# try to find module or package
|
|
||||||
name = _get_modpkg_path(name)
|
|
||||||
if not name:
|
|
||||||
return []
|
|
||||||
|
|
||||||
if os.path.isdir(name):
|
|
||||||
# find all python files in directory
|
|
||||||
list = []
|
|
||||||
os.path.walk(name, _visit_pyfiles, list)
|
|
||||||
return list
|
|
||||||
elif os.path.exists(name):
|
|
||||||
# a single file
|
|
||||||
return [name]
|
|
||||||
|
|
||||||
return []
|
|
||||||
|
|
||||||
|
|
||||||
class TokenEater:
|
|
||||||
def __init__(self, options):
|
|
||||||
self.__options = options
|
|
||||||
self.__messages = {}
|
|
||||||
self.__state = self.__waiting
|
|
||||||
self.__data = []
|
|
||||||
self.__lineno = -1
|
|
||||||
self.__freshmodule = 1
|
|
||||||
self.__curfile = None
|
|
||||||
self.__ngettext = False
|
|
||||||
|
|
||||||
def __call__(self, ttype, tstring, stup, etup, line):
|
|
||||||
# dispatch
|
|
||||||
# import token
|
|
||||||
# print >> sys.stderr, 'ttype:', token.tok_name[ttype], \
|
|
||||||
# 'tstring:', tstring
|
|
||||||
self.__state(ttype, tstring, stup[0])
|
|
||||||
|
|
||||||
def __waiting(self, ttype, tstring, lineno):
|
|
||||||
opts = self.__options
|
|
||||||
# Do docstring extractions, if enabled
|
|
||||||
if opts.docstrings and not opts.nodocstrings.get(self.__curfile):
|
|
||||||
# module docstring?
|
|
||||||
if self.__freshmodule:
|
|
||||||
if ttype == tokenize.STRING:
|
|
||||||
self.__addentry(safe_eval(tstring), lineno, isdocstring=1)
|
|
||||||
self.__freshmodule = 0
|
|
||||||
elif ttype not in (tokenize.COMMENT, tokenize.NL):
|
|
||||||
self.__freshmodule = 0
|
|
||||||
return
|
|
||||||
# class docstring?
|
|
||||||
if ttype == tokenize.NAME and tstring in ('class', 'def'):
|
|
||||||
self.__state = self.__suiteseen
|
|
||||||
return
|
|
||||||
if ttype == tokenize.NAME and tstring in opts.keywords:
|
|
||||||
self.__state = self.__keywordseen
|
|
||||||
self.__ngettext = tstring in opts.ngettext_keywords
|
|
||||||
|
|
||||||
def __suiteseen(self, ttype, tstring, lineno):
|
|
||||||
# ignore anything until we see the colon
|
|
||||||
if ttype == tokenize.OP and tstring == ':':
|
|
||||||
self.__state = self.__suitedocstring
|
|
||||||
|
|
||||||
def __suitedocstring(self, ttype, tstring, lineno):
|
|
||||||
# ignore any intervening noise
|
|
||||||
if ttype == tokenize.STRING:
|
|
||||||
self.__addentry(safe_eval(tstring), lineno, isdocstring=1)
|
|
||||||
self.__state = self.__waiting
|
|
||||||
elif ttype not in (tokenize.NEWLINE, tokenize.INDENT,
|
|
||||||
tokenize.COMMENT):
|
|
||||||
# there was no class docstring
|
|
||||||
self.__state = self.__waiting
|
|
||||||
|
|
||||||
def __keywordseen(self, ttype, tstring, lineno):
|
|
||||||
if ttype == tokenize.OP and tstring == '(':
|
|
||||||
self.__data = []
|
|
||||||
self.__lineno = lineno
|
|
||||||
self.__state = self.__openseen
|
|
||||||
else:
|
|
||||||
self.__state = self.__waiting
|
|
||||||
|
|
||||||
def __openseen(self, ttype, tstring, lineno):
|
|
||||||
if ttype == tokenize.OP and tstring == ')':
|
|
||||||
# We've seen the last of the translatable strings. Record the
|
|
||||||
# line number of the first line of the strings and update the list
|
|
||||||
# of messages seen. Reset state for the next batch. If there
|
|
||||||
# were no strings inside _(), then just ignore this entry.
|
|
||||||
if self.__data:
|
|
||||||
if self.__ngettext:
|
|
||||||
data = []
|
|
||||||
msg = []
|
|
||||||
for s in self.__data:
|
|
||||||
if s is not None:
|
|
||||||
msg.append(s)
|
|
||||||
else:
|
|
||||||
data.append(EMPTYSTRING.join(msg))
|
|
||||||
msg = []
|
|
||||||
if len(data) == 2 and data[0] and data[1]:
|
|
||||||
self.__addentry(tuple(data))
|
|
||||||
elif self.__options.verbose:
|
|
||||||
print_(_(
|
|
||||||
'*** %(file)s:%(lineno)s: incorrect '
|
|
||||||
'ngettext format'
|
|
||||||
) % {
|
|
||||||
'file': self.__curfile,
|
|
||||||
'lineno': self.__lineno}, file=sys.stderr)
|
|
||||||
else:
|
|
||||||
self.__addentry(EMPTYSTRING.join(self.__data))
|
|
||||||
self.__state = self.__waiting
|
|
||||||
elif ttype == tokenize.STRING:
|
|
||||||
self.__data.append(safe_eval(tstring))
|
|
||||||
elif ttype not in [tokenize.COMMENT, token.INDENT, token.DEDENT,
|
|
||||||
token.NEWLINE, tokenize.NL]:
|
|
||||||
if self.__ngettext and ttype == tokenize.OP and tstring == ',':
|
|
||||||
self.__data.append(None)
|
|
||||||
elif self.__ngettext: # and ttype == tokenize.NUMBER:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
# warn if we see anything else than STRING or whitespace
|
|
||||||
if self.__options.verbose:
|
|
||||||
print_(_(
|
|
||||||
'*** %(file)s:%(lineno)s: Seen unexpected '
|
|
||||||
'token "%(token)s"'
|
|
||||||
) % {
|
|
||||||
'token': tstring,
|
|
||||||
'file': self.__curfile,
|
|
||||||
'lineno': self.__lineno
|
|
||||||
}, file=sys.stderr)
|
|
||||||
self.__state = self.__waiting
|
|
||||||
|
|
||||||
def __addentry(self, msg, lineno=None, isdocstring=0):
|
|
||||||
if lineno is None:
|
|
||||||
lineno = self.__lineno
|
|
||||||
if msg not in self.__options.toexclude:
|
|
||||||
entry = (self.__curfile, lineno)
|
|
||||||
self.__messages.setdefault(msg, {})[entry] = isdocstring
|
|
||||||
|
|
||||||
def set_filename(self, filename):
|
|
||||||
self.__curfile = filename
|
|
||||||
self.__freshmodule = 1
|
|
||||||
|
|
||||||
def write(self, fp):
|
|
||||||
options = self.__options
|
|
||||||
timestamp = time.ctime(time.time())
|
|
||||||
# The time stamp in the header doesn't have the same format as that
|
|
||||||
# generated by xgettext...
|
|
||||||
print_(pot_header % {'time': timestamp, 'version': __version__},
|
|
||||||
file=fp)
|
|
||||||
# Sort the entries. First sort each particular entry's keys, then
|
|
||||||
# sort all the entries by their first item.
|
|
||||||
reverse = {}
|
|
||||||
for k, v in self.__messages.items():
|
|
||||||
keys = list(v.keys())
|
|
||||||
keys.sort()
|
|
||||||
reverse.setdefault(tuple(keys), []).append((k, v))
|
|
||||||
rkeys = list(reverse.keys())
|
|
||||||
rkeys.sort()
|
|
||||||
for rkey in rkeys:
|
|
||||||
rentries = reverse[rkey]
|
|
||||||
rentries.sort()
|
|
||||||
for k, v in rentries:
|
|
||||||
isdocstring = 0
|
|
||||||
# If the entry was gleaned out of a docstring, then add a
|
|
||||||
# comment stating so. This is to aid translators who may wish
|
|
||||||
# to skip translating some unimportant docstrings.
|
|
||||||
if functools.reduce(operator.__add__, v.values()):
|
|
||||||
isdocstring = 1
|
|
||||||
# k is the message string, v is a dictionary-set of (filename,
|
|
||||||
# lineno) tuples. We want to sort the entries in v first by
|
|
||||||
# file name and then by line number.
|
|
||||||
v = list(v.keys())
|
|
||||||
v.sort()
|
|
||||||
if not options.writelocations:
|
|
||||||
pass
|
|
||||||
# location comments are different b/w Solaris and GNU:
|
|
||||||
elif options.locationstyle == options.SOLARIS:
|
|
||||||
for filename, lineno in v:
|
|
||||||
d = {'filename': filename, 'lineno': lineno}
|
|
||||||
print_(_('# File: %(filename)s, line: %(lineno)d') % d,
|
|
||||||
file=fp)
|
|
||||||
elif options.locationstyle == options.GNU:
|
|
||||||
# fit as many locations on one line, as long as the
|
|
||||||
# resulting line length doesn't exceeds 'options.width'
|
|
||||||
locline = '#:'
|
|
||||||
for filename, lineno in v:
|
|
||||||
d = {'filename': filename, 'lineno': lineno}
|
|
||||||
s = _(' %(filename)s:%(lineno)d') % d
|
|
||||||
if len(locline) + len(s) <= options.width:
|
|
||||||
locline = locline + s
|
|
||||||
else:
|
|
||||||
print_(locline, file=fp)
|
|
||||||
locline = "#:" + s
|
|
||||||
if len(locline) > 2:
|
|
||||||
print_(locline, file=fp)
|
|
||||||
if isdocstring:
|
|
||||||
print_('#, docstring', file=fp)
|
|
||||||
if isinstance(k, str):
|
|
||||||
print_('msgid', normalize(k), file=fp)
|
|
||||||
print_('msgstr ""\n', file=fp)
|
|
||||||
else:
|
|
||||||
# ngettext
|
|
||||||
assert isinstance(k, tuple)
|
|
||||||
assert len(k) == 2
|
|
||||||
print_('msgid', normalize(k[0]), file=fp)
|
|
||||||
print_('msgid_plural', normalize(k[1]), file=fp)
|
|
||||||
print_('msgstr[0] ""', file=fp)
|
|
||||||
print_('msgstr[1] ""\n', file=fp)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
global default_keywords
|
|
||||||
try:
|
|
||||||
opts, args = getopt.getopt(
|
|
||||||
sys.argv[1:],
|
|
||||||
'ad:DEhk:Kno:p:S:Vvw:x:X:',
|
|
||||||
['extract-all', 'default-domain=', 'escape', 'help',
|
|
||||||
'keyword=', 'no-default-keywords', 'ngettext-keyword=',
|
|
||||||
'add-location', 'no-location', 'output=', 'output-dir=',
|
|
||||||
'style=', 'verbose', 'version', 'width=', 'exclude-file=',
|
|
||||||
'docstrings', 'no-docstrings',
|
|
||||||
])
|
|
||||||
except getopt.error as msg:
|
|
||||||
usage(1, msg)
|
|
||||||
|
|
||||||
# for holding option values
|
|
||||||
class Options:
|
|
||||||
# constants
|
|
||||||
GNU = 1
|
|
||||||
SOLARIS = 2
|
|
||||||
# defaults
|
|
||||||
extractall = 0 # FIXME: currently this option has no effect at all.
|
|
||||||
escape = 0
|
|
||||||
keywords = []
|
|
||||||
ngettext_keywords = []
|
|
||||||
outpath = ''
|
|
||||||
outfile = 'messages.pot'
|
|
||||||
writelocations = 1
|
|
||||||
locationstyle = GNU
|
|
||||||
verbose = 0
|
|
||||||
width = 78
|
|
||||||
excludefilename = ''
|
|
||||||
docstrings = 0
|
|
||||||
nodocstrings = {}
|
|
||||||
|
|
||||||
options = Options()
|
|
||||||
locations = {'gnu': options.GNU,
|
|
||||||
'solaris': options.SOLARIS,
|
|
||||||
}
|
|
||||||
|
|
||||||
# parse options
|
|
||||||
for opt, arg in opts:
|
|
||||||
if opt in ('-h', '--help'):
|
|
||||||
usage(0)
|
|
||||||
elif opt in ('-a', '--extract-all'):
|
|
||||||
options.extractall = 1
|
|
||||||
elif opt in ('-d', '--default-domain'):
|
|
||||||
options.outfile = arg + '.pot'
|
|
||||||
elif opt in ('-E', '--escape'):
|
|
||||||
options.escape = 1
|
|
||||||
elif opt in ('-D', '--docstrings'):
|
|
||||||
options.docstrings = 1
|
|
||||||
elif opt in ('-k', '--keyword'):
|
|
||||||
options.keywords.append(arg)
|
|
||||||
elif opt in ('--ngettext-keyword'):
|
|
||||||
options.ngettext_keywords.append(arg)
|
|
||||||
elif opt in ('-K', '--no-default-keywords'):
|
|
||||||
default_keywords = []
|
|
||||||
elif opt in ('-n', '--add-location'):
|
|
||||||
options.writelocations = 1
|
|
||||||
elif opt in ('--no-location',):
|
|
||||||
options.writelocations = 0
|
|
||||||
elif opt in ('-S', '--style'):
|
|
||||||
options.locationstyle = locations.get(arg.lower())
|
|
||||||
if options.locationstyle is None:
|
|
||||||
usage(1, _('Invalid value for --style: %s') % arg)
|
|
||||||
elif opt in ('-o', '--output'):
|
|
||||||
options.outfile = arg
|
|
||||||
elif opt in ('-p', '--output-dir'):
|
|
||||||
options.outpath = arg
|
|
||||||
elif opt in ('-v', '--verbose'):
|
|
||||||
options.verbose = 1
|
|
||||||
elif opt in ('-V', '--version'):
|
|
||||||
print(_('pygettext.py (xgettext for Python) %s') % __version__)
|
|
||||||
sys.exit(0)
|
|
||||||
elif opt in ('-w', '--width'):
|
|
||||||
try:
|
|
||||||
options.width = int(arg)
|
|
||||||
except ValueError:
|
|
||||||
usage(1, _('--width argument must be an integer: %s') % arg)
|
|
||||||
elif opt in ('-x', '--exclude-file'):
|
|
||||||
options.excludefilename = arg
|
|
||||||
elif opt in ('-X', '--no-docstrings'):
|
|
||||||
fp = open(arg)
|
|
||||||
try:
|
|
||||||
while 1:
|
|
||||||
line = fp.readline()
|
|
||||||
if not line:
|
|
||||||
break
|
|
||||||
options.nodocstrings[line[:-1]] = 1
|
|
||||||
finally:
|
|
||||||
fp.close()
|
|
||||||
|
|
||||||
# calculate escapes
|
|
||||||
make_escapes(options.escape)
|
|
||||||
|
|
||||||
# calculate all keywords
|
|
||||||
options.keywords.extend(default_keywords)
|
|
||||||
|
|
||||||
options.ngettext_keywords.extend(default_ngettext_keywords)
|
|
||||||
options.keywords.extend(options.ngettext_keywords)
|
|
||||||
|
|
||||||
# initialize list of strings to exclude
|
|
||||||
if options.excludefilename:
|
|
||||||
try:
|
|
||||||
fp = open(options.excludefilename)
|
|
||||||
options.toexclude = fp.readlines()
|
|
||||||
fp.close()
|
|
||||||
except IOError:
|
|
||||||
print_(_("Can't read --exclude-file: %s") %
|
|
||||||
options.excludefilename, file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
else:
|
|
||||||
options.toexclude = []
|
|
||||||
|
|
||||||
# resolve args to module lists
|
|
||||||
expanded = []
|
|
||||||
for arg in args:
|
|
||||||
if arg == '-':
|
|
||||||
expanded.append(arg)
|
|
||||||
else:
|
|
||||||
expanded.extend(getFilesForName(arg))
|
|
||||||
args = expanded
|
|
||||||
|
|
||||||
# slurp through all the files
|
|
||||||
eater = TokenEater(options)
|
|
||||||
for filename in args:
|
|
||||||
if filename == '-':
|
|
||||||
if options.verbose:
|
|
||||||
print(_('Reading standard input'))
|
|
||||||
fp = sys.stdin
|
|
||||||
closep = 0
|
|
||||||
else:
|
|
||||||
if options.verbose:
|
|
||||||
print(_('Working on %s') % filename)
|
|
||||||
fp = open(filename, 'rb')
|
|
||||||
closep = 1
|
|
||||||
try:
|
|
||||||
eater.set_filename(filename)
|
|
||||||
try:
|
|
||||||
if PY2:
|
|
||||||
for token_info in tokenize.generate_tokens(fp.readline):
|
|
||||||
eater(*token_info)
|
|
||||||
else:
|
|
||||||
for token_info in tokenize.tokenize(fp.readline):
|
|
||||||
eater(*token_info)
|
|
||||||
except tokenize.TokenError as e:
|
|
||||||
print_('%s: %s, line %d, column %d' % (
|
|
||||||
e[0], filename, e[1][0], e[1][1]), file=sys.stderr)
|
|
||||||
except tokenize.StopTokenizing:
|
|
||||||
pass
|
|
||||||
finally:
|
|
||||||
if closep:
|
|
||||||
fp.close()
|
|
||||||
|
|
||||||
# write the output
|
|
||||||
if options.outfile == '-':
|
|
||||||
fp = sys.stdout
|
|
||||||
closep = 0
|
|
||||||
else:
|
|
||||||
if options.outpath:
|
|
||||||
options.outfile = os.path.join(options.outpath, options.outfile)
|
|
||||||
fp = open(options.outfile, 'w')
|
|
||||||
closep = 1
|
|
||||||
try:
|
|
||||||
eater.write(fp)
|
|
||||||
finally:
|
|
||||||
if closep:
|
|
||||||
fp.close()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
# some more test strings
|
|
||||||
_('a unicode string')
|
|
||||||
# this one creates a warning
|
|
||||||
_('*** Seen unexpected token "%(token)s"') % {'token': 'test'}
|
|
||||||
_('more' 'than' 'one' 'string')
|
|
19
setup.py
|
@ -2,11 +2,13 @@
|
||||||
# -*- mode: python; -*-
|
# -*- mode: python; -*-
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from distutils.core import setup
|
|
||||||
from glob import glob
|
from glob import glob
|
||||||
|
|
||||||
from pysollib.settings import PACKAGE_URL
|
from pysollib.settings import PACKAGE_URL
|
||||||
from pysollib.settings import VERSION
|
from pysollib.settings import VERSION
|
||||||
|
|
||||||
|
from setuptools import setup
|
||||||
|
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
import py2exe # noqa: F401
|
import py2exe # noqa: F401
|
||||||
|
|
||||||
|
@ -43,9 +45,9 @@ for d in ddirs:
|
||||||
|
|
||||||
if os.name == 'posix':
|
if os.name == 'posix':
|
||||||
data_files.append(('share/pixmaps', ['data/pysol.xbm', 'data/pysol.xpm']))
|
data_files.append(('share/pixmaps', ['data/pysol.xbm', 'data/pysol.xpm']))
|
||||||
data_files.append(('share/icons',
|
for size in os.listdir('data/images/icons'):
|
||||||
['data/images/misc/pysol01.png',
|
data_files.append(('share/icons/hicolor/%s/apps' % size,
|
||||||
'data/images/misc/pysol02.png', ]))
|
['data/images/icons/%s/pysol.png' % size]))
|
||||||
for mofile in glob('locale/*/*/*.mo'):
|
for mofile in glob('locale/*/*/*.mo'):
|
||||||
data_files.append(('share/' + os.path.dirname(mofile), [mofile]))
|
data_files.append(('share/' + os.path.dirname(mofile), [mofile]))
|
||||||
data_files.append((data_dir, ['data/pysolfc.glade']))
|
data_files.append((data_dir, ['data/pysolfc.glade']))
|
||||||
|
@ -69,11 +71,18 @@ kw = {
|
||||||
'author': 'Skomoroh',
|
'author': 'Skomoroh',
|
||||||
'author_email': 'skomoroh@gmail.com',
|
'author_email': 'skomoroh@gmail.com',
|
||||||
'description': 'a Python solitaire game collection',
|
'description': 'a Python solitaire game collection',
|
||||||
|
'install_requires': [
|
||||||
|
'attrs',
|
||||||
|
'configobj',
|
||||||
|
'pycotap',
|
||||||
|
'pysol_cards',
|
||||||
|
'random2',
|
||||||
|
'six',
|
||||||
|
],
|
||||||
'long_description': long_description,
|
'long_description': long_description,
|
||||||
'license': 'GPL',
|
'license': 'GPL',
|
||||||
'scripts': ['pysol.py'],
|
'scripts': ['pysol.py'],
|
||||||
'packages': ['pysollib',
|
'packages': ['pysollib',
|
||||||
'pysollib.configobj',
|
|
||||||
'pysollib.macosx',
|
'pysollib.macosx',
|
||||||
'pysollib.winsystems',
|
'pysollib.winsystems',
|
||||||
'pysollib.tk',
|
'pysollib.tk',
|
||||||
|
|