Added a setting where the exported excel files should be stored.

Added a option to send the exported excel as mail attachment.
This commit is contained in:
2017-11-23 22:02:40 +01:00
parent 854fd38740
commit bb5081a78b
3 changed files with 79 additions and 31 deletions

View File

@@ -273,6 +273,7 @@ KYU_RANKS = (
DAN_ALLOW_DROP_DOWN = True DAN_ALLOW_DROP_DOWN = True
MIN_HANCHANS_FOR_LADDER = 5 MIN_HANCHANS_FOR_LADDER = 5
RANKING_EXPORT_PATH = path.join(PROJECT_PATH, 'backup', 'mahjong_ranking')
try: try:
from .local_settings import * # Ignore PyLintBear (W0401, W0614) from .local_settings import * # Ignore PyLintBear (W0401, W0614)

View File

@@ -1,11 +1,15 @@
"""Export Mahjong Rankings as excel files.""" """Export Mahjong Rankings as excel files."""
import openpyxl import os
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 datetime import date, time, datetime
import openpyxl
from django.conf import settings
from django.core.management.base import BaseCommand
from django.utils import timezone from django.utils import timezone
from django.utils.dateparse import parse_date
from django.core.mail import EmailMessage
from mahjong_ranking.models import SeasonRanking, KyuDanRanking from mahjong_ranking.models import SeasonRanking, KyuDanRanking
THIN_BORDER = openpyxl.styles.Side(style='thin', color="d3d7cf") THIN_BORDER = openpyxl.styles.Side(style='thin', color="d3d7cf")
@@ -38,7 +42,19 @@ DATE_STYLE.font = DEFAULT_STYLE.font
DATE_STYLE.border = DEFAULT_STYLE.border DATE_STYLE.border = DEFAULT_STYLE.border
DATE_STYLE.number_format = 'dd.mm.yyyy' DATE_STYLE.number_format = 'dd.mm.yyyy'
MAIL_BODY = """
Hallo! Ich bin's dein Server.
Ich habe gerade die Mahjong Rankings als Excel exportiert und dachte mir das
ich sie dir am besten gleich schicke.
Bitte versuche nicht auf diese E-Mail zu antworten.
Ich bin nur ein dummes Programm.
mit lieben Grüßen
Der Kasu Server
"""
def geneate_excel(): def geneate_excel():
"""Generate an excel .xlsx spreadsheet from json data of the kyu/dan """Generate an excel .xlsx spreadsheet from json data of the kyu/dan
rankings. rankings.
@@ -108,7 +124,7 @@ def export_season_rankings(workbook, until):
'style': 'content', 'style': 'content',
'width': 25}, 'width': 25},
{'col': 'C', 'title': '⌀ Platz', 'attr': 'avg_placement', {'col': 'C', 'title': '⌀ Platz', 'attr': 'avg_placement',
'style': 'int', 'width': 8}, 'style': 'float', 'width': 8},
{'col': 'D', 'title': '⌀ Punkte', 'attr': 'avg_score', {'col': 'D', 'title': '⌀ Punkte', 'attr': 'avg_score',
'style': 'float', 'width': 12}, 'style': 'float', 'width': 12},
{'col': 'E', 'title': 'Hanchans', 'attr': 'hanchan_count', {'col': 'E', 'title': 'Hanchans', 'attr': 'hanchan_count',
@@ -156,17 +172,43 @@ def export_kyu_dan_rankings(workbook, until):
class Command(BaseCommand): class Command(BaseCommand):
"""Exports the SeasonRankings""" """Exports the SeasonRankings"""
filename = str()
until = datetime
def add_arguments(self, parser): def add_arguments(self, parser):
parser.add_argument('--until', nargs='?', type=parse_date) parser.add_argument(
'--until', nargs='?', type=parse_date,
default=date.today(), metavar='YYYY-MM-DD',
help='Calculate and export rankings until the given date.')
parser.add_argument(
'--mail', nargs='*', type=str, metavar='user@example.com',
help='Send the spreadsheet via eMail to the given recipient.')
def handle(self, *args, **options): def handle(self, *args, **options):
"""Exports the current ladder ranking in a spreadsheet. """Exports the current ladder ranking in a spreadsheet.
This is useful as a backup in form of a hardcopy.""" This is useful as a backup in form of a hardcopy."""
until = timezone.make_aware( self.until = timezone.make_aware(datetime.combine(
datetime.combine(options['until'] or date.today(), options['until'], time(23, 59, 59)
time(23, 59, 59))) ))
self.filename = os.path.join(
settings.RANKING_EXPORT_PATH,
'mahjong_rankings_{:%Y-%m-%d}.xlsx'.format(self.until)
)
workbook = geneate_excel() workbook = geneate_excel()
export_season_rankings(workbook, until=until) export_season_rankings(workbook, until=self.until)
export_kyu_dan_rankings(workbook, until=until) export_kyu_dan_rankings(workbook, until=self.until)
workbook.save('mahjong_rankings_{:%Y-%m-%d}.xlsx'.format(until)) os.makedirs(settings.RANKING_EXPORT_PATH, exist_ok=True)
workbook.save(self.filename)
if options['mail']:
self.send_mail(options['mail'])
def send_mail(self, recipients):
mail = EmailMessage(
subject='Mahjong Rankings vom {:%d.%m.%Y}'.format(self.until),
body=MAIL_BODY,
from_email=settings.DEFAULT_FROM_EMAIL,
to=recipients)
mail.attach_file(self.filename)
mail.send()

View File

@@ -4,7 +4,9 @@
# werden dürfen. # werden dürfen.
from __future__ import division from __future__ import division
from datetime import datetime, time from datetime import datetime, time
from django.conf import settings from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
@@ -463,8 +465,12 @@ class KyuDanRanking(models.Model):
datetime.combine(self.legacy_date, time(0, 0, 0))) datetime.combine(self.legacy_date, time(0, 0, 0)))
else: else:
since = None since = None
else: elif self.last_hanchan_date:
since = self.last_hanchan_date or self.legacy_date since = self.last_hanchan_date
elif self.legacy_date:
since = timezone.make_aware(
datetime.combine(self.legacy_date, time(0, 0, 0))
)
LOGGER.info( LOGGER.info(
"recalculating Kyu/Dan points for %(user)s since %(since)s...", "recalculating Kyu/Dan points for %(user)s since %(since)s...",
{'user': self.user, 'since': str(since)} {'user': self.user, 'since': str(since)}
@@ -474,13 +480,11 @@ class KyuDanRanking(models.Model):
if until: if until:
valid_hanchans = valid_hanchans.filter(start__lte=until) valid_hanchans = valid_hanchans.filter(start__lte=until)
""" TODO: Hanchan Punkte nur neu berechnen wenn sie nach hachan_start
lagen. Es müssen aber alle durch die Schleife rennen, damit die Punkte
richtig gezählt werden."""
self.hanchan_count += valid_hanchans.count() self.hanchan_count += valid_hanchans.count()
for hanchan in valid_hanchans: for hanchan in valid_hanchans:
hanchan.get_playerdata(self.user) hanchan.get_playerdata(self.user)
if since and since < hanchan.start: if since and hanchan.start < since:
print(hanchan, "<", since, "no recalc")
self.dan_points += hanchan.dan_points or 0 self.dan_points += hanchan.dan_points or 0
self.kyu_points += hanchan.kyu_points or 0 self.kyu_points += hanchan.kyu_points or 0
self.update_rank() self.update_rank()
@@ -564,6 +568,7 @@ class KyuDanRanking(models.Model):
hanchan.kyu_points -= (self.kyu_points + hanchan.kyu_points) hanchan.kyu_points -= (self.kyu_points + hanchan.kyu_points)
self.kyu_points += hanchan.kyu_points self.kyu_points += hanchan.kyu_points
# TODO: Merkwürdige Methode die zwar funktioniert aber nicht sehr # TODO: Merkwürdige Methode die zwar funktioniert aber nicht sehr
# aussagekräfig ist. Überarbeiten? # aussagekräfig ist. Überarbeiten?
def update_rank(self): def update_rank(self):