From 8e80cec14a4834ae2012959d61e473a2b430c6c4 Mon Sep 17 00:00:00 2001 From: emkael Date: Fri, 25 Nov 2016 16:33:01 +0100 Subject: bootstrap file and environment for pyinstaller --- .gitignore | 2 ++ ql/__main__.py | 16 ---------------- quick_lineup.py | 16 ++++++++++++++++ quick_lineup.spec | 28 ++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 16 deletions(-) delete mode 100644 ql/__main__.py create mode 100644 quick_lineup.py create mode 100644 quick_lineup.spec diff --git a/.gitignore b/.gitignore index b20b868..0903698 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ *.pyc __pycache__ /venv* +build +dist diff --git a/ql/__main__.py b/ql/__main__.py deleted file mode 100644 index e79056d..0000000 --- a/ql/__main__.py +++ /dev/null @@ -1,16 +0,0 @@ -import sys -from .console import Console - - -if len(sys.argv) < 3 or len(sys.argv) > 4: - print('Give correct parameters: round, segment and (optionally) table') - sys.exit(1) - -round = int(sys.argv[1]) -segment = int(sys.argv[2]) -if len(sys.argv) == 4: - table = int(sys.argv[3]) -else: - table = None - -Console(round, segment, table).run() diff --git a/quick_lineup.py b/quick_lineup.py new file mode 100644 index 0000000..c63aad1 --- /dev/null +++ b/quick_lineup.py @@ -0,0 +1,16 @@ +import sys +from ql.console import Console + + +if len(sys.argv) < 3 or len(sys.argv) > 4: + print('Give correct parameters: round, segment and (optionally) table') + sys.exit(1) + +round = int(sys.argv[1]) +segment = int(sys.argv[2]) +if len(sys.argv) == 4: + table = int(sys.argv[3]) +else: + table = None + +Console(round, segment, table).run() diff --git a/quick_lineup.spec b/quick_lineup.spec new file mode 100644 index 0000000..f96a842 --- /dev/null +++ b/quick_lineup.spec @@ -0,0 +1,28 @@ +# -*- mode: python -*- + +block_cipher = None + + +a = Analysis(['quick_lineup.py'], + pathex=['Z:\\teamy-quick-lineup'], + binaries=None, + datas=None, + hiddenimports=['html.parser','http.cookies'], + hookspath=[], + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher) +pyz = PYZ(a.pure, a.zipped_data, + cipher=block_cipher) +exe = EXE(pyz, + a.scripts, + a.binaries, + a.zipfiles, + a.datas, + name='quick_lineup', + debug=False, + strip=False, + upx=True, + console=True ) -- cgit v1.2.3 From 62dca92a29e746d7dabf04ad7bea6931fa0e7ad7 Mon Sep 17 00:00:00 2001 From: emkael Date: Fri, 25 Nov 2016 18:00:29 +0100 Subject: Replacing cached_property module from Django to a standalone one --- ql/lineup.py | 2 +- requirements-linux.txt | 1 + requirements-windows.txt | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ql/lineup.py b/ql/lineup.py index b0d5847..5a2ce82 100644 --- a/ql/lineup.py +++ b/ql/lineup.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from django.utils.functional import cached_property +from cached_property import cached_property from .orm.models import Segment, Team, Player diff --git a/requirements-linux.txt b/requirements-linux.txt index 02377be..967d473 100644 --- a/requirements-linux.txt +++ b/requirements-linux.txt @@ -1,3 +1,4 @@ django mysqlclient readline +cached_property diff --git a/requirements-windows.txt b/requirements-windows.txt index 48b847f..3e5e893 100644 --- a/requirements-windows.txt +++ b/requirements-windows.txt @@ -1,2 +1,3 @@ django pyreadline +cached_property -- cgit v1.2.3 From ee4f35076b048162c87059d08425b6280776ec09 Mon Sep 17 00:00:00 2001 From: Michal Zimniewicz Date: Sun, 9 Oct 2016 12:27:23 +0200 Subject: adjust super() calls to python2 --- ql/lineup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ql/lineup.py b/ql/lineup.py index 5a2ce82..cca69e5 100644 --- a/ql/lineup.py +++ b/ql/lineup.py @@ -38,7 +38,7 @@ class TeamInSegment(object): class HomeTeamInSegment(TeamInSegment): def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) + super(HomeTeamInSegment, self).__init__(*args, **kwargs) def get_paired_players_fields(self): return [ @@ -56,7 +56,7 @@ class HomeTeamInSegment(TeamInSegment): class AwayTeamInSegment(TeamInSegment): def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) + super(AwayTeamInSegment, self).__init__(*args, **kwargs) def get_paired_players_fields(self): return [ -- cgit v1.2.3 From ae7738768ead06aea4b93826c8e164da53eeba51 Mon Sep 17 00:00:00 2001 From: emkael Date: Mon, 10 Oct 2016 13:19:25 +0200 Subject: alias raw_input() as input() for python2 --- ql/console.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ql/console.py b/ql/console.py index 0c741ca..dede956 100755 --- a/ql/console.py +++ b/ql/console.py @@ -22,6 +22,12 @@ class Console(object): lineup = self.get_lineup(table) print(lineup.info) print() + # Python 2.x workaround + global input + try: + input = raw_input + except NameError: + pass # if raw_input is not defined (Python 3.x), ignore it for team in lineup.teams: Completer.install_new_completer(team.player_names) for pair in team.pairs: -- cgit v1.2.3 From 07401a984b58d6d1328264efca45df39e1951ea2 Mon Sep 17 00:00:00 2001 From: emkael Date: Mon, 10 Oct 2016 16:12:23 +0200 Subject: encoding readline completer options in case Python2 unicode strings are involved --- ql/completer.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ql/completer.py b/ql/completer.py index a9b7d8d..89920d4 100644 --- a/ql/completer.py +++ b/ql/completer.py @@ -1,4 +1,5 @@ import readline +import sys class Completer(object): @@ -10,8 +11,15 @@ class Completer(object): readline.set_completer_delims('') # allow options with whitespace readline.parse_and_bind('tab: complete') + def __encode_completion_string(self, s): + try: + return s.encode(sys.stdin.encoding) if isinstance(s, unicode) else s + except NameError: # Python 3.x does not have a 'unicode' type + pass + return s + def __init__(self, options): - self.options = options + self.options = [self.__encode_completion_string(s) for s in options] def complete(self, text, state): text = text.lower() -- cgit v1.2.3 From 918046228044145d77e96d8b739430c65da6f23f Mon Sep 17 00:00:00 2001 From: emkael Date: Mon, 10 Oct 2016 16:15:33 +0200 Subject: fun fact: `print()` in Python2 prints out "()" --- ql/console.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/console.py b/ql/console.py index dede956..6751b83 100755 --- a/ql/console.py +++ b/ql/console.py @@ -21,7 +21,7 @@ class Console(object): def process_table(self, table): lineup = self.get_lineup(table) print(lineup.info) - print() + print('') # Python 2.x workaround global input try: -- cgit v1.2.3 From cadaee4d114be675bdc6a235cb918dd1bae35ed3 Mon Sep 17 00:00:00 2001 From: emkael Date: Mon, 10 Oct 2016 16:17:39 +0200 Subject: clearing up Pair info for printing purposes --- ql/lineup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/lineup.py b/ql/lineup.py index cca69e5..872fc7f 100644 --- a/ql/lineup.py +++ b/ql/lineup.py @@ -95,7 +95,7 @@ class Pair(object): return 'Team: %s - %s - %s' % ( self.team.name, self.label, - [ p.info if p is not None else '' for p in self.players ] + ', '.join([ p.info if p is not None else '' for p in self.players ]) ) def set_player(self, name): -- cgit v1.2.3 From f825baa2b0774b4bfe4749060a32df72b0db90fd Mon Sep 17 00:00:00 2001 From: emkael Date: Fri, 25 Nov 2016 21:10:47 +0100 Subject: All the necessary hidden imports. Fixes #4 --- quick_lineup.spec | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/quick_lineup.spec b/quick_lineup.spec index f96a842..624a236 100644 --- a/quick_lineup.spec +++ b/quick_lineup.spec @@ -7,7 +7,12 @@ a = Analysis(['quick_lineup.py'], pathex=['Z:\\teamy-quick-lineup'], binaries=None, datas=None, - hiddenimports=['html.parser','http.cookies'], + hiddenimports=['html.parser','http.cookies', + 'django.template.defaulttags','django.template.loader_tags', + 'django.middleware.common', + 'ql.settings', + 'mysql.connector.django', 'mysql.connector.django.base', + 'mysql.connector.django.compiler'], hookspath=[], runtime_hooks=[], excludes=[], -- cgit v1.2.3 From 2ee4dc85051ebb01a88ffd49ed513b65ccc651c8 Mon Sep 17 00:00:00 2001 From: emkael Date: Fri, 25 Nov 2016 21:35:10 +0100 Subject: Handling Ctrl+C/Ctrl+D a bit more gracefully --- ql/console.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ql/console.py b/ql/console.py index 6751b83..f797da7 100755 --- a/ql/console.py +++ b/ql/console.py @@ -16,7 +16,10 @@ class Console(object): def run(self): for table in self.tables: - self.process_table(table) + try: + self.process_table(table) + except (EOFError, KeyboardInterrupt): + break def process_table(self, table): lineup = self.get_lineup(table) -- cgit v1.2.3 From 28ce1bfbff9a738b33409df0e575985f6f1b3ce2 Mon Sep 17 00:00:00 2001 From: emkael Date: Fri, 25 Nov 2016 22:03:49 +0100 Subject: Global error handling --- quick_lineup.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/quick_lineup.py b/quick_lineup.py index c63aad1..237bc19 100644 --- a/quick_lineup.py +++ b/quick_lineup.py @@ -13,4 +13,7 @@ if len(sys.argv) == 4: else: table = None -Console(round, segment, table).run() +try: + Console(round, segment, table).run() +except: + print('ERROR: %s' % sys.exc_info()[1]) -- cgit v1.2.3 From 542e7cfbf6c543a234309feb42d087779a7cdc12 Mon Sep 17 00:00:00 2001 From: emkael Date: Fri, 25 Nov 2016 22:09:22 +0100 Subject: Configuration from external JSON file. Fixes #2 --- .gitignore | 1 + ql/settings.py | 37 +++++++++++++++++++++++++++++-------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 0903698..38e438d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ __pycache__ /venv* build dist +config.json diff --git a/ql/settings.py b/ql/settings.py index a975f14..df68ae3 100755 --- a/ql/settings.py +++ b/ql/settings.py @@ -1,12 +1,33 @@ +import json, sys + +def _fetch_settings(config_path, constant_config, default_config): + try: + config = constant_config.copy() + config.update(json.load(open(config_path))) + return config + except FileNotFoundError: + with open(config_path, 'w') as new_config: + json.dump(default_config, new_config) + print('Config file created, fill it up!') + sys.exit() + except ValueError: + print('Config file invalid, fix it!') + sys.exit(1) + DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.mysql', - 'HOST': '127.0.0.1', - 'PORT': '3306', - 'USER': 'your-username', - 'PASSWORD': 'your-password', - 'NAME': 'your-database-name', - } + 'default': _fetch_settings( + 'config.json', + { + 'ENGINE': 'mysql.connector.django' + }, + { + 'HOST': 'localhost', + 'PORT': '3306', + 'USER': 'root', + 'PASSWORD': '', + 'NAME': 'belongs_to_us' + } + ) } INSTALLED_APPS = ( -- cgit v1.2.3 From 6d5ae86eac297cbc62d56c0479582e50207b05bd Mon Sep 17 00:00:00 2001 From: emkael Date: Fri, 25 Nov 2016 22:26:19 +0100 Subject: More verbose config-related messages --- ql/settings.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ql/settings.py b/ql/settings.py index df68ae3..7d8af00 100755 --- a/ql/settings.py +++ b/ql/settings.py @@ -1,4 +1,4 @@ -import json, sys +import json, os, sys def _fetch_settings(config_path, constant_config, default_config): try: @@ -8,10 +8,16 @@ def _fetch_settings(config_path, constant_config, default_config): except FileNotFoundError: with open(config_path, 'w') as new_config: json.dump(default_config, new_config) - print('Config file created, fill it up!') + print( + 'Config file %s created, fill it up!' % + os.path.realpath(config_path) + ) sys.exit() except ValueError: - print('Config file invalid, fix it!') + print( + 'Config file %s invalid, fix it!' % + os.path.realpath(config_path) + ) sys.exit(1) DATABASES = { -- cgit v1.2.3 From 33159ab536d15adab09da18e0012889023887ec9 Mon Sep 17 00:00:00 2001 From: emkael Date: Fri, 25 Nov 2016 22:27:05 +0100 Subject: Wrapping app entry point in method --- quick_lineup.py | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/quick_lineup.py b/quick_lineup.py index 237bc19..965922e 100644 --- a/quick_lineup.py +++ b/quick_lineup.py @@ -2,18 +2,23 @@ import sys from ql.console import Console -if len(sys.argv) < 3 or len(sys.argv) > 4: - print('Give correct parameters: round, segment and (optionally) table') - sys.exit(1) +def main(): + if len(sys.argv) < 3 or len(sys.argv) > 4: + print('Give correct parameters: round, segment and (optionally) table') + sys.exit(1) -round = int(sys.argv[1]) -segment = int(sys.argv[2]) -if len(sys.argv) == 4: - table = int(sys.argv[3]) -else: - table = None + round = int(sys.argv[1]) + segment = int(sys.argv[2]) + if len(sys.argv) == 4: + table = int(sys.argv[3]) + else: + table = None -try: - Console(round, segment, table).run() -except: - print('ERROR: %s' % sys.exc_info()[1]) + try: + Console(round, segment, table).run() + except: + print('ERROR: %s' % sys.exc_info()[1]) + + +if __name__ == '__main__': + main() -- cgit v1.2.3 From 69449fe53c8bfc226bf48a9680d29c77e99dcf3c Mon Sep 17 00:00:00 2001 From: emkael Date: Fri, 25 Nov 2016 22:33:15 +0100 Subject: Parsing command-line arguments with argparse --- quick_lineup.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/quick_lineup.py b/quick_lineup.py index 965922e..7da857f 100644 --- a/quick_lineup.py +++ b/quick_lineup.py @@ -1,21 +1,24 @@ +import argparse import sys from ql.console import Console def main(): - if len(sys.argv) < 3 or len(sys.argv) > 4: - print('Give correct parameters: round, segment and (optionally) table') - sys.exit(1) + parser = argparse.ArgumentParser( + description='Interface for line-up management in JFR Teamy') - round = int(sys.argv[1]) - segment = int(sys.argv[2]) - if len(sys.argv) == 4: - table = int(sys.argv[3]) - else: - table = None + parser.add_argument('round', metavar='ROUND', type=int, + help='round number') + parser.add_argument('segment', metavar='SEGMENT', type=int, + help='segment number') + parser.add_argument('table', metavar='TABLE', type=int, + nargs='?', default=None, + help='table to start from') + + arguments = parser.parse_args() try: - Console(round, segment, table).run() + Console(arguments.round, arguments.segment, arguments.table).run() except: print('ERROR: %s' % sys.exc_info()[1]) -- cgit v1.2.3 From 5d2b426fc97f3d9b3cb91019e512aa8cf4c4f468 Mon Sep 17 00:00:00 2001 From: emkael Date: Sat, 26 Nov 2016 00:41:42 +0100 Subject: Program icon --- quick_lineup.spec | 3 ++- res/ql.ico | Bin 0 -> 4286 bytes 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 res/ql.ico diff --git a/quick_lineup.spec b/quick_lineup.spec index 624a236..dc66d2e 100644 --- a/quick_lineup.spec +++ b/quick_lineup.spec @@ -30,4 +30,5 @@ exe = EXE(pyz, debug=False, strip=False, upx=True, - console=True ) + console=True, + icon='res\\ql.ico') diff --git a/res/ql.ico b/res/ql.ico new file mode 100644 index 0000000..f90e031 Binary files /dev/null and b/res/ql.ico differ -- cgit v1.2.3 From d9af0bcf382ab73ddc7ff720f08dc3e8c77a4195 Mon Sep 17 00:00:00 2001 From: emkael Date: Sat, 26 Nov 2016 01:15:15 +0100 Subject: Compiled binary. Fixes #3 --- .gitignore | 1 - dist/quick_lineup.exe | Bin 0 -> 8533894 bytes 2 files changed, 1 deletion(-) create mode 100644 dist/quick_lineup.exe diff --git a/.gitignore b/.gitignore index 38e438d..564b18b 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,4 @@ __pycache__ /venv* build -dist config.json diff --git a/dist/quick_lineup.exe b/dist/quick_lineup.exe new file mode 100644 index 0000000..bae93aa Binary files /dev/null and b/dist/quick_lineup.exe differ -- cgit v1.2.3 From f6870ca22e3dfc2582585704e70b3a2dd1283f3c Mon Sep 17 00:00:00 2001 From: emkael Date: Sat, 26 Nov 2016 01:22:30 +0100 Subject: README updated to reflect bootstrap script, not module architecture --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6b47751..dba7b4e 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,13 @@ For Linux, you can leave the default `engine` property, for Windows, you have to # Usage ``` -python -m ql [] +python quick_lineup.py [] ``` For instance, to process round 3, segment 2, starting from table 1 run: ``` -python -m ql 3 2 1 +python quick_lineup.py 3 2 1 ``` The script will iterate pair by pair in each match. It presents the currently assigned players and let you confirm them - pressing ENTER without any input - or change - providing player names (press TAB to autocomplete). -- cgit v1.2.3 From b4338fe7ba0690c3e7201d7965c29ada047ce74f Mon Sep 17 00:00:00 2001 From: emkael Date: Sat, 26 Nov 2016 01:22:30 +0100 Subject: README updated to reflect bootstrap script, not module architecture Closes #3 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6b47751..dba7b4e 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,13 @@ For Linux, you can leave the default `engine` property, for Windows, you have to # Usage ``` -python -m ql [] +python quick_lineup.py [] ``` For instance, to process round 3, segment 2, starting from table 1 run: ``` -python -m ql 3 2 1 +python quick_lineup.py 3 2 1 ``` The script will iterate pair by pair in each match. It presents the currently assigned players and let you confirm them - pressing ENTER without any input - or change - providing player names (press TAB to autocomplete). -- cgit v1.2.3 From fca5169ad79dbee8db6d31a7ab51a74525fda561 Mon Sep 17 00:00:00 2001 From: emkael Date: Sun, 26 Feb 2017 16:36:46 +0100 Subject: https://github.com/michzimny/teamy-quick-lineup/pull/9#pullrequestreview-23883015 --- ql/lineup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/lineup.py b/ql/lineup.py index 872fc7f..688825b 100644 --- a/ql/lineup.py +++ b/ql/lineup.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from cached_property import cached_property +from django.utils.functional import cached_property from .orm.models import Segment, Team, Player -- cgit v1.2.3