added new fields to KyuDanRanking that allow to pick up the calculation from the last state of the KyuDanRanking.

last_hanchan_date: it contains the start of the latest hanchan content for this players ranking.
wins_in_row: to save the currents wins in a row

Added option to calcuclate rankings until a given datetime.
This commit is contained in:
2017-11-19 16:14:59 +01:00
parent 53ff0f1adb
commit 0a45cf1fd8
7 changed files with 189 additions and 85 deletions

View File

@@ -1,12 +1,11 @@
"""Export Mahjong Rankings as excel files."""
from datetime import date
from operator import itemgetter
import openpyxl
from django.core.management.base import BaseCommand
from django.utils.dateparse import parse_date
from openpyxl.styles import Border
from datetime import date, time, datetime
from django.utils import timezone
from mahjong_ranking.models import SeasonRanking, KyuDanRanking
THIN_BORDER = openpyxl.styles.Side(style='thin', color="d3d7cf")
@@ -34,6 +33,11 @@ FLOAT_STYLE.font = DEFAULT_STYLE.font
FLOAT_STYLE.border = DEFAULT_STYLE.border
FLOAT_STYLE.number_format = '#,##0.00'
DATE_STYLE = openpyxl.styles.NamedStyle(name='date')
DATE_STYLE.font = DEFAULT_STYLE.font
DATE_STYLE.border = DEFAULT_STYLE.border
DATE_STYLE.number_format = 'dd.mm.yyyy'
def geneate_excel():
"""Generate an excel .xlsx spreadsheet from json data of the kyu/dan
@@ -45,8 +49,9 @@ def geneate_excel():
workbook.add_named_style(DEFAULT_STYLE)
workbook.add_named_style(INT_STYLE)
workbook.add_named_style(FLOAT_STYLE)
workbook.add_named_style(DATE_STYLE)
for sheet in workbook.worksheets:
print(sheet)
workbook.remove(sheet)
return workbook
@@ -55,6 +60,8 @@ def generate_sheet(workbook, title, columns_settings, json_data):
row = 1
ws = workbook.create_sheet()
ws.title = title
ws.syncHorizontal = True
ws.filterMode = True
# setup print orientation
ws.page_setup.orientation = ws.ORIENTATION_PORTRAIT
@@ -90,10 +97,10 @@ def generate_sheet(workbook, title, columns_settings, json_data):
ws.column_dimensions[settings['col']].width = settings['width']
def export_season_rankings(workbook):
json_data = sorted(SeasonRanking.objects.json_data(),
key=itemgetter('placement'))
title = "Mahjong Ladder - {}".format(date.today().year)
def export_season_rankings(workbook, until):
SeasonRanking.objects.update(until=until)
json_data = SeasonRanking.objects.json_data()
title = "Mahjong Ladder - {}".format(until.year)
columns_settings = (
{'col': 'A', 'title': 'Rang', 'attr': 'placement', 'style': 'int',
'width': 8},
@@ -111,7 +118,6 @@ def export_season_rankings(workbook):
{'col': 'G', 'title': 'Gewonnen', 'attr': 'won_hanchans',
'style': 'int', 'width': 10},
)
generate_sheet(
workbook=workbook,
title=title,
@@ -119,7 +125,8 @@ def export_season_rankings(workbook):
json_data=json_data)
def export_kyu_dan_rankings(workbook):
def export_kyu_dan_rankings(workbook, until):
KyuDanRanking.objects.update(until=until)
json_data = KyuDanRanking.objects.json_data()
title = "Kyū & Dan Rankings"
columns_settings = (
@@ -136,7 +143,9 @@ def export_kyu_dan_rankings(workbook):
{'col': 'F', 'title': 'Gut', 'attr': 'good_hanchans',
'style': 'int', 'width': 5},
{'col': 'G', 'title': 'Gewonnen', 'attr': 'won_hanchans',
'style': 'int', 'width': 10},
'style': 'int', 'width': 8},
{'col': 'H', 'title': 'letzte Hanchan', 'attr': 'last_hanchan_date',
'style': 'date', 'width': 16},
)
generate_sheet(
workbook=workbook,
@@ -148,11 +157,16 @@ def export_kyu_dan_rankings(workbook):
class Command(BaseCommand):
"""Exports the SeasonRankings"""
def add_arguments(self, parser):
parser.add_argument('--until', nargs='?', type=parse_date)
def handle(self, *args, **options):
"""Exports the current ladder ranking in a spreadsheet.
This is useful as a backup in form of a hardcopy."""
until = timezone.make_aware(
datetime.combine(options['until'] or date.today(),
time(23, 59, 59)))
workbook = geneate_excel()
export_season_rankings(workbook)
export_kyu_dan_rankings(workbook)
workbook.save('sample.x')
workbook.save('mahjong_rankings_{}.xlsx'.format(str(date.today())))
export_season_rankings(workbook, until=until)
export_kyu_dan_rankings(workbook, until=until)
workbook.save('mahjong_rankings_{:%Y-%m-%d}.xlsx'.format(until))

View File

@@ -5,27 +5,29 @@ Recalculate Mahjong Rankings...
"""
from django.core.management.base import BaseCommand
from mahjong_ranking import LOGGER
from datetime import date, datetime, time
from mahjong_ranking import models
from django.utils.dateparse import parse_date
from django.utils import timezone
class Command(BaseCommand):
""" Recalculate all Kyu/Dan Rankings """
help = "Recalculate all Kyu/Dan Rankings"
def add_arguments(self, parser):
parser.add_argument('--since', nargs='?', type=parse_date)
parser.add_argument('--until', nargs='?', type=parse_date)
parser.add_argument('--forcerecalc', action='store_true')
def handle(self, *args, **options):
old_attr = {'dan': None, 'dan_points': None,
'kyu': None, 'kyu_points': None, 'won_hanchans': None,
'good_hanchans': None, 'hanchan_count': None}
for ranking in models.KyuDanRanking.objects.all():
old_attr = {attr: getattr(ranking, attr) for attr in old_attr.keys()}
ranking.recalculate()
for attr, old_value in old_attr.items():
if getattr(ranking, attr) != old_value:
LOGGER.warning(
"%(user)s recalc shows differences in %(attr)s! old: %(old)d, new: %(new)d",
{'user': ranking.user, 'attr': attr,
'old': old_value, 'new': getattr(ranking, attr)}
)
since = options.get('since', None)
until = options.get('until', None)
force_recalc = options.get('forecerecalc', False)
if isinstance(since, date):
since = datetime.combine(since, time(0, 0, 0))
since = timezone.make_aware(since)
if isinstance(until, date):
until = datetime.combine(until, time(23, 59, 59))
until = timezone.make_aware(until)
models.KyuDanRanking.objects.update(since=since, until=until, force_recalc=force_recalc)