Initial commit
This commit is contained in:
60
templates/base.html
Normal file
60
templates/base.html
Normal file
@@ -0,0 +1,60 @@
|
||||
{% load static %}
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" dir="ltr">
|
||||
<head>
|
||||
<!-- meta tags -->
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<meta name="Author" content="Martin Bley" />
|
||||
<meta name="Description" content="Tippspiel" />
|
||||
<meta name="Copyright" content="Martin Bley, 2014-2015" />
|
||||
<meta name="Robots" content="robots" />
|
||||
<meta name="Generator" content="Django" />
|
||||
<meta name="Keywords" content="Tippspiel Bundesliga" />
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- Bootstrap -->
|
||||
<link href="{{ STATIC_URL }}css/bootstrap.min.css" rel="stylesheet">
|
||||
|
||||
<!-- Bootstrap-Theme -->
|
||||
<link href="{{ STATIC_URL }}css/bootstrap-theme.min.css" rel="stylesheet">
|
||||
|
||||
<!-- Bootstrap-Theme -->
|
||||
<link href="{{ STATIC_URL }}css/tippy-bootstrap.css" rel="stylesheet">
|
||||
|
||||
<!-- Unterstützung für Media Queries und HTML5-Elemente im Internet Explorer über HTML5 shim und Respond.js -->
|
||||
<!-- ACHTUNG: Respond.js funktioniert nicht, wenn du die Seite über file:// aufrufst -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- jQuery (wird für Bootstrap JavaScript-Plugins benötigt) -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
|
||||
<!-- Binde alle kompilierten Plugins zusammen ein (wie hier unten) oder such dir einzelne Dateien nach Bedarf aus -->
|
||||
<script src="{{ STATIC_URL }}js/bootstrap.min.js"></script>
|
||||
|
||||
{% block nav %}{% endblock %}
|
||||
|
||||
<div class="jumbotron">
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
{% block body %}{% endblock %}
|
||||
</div>
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-7">
|
||||
<p>© Martin Bley, 2014-2015 | Dank an <a href="http://openligadb.de">OpenLigaDB</a> für
|
||||
die Bereitstellung der Spielergebnisse.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
||||
|
||||
72
templates/blogindex.html
Normal file
72
templates/blogindex.html
Normal file
@@ -0,0 +1,72 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n static %}
|
||||
{% load humanize %}
|
||||
{% block head %}
|
||||
<title> TipPy Blog</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block nav %}
|
||||
{% include "nav.html" with ls=ls season=season %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div id="content-main">
|
||||
<div class="row">
|
||||
<div class="col-md-7">
|
||||
<h2>TipPy Blog</h2>
|
||||
<p class="text-right">
|
||||
<a class="btn btn-default" href="/blog/newpost" role="button">Neue Nachricht</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% for post, avatar in posts %}
|
||||
<div class="row">
|
||||
<div class="col-md-7">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
{{post.author.first_name}} schrieb {{post.created|naturaltime}},
|
||||
<a href="{{post.get_absolute_url}}">{{post.title}}</a>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{% if avatar %}
|
||||
<img class="img-circle img-responsive pull-left blog" alt="Profile Pic" src="/media/{{avatar}}" />
|
||||
{% else %}
|
||||
<img class="img-circle img-responsive pull-left blog" alt="Profile Pic" src="/media/profiles/dummy.png" />
|
||||
{% endif %}
|
||||
{{post.content|safe}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="row">
|
||||
<div class="col-md-7">
|
||||
<nav>
|
||||
<ul class="pager">
|
||||
{% if posts.has_previous %}
|
||||
<li data-toggle="tooltip" title="{% trans 'previous' %}" class="previous">
|
||||
<a href="/blog/{{ page|add:"-1" }}">
|
||||
{% else %}
|
||||
<li data-toggle="tooltip" title="{% trans 'previous' %}" class="previous inactive">
|
||||
<a href="/blog/{{ page }}">
|
||||
{% endif %}
|
||||
<span aria-hidden="true">←</span>
|
||||
</a>
|
||||
</li>
|
||||
Seite {{ posts.number }} von {{ posts.paginator.num_pages }}.
|
||||
{% if posts.has_next %}
|
||||
<li data-toggle="tooltip" title="{% trans 'next' %}" class="next">
|
||||
<a href="/blog/{{ page|add:"1" }}">
|
||||
{% else %}
|
||||
<li data-toggle="tooltip" title="{% trans 'next' %}" class="next inactive">
|
||||
<a href="/blog/{{ page }}">
|
||||
{% endif %}
|
||||
<span aria-hidden="true">→</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
32
templates/blogpost.html
Normal file
32
templates/blogpost.html
Normal file
@@ -0,0 +1,32 @@
|
||||
{% extends "base.html" %}
|
||||
{% block head %}
|
||||
<title> TipPy Blog</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block nav %}
|
||||
{% include "nav.html" with ls=ls season=season %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div id="content-main">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<article>
|
||||
<header>
|
||||
<h3> {{post.title}} </h3>
|
||||
<p>
|
||||
geposted am
|
||||
<time datetime="{{post.created|date:""}}">
|
||||
{{post.created|date}} von {{post.author}}
|
||||
</time>
|
||||
</p>
|
||||
</header>
|
||||
<p class="description">
|
||||
{{post.description}}
|
||||
</p>
|
||||
{{post.content|safe}}
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
38
templates/charts.html
Normal file
38
templates/charts.html
Normal file
@@ -0,0 +1,38 @@
|
||||
{% extends "base.html" %}
|
||||
{% block head %}
|
||||
<title> TipPy Charts</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block nav %}
|
||||
{% include "nav.html" with ls=ls season=season %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% for mandant, users in mandant_dict.items %}
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h2>Bestenliste
|
||||
{% if pos == 'rueck' %}
|
||||
(Rückrunde)</h2>
|
||||
<p><a href="/charts/{{ ls }}/{{ season }}/hin">Hinrunde anzeigen</a></p>
|
||||
{% elif pos == 'hin' %}
|
||||
(Hinrunde)</h3>
|
||||
<p><a href="/charts/{{ ls }}/{{ season }}/rueck">Rückrunde anzeigen</a></p>
|
||||
{% endif %}
|
||||
<h4>Tippgemeinschaft: {{ mandant }}</h4>
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<th>Spieler</th>
|
||||
<th>Punkte</th>
|
||||
</tr>
|
||||
{% for user, score in users %}
|
||||
<tr>
|
||||
<td>{{ user }}</td>
|
||||
<td>{{ score }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
33
templates/login.html
Normal file
33
templates/login.html
Normal file
@@ -0,0 +1,33 @@
|
||||
{% extends "base.html" %}
|
||||
{% load url from future %}
|
||||
{% comment %}
|
||||
Main page to authenticate users.
|
||||
{% endcomment %}
|
||||
|
||||
{% block head %}
|
||||
<title>TipPy | Login</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block nav %}
|
||||
{% include "nav_login.html" with ls=ls season=season %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% if form.errors %}
|
||||
<div class="row">
|
||||
<p>Benutzename und Passwort passen nicht zusammen. Bitte versuche es noch einmal.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<form class="form-signin" role="form" method="post" action="{% url 'django.contrib.auth.views.login' %}">
|
||||
<h2 class="form-signin-heading">Bitte melde dich an</h2>
|
||||
{% csrf_token %}
|
||||
<input class="form-control" type="text" autofocus="" required="" name="{{form.username.html_name}}" placeholder="Anmeldename" />
|
||||
<input class="form-control" type="password" required="" placeholder="Passwort" name="{{form.password.html_name}}" />
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit">Anmelden</button>
|
||||
<input type="hidden" name="next" value="{{ next }}" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
109
templates/md.html
Normal file
109
templates/md.html
Normal file
@@ -0,0 +1,109 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n static %}
|
||||
{% load humanize %}
|
||||
{% block head %}
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}javascript/tippy.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block nav %}
|
||||
{% include "nav.html" with ls=ls season=season %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div id="content-main">
|
||||
<div class="row">
|
||||
<div class="col-md-7">
|
||||
<h2>Neueste Nachrichten</h2>
|
||||
<p class="text-right">
|
||||
<a class="btn btn-default" href="/blog/1" role="button">zum Blog</a>
|
||||
</p>
|
||||
{% for post, avatar in posts %}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
{{post.author.first_name}} schrieb {{post.created|naturaltime}},
|
||||
<a href="{{post.get_absolute_url}}">{{post.title}}</a>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{% if avatar %}
|
||||
<img class="img-circle img-responsive pull-left blog" alt="Profile Pic" src="/media/{{avatar}}" />
|
||||
{% else %}
|
||||
<img class="img-circle img-responsive pull-left blog" alt="Profile Pic" src="/media/profiles/dummy.png" />
|
||||
{% endif %}
|
||||
{{post.content|safe}}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-7">
|
||||
<h2>Deine Tipps</h2>
|
||||
<nav>
|
||||
<ul class="pager">
|
||||
<li data-toggle="tooltip" title="{% trans 'previous' %}" class="previous"><a href="/matchday/{{ ls }}/{{ season }}/{{ cur_md|add:"-1"|stringformat:"02i" }}"><span aria-hidden="true">←</span></a></li>
|
||||
{{ cur_md }}. Spieltag
|
||||
<li data-toggle="tooltip" title="{% trans 'next' %}" class="next"><a href="/matchday/{{ ls }}/{{ season }}/{{ cur_md|add:"1"|stringformat:"02i" }}"><span aria-hidden="true">→</span></a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<form role="form" action="" method="post">{% csrf_token %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-condensed">
|
||||
<tr>
|
||||
<th>Anstoß</th>
|
||||
<th>Heim</th>
|
||||
<th>Gast</th>
|
||||
<th>Erg.></th>
|
||||
<th colspan="2">Tipp</th>
|
||||
</tr>
|
||||
{% for match in matches %}
|
||||
{% if match.started and not match.finished %}
|
||||
<tr class="danger">{% else %}<tr>{% endif %}
|
||||
<td>{{ match.matchDateTime }}</td>
|
||||
<td><img src="{{ STATIC_URL}}{{ match.iconTeam1 }}" />
|
||||
<span class="hidden-xs"> {{ match.nameTeam1 }}</span>
|
||||
<span class="visible-xs"> {{ match.abbrTeam1 }}</span>
|
||||
</td>
|
||||
<td><img src="{{ STATIC_URL}}{{ match.iconTeam2 }}" />
|
||||
<span class="hidden-xs"> {{ match.nameTeam2 }}</span>
|
||||
<span class="visible-xs"> {{ match.abbrTeam2 }}</span>
|
||||
</td>
|
||||
<td>{{ match.matchResult }}</td>
|
||||
<td>{{ match.tippFormTeam1 }}</td><td>{{ match.tippFormTeam2 }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-default btn-lg btn-block">
|
||||
<span class="glyphicon glyphicon-saved" aria-hidden="true"></span> Tipps abgeben
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-7">
|
||||
<h2>Mitspieler</h2>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-condensed">
|
||||
<tr>
|
||||
<th>Tipper</th>
|
||||
<th>Gesamt</th>
|
||||
{% for match in matches %}
|
||||
<th><img src="{{ STATIC_URL }}{{ match.iconTeam1 }}" /><br /><br />
|
||||
<img src="{{ STATIC_URL }}{{ match.iconTeam2 }}" /></th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% for mate in tipp_mates %}
|
||||
<tr>
|
||||
<td>{{ mate.mate }}</td>
|
||||
<td>{{ mate.sum_score }}</td>
|
||||
{% for tipp in mate.tipps %}
|
||||
<td>{{ tipp }}</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
41
templates/nav.html
Normal file
41
templates/nav.html
Normal file
@@ -0,0 +1,41 @@
|
||||
{% load i18n static %}
|
||||
<!-- Fixierte Navbar -->
|
||||
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Navigation ein-/ausblenden</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<span class="navbar-brand">TipPy 1.0</span>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="/">Tipps</a></li>
|
||||
<li><a href="/charts/{{ ls }}/{{ season }}{% if pos %}/{{ pos }}{% endif %}">Bestenliste</a></li>
|
||||
<li><a href="/blog/1">Blog</a></li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
{% if has_refresh %}
|
||||
<li>
|
||||
<a data-toggle="tooltip" title="Ergebnisse aktualisieren" href="/update/{{ ls }}/{{ season }}/{{ cur_md }}">
|
||||
<span class="glyphicon glyphicon-refresh" aria-hidden="true"></span>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="glyphicon glyphicon-user"></span> {{ user.first_name }} <span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="/accounts/profile/{{user.id}}">Profil ändern</a></li>
|
||||
<li><a href="/accounts/password_change/">Passwort ändern</a></li>
|
||||
<li><a href="/logout">Abmelden</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
13
templates/nav_login.html
Normal file
13
templates/nav_login.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Navigation ein-/ausblenden</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<span class="navbar-brand">TipPy 1.0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
49
templates/newblogpost.html
Normal file
49
templates/newblogpost.html
Normal file
@@ -0,0 +1,49 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n static %}
|
||||
{% block head %}
|
||||
<title> TipPy Blog</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block nav %}
|
||||
{% include "nav.html" with ls=ls season=season %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div id="content-main">
|
||||
{% if form.errors %}
|
||||
<div>
|
||||
<p class="errornote">
|
||||
{% if form.errors.items|length == 1 %}
|
||||
{% trans "Please correct the error below." %}
|
||||
{% else %}
|
||||
{% trans "Please correct the errors below." %}
|
||||
{% endif %}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<form class="form-horizontal" action="" method="post">{% csrf_token %}
|
||||
<div class="form-group">
|
||||
{{form.title.errors}}
|
||||
<label for="id_title" class="col-sm-4 control-label required">{% trans 'Title' %}</label>
|
||||
<div class="col-sm-5">
|
||||
<input id="id_title" maxlength="32" name="title" class="form-control" type="text" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{form.content.errors}}
|
||||
<label for="id_content" class="col-sm-4 control-label required">{% trans 'Content' %}</label>
|
||||
<div class="col-sm-5">
|
||||
<textarea class="form-control" maxlength="256" rows="2" id="id_content" name="content"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<button type="submit" class="btn btn-default">{% trans 'Sent' %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
33
templates/registration/login.html
Normal file
33
templates/registration/login.html
Normal file
@@ -0,0 +1,33 @@
|
||||
{% extends "base.html" %}
|
||||
{% load url from future %}
|
||||
{% comment %}
|
||||
Main page to authenticate users.
|
||||
{% endcomment %}
|
||||
|
||||
{% block head %}
|
||||
<title>TipPy | Login</title>
|
||||
{% endblock %}
|
||||
|
||||
{% block nav %}
|
||||
{% include "nav_login.html" with ls=ls season=season %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% if form.errors %}
|
||||
<div class="row">
|
||||
<p>Benutzename und Passwort passen nicht zusammen. Bitte versuche es noch einmal.</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<form class="form-signin" role="form" method="post" action="{% url 'django.contrib.auth.views.login' %}">
|
||||
<h2 class="form-signin-heading">Bitte melde dich an</h2>
|
||||
{% csrf_token %}
|
||||
<input class="form-control" type="text" autofocus="" required="" name="{{form.username.html_name}}" placeholder="Anmeldename" />
|
||||
<input class="form-control" type="password" required="" placeholder="Passwort" name="{{form.password.html_name}}" />
|
||||
<button class="btn btn-lg btn-primary btn-block" type="submit">Anmelden</button>
|
||||
<input type="hidden" name="next" value="{{ next }}" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
22
templates/registration/password_change_done.html
Normal file
22
templates/registration/password_change_done.html
Normal file
@@ -0,0 +1,22 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n static %}
|
||||
|
||||
{% block title %}{% trans 'Password change successful' %}{% endblock %}
|
||||
|
||||
{% block nav %}
|
||||
{% include "nav.html" with ls=ls season=season %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
|
||||
<div id="content-main">
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<h3>{% trans 'Password change successful' %}</h3>
|
||||
<p>{% trans 'Your password was changed.' %}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
59
templates/registration/password_change_form.html
Normal file
59
templates/registration/password_change_form.html
Normal file
@@ -0,0 +1,59 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n static %}
|
||||
|
||||
{% block title %}{% trans 'Password change' %}{% endblock %}
|
||||
|
||||
{% block nav %}
|
||||
{% include "nav.html" with ls=ls season=season %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div id="content-main">
|
||||
<div>
|
||||
{% if form.errors %}
|
||||
<p class="errornote">
|
||||
{% if form.errors.items|length == 1 %}
|
||||
{% trans "Please correct the error below." %}
|
||||
{% else %}
|
||||
{% trans "Please correct the errors below." %}
|
||||
{% endif %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<h2 class="form-signin-heading">{% trans 'Password change' %}</h2>
|
||||
<p>{% trans "Please enter your old password, for security's sake, and then enter your new password twice so we can verify you typed it in correctly." %}</p>
|
||||
<form class="form-horizontal" action="" method="post">{% csrf_token %}
|
||||
<div class="form-group">
|
||||
{{ form.old_password.errors }}
|
||||
<label for="id_old_password" class="col-sm-4 control-label required">{% trans 'Old password' %}</label>
|
||||
<div class="col-sm-5">
|
||||
<input id="id_old_password" name="old_password" class="form-control" type="password" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{ form.new_password1.errors }}
|
||||
<label for="id_new_password1" class="col-sm-4 control-label required">{% trans 'New password' %}</label>
|
||||
<div class="col-sm-5">
|
||||
<input id="id_new_password1" name="new_password1" class="form-control" type="password" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{ form.new_password2.errors }}
|
||||
<label for="id_new_password2" class="col-sm-4 control-label required">{% trans 'Password (again)' %}</label>
|
||||
<div class="col-sm-5">
|
||||
<input id="id_new_password2" name="new_password2" class="form-control" type="password" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<button type="submit" class="btn btn-default">{% trans 'Change my password' %}</button>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">document.getElementById("id_old_password").focus();</script>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
80
templates/registration/profile.html
Normal file
80
templates/registration/profile.html
Normal file
@@ -0,0 +1,80 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n static %}
|
||||
|
||||
{% block title %}{% trans 'Password change' %}{% endblock %}
|
||||
|
||||
{% block nav %}
|
||||
{% include "nav.html" with ls=ls season=season %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div id="content-main">
|
||||
<div>
|
||||
{% if form.errors %}
|
||||
<p class="errornote">
|
||||
{% if form.errors.items|length == 1 %}
|
||||
{% trans "Please correct the error below." %}
|
||||
</p><p>{{ form.errors }}
|
||||
{% else %}
|
||||
{% trans "Please correct the errors below." %}
|
||||
{% endif %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<h2 class="form-signin-heading">{% trans 'Edit Profile' %}</h2>
|
||||
{% if img %}
|
||||
<p><img border="0" alt="Profile Pic" src="{{ img }}" /></p>
|
||||
{% endif %}
|
||||
<form class="form-horizontal" action="" method="post" enctype="multipart/form-data">{% csrf_token %}
|
||||
<div class="form-group">
|
||||
<label for="{{ profile_form.avatar.id_for_label }}" class="col-sm-4 control-label required">Avatar</label>
|
||||
<div class="col-sm-5">
|
||||
{% if img %}
|
||||
<img src="/media/{{ img }}" /><br />
|
||||
<input id="avatar-clear_id" name="avatar-clear" type="checkbox" />
|
||||
<label for="avatar-clear_id">Zurücksetzen</label><br />
|
||||
Ändern: <input id="id_avatar" name="avatar" type="file" />
|
||||
{% else %}
|
||||
<input id="id_avatar" name="avatar" type="file" />
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="{{ user_form.first_name.id_for_label }}" class="col-sm-4 control-label required">Vorname</label>
|
||||
<div class="col-sm-5">
|
||||
{{ user_form.first_name }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="{{ user_form.last_name.id_for_label }}" class="col-sm-4 control-label required">Nachname</label>
|
||||
<div class="col-sm-5">
|
||||
{{ user_form.last_name }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="{{ user_form.email.id_for_label }}" class="col-sm-4 control-label required">E-Mail</label>
|
||||
<div class="col-sm-5">
|
||||
{{ user_form.email }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<button type="submit" class="btn btn-default">{% trans 'Update' %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% if debug %}
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<h2 class="form-signin-heading">{% trans 'Debug' %}</h2>
|
||||
{% for line in debug %}
|
||||
<p>{{ line }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
22
templates/registration/profile_change_done.html
Normal file
22
templates/registration/profile_change_done.html
Normal file
@@ -0,0 +1,22 @@
|
||||
{% extends "base.html" %}
|
||||
{% load i18n static %}
|
||||
|
||||
{% block title %}{% trans 'Profile change successful' %}{% endblock %}
|
||||
|
||||
{% block nav %}
|
||||
{% include "nav.html" with ls=ls season=season %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
|
||||
<div id="content-main">
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<h3>{% trans 'Profile change successful' %}</h3>
|
||||
<p>{% trans 'Your profile was changed.' %}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
0
tipp/__init__.py
Normal file
0
tipp/__init__.py
Normal file
28
tipp/admin.py
Normal file
28
tipp/admin.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from tipp.models import Team, Match, Tipp, Score, Mandant, RelUserMandant, Competition, Post, UserProfile
|
||||
from django.contrib import admin
|
||||
|
||||
class PostAdmin(admin.ModelAdmin):
|
||||
# fields display on change list
|
||||
list_display = ['title']
|
||||
# fields to filter the change list with
|
||||
list_filter = ['published', 'created']
|
||||
# fields to search in change list
|
||||
search_fields = ['title', 'content']
|
||||
# enable the date drill down on change list
|
||||
date_hierarchy = 'created'
|
||||
# enable the save buttons on top on change form
|
||||
save_on_top = True
|
||||
# prepopulate the slug from the title - big timesaver!
|
||||
prepopulated_fields = {"slug": ("title",)}
|
||||
|
||||
|
||||
|
||||
admin.site.register(Team)
|
||||
admin.site.register(Match)
|
||||
admin.site.register(Tipp)
|
||||
admin.site.register(Mandant)
|
||||
admin.site.register(Score)
|
||||
admin.site.register(RelUserMandant)
|
||||
admin.site.register(Competition)
|
||||
admin.site.register(Post, PostAdmin)
|
||||
|
||||
40
tipp/forms.py
Normal file
40
tipp/forms.py
Normal file
@@ -0,0 +1,40 @@
|
||||
from django import forms
|
||||
from django.forms import ModelForm
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.files.images import get_image_dimensions
|
||||
from tipp.models import Match, Competition, Post, UserProfile
|
||||
|
||||
class NumberInput(forms.TextInput):
|
||||
input_type = 'number'
|
||||
|
||||
class TippForm(forms.Form):
|
||||
tippTeam1 = forms.IntegerField(required=True,widget=NumberInput(attrs={
|
||||
'cols': '2',
|
||||
'min': '0', 'max': '99', 'step': '1',
|
||||
'class':'form-inline',
|
||||
'role': 'form'}
|
||||
))
|
||||
tippTeam2 = forms.IntegerField(required=True,widget=NumberInput(attrs={
|
||||
'cols': '2',
|
||||
'min': '0', 'max': '99', 'step': '1',
|
||||
'class':'form-inline',
|
||||
'role': 'form'}
|
||||
))
|
||||
tippTeam1.widget.attrs['style'] = "width:35px"
|
||||
tippTeam2.widget.attrs['style'] = "width:35px"
|
||||
|
||||
class BlogpostForm(ModelForm):
|
||||
class Meta:
|
||||
model = Post
|
||||
fields = ['title', 'content']
|
||||
|
||||
class UserForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['email', 'first_name', 'last_name']
|
||||
|
||||
class UserProfileForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = UserProfile
|
||||
fields = ['avatar']
|
||||
|
||||
111
tipp/models.py
Normal file
111
tipp/models.py
Normal file
@@ -0,0 +1,111 @@
|
||||
from django.db import models
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
class UserProfile(models.Model):
|
||||
user = models.OneToOneField(User)
|
||||
avatar = models.ImageField(upload_to="profiles/", blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.user.username
|
||||
|
||||
class Competition(models.Model):
|
||||
leagueShortcut = models.CharField(max_length=32)
|
||||
leagueName = models.CharField(max_length=128)
|
||||
season = models.CharField(max_length=4)
|
||||
|
||||
def __unicode__(self):
|
||||
return(self.leagueShortcut)
|
||||
|
||||
class Team(models.Model):
|
||||
teamID = models.IntegerField(unique=True, primary_key=True)
|
||||
name = models.CharField(max_length=200)
|
||||
icon = models.FileField(upload_to="images/team_logos/")
|
||||
abbr = models.CharField(max_length=3)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class Match(models.Model):
|
||||
matchID = models.IntegerField(unique=True,primary_key=True)
|
||||
matchDateTime = models.DateTimeField()
|
||||
group = models.IntegerField()
|
||||
matchday = models.IntegerField()
|
||||
idTeam1 = models.ForeignKey(Team, related_name='+')
|
||||
idTeam2 = models.ForeignKey(Team, related_name='+')
|
||||
pointsTeam1 = models.SmallIntegerField()
|
||||
pointsTeam2 = models.SmallIntegerField()
|
||||
finished = models.BooleanField()
|
||||
season = models.CharField(max_length=4)
|
||||
leagueShortcut = models.CharField(max_length=12)
|
||||
|
||||
def __unicode__(self):
|
||||
"""
|
||||
return (str(self.matchID) +
|
||||
str(Team.objects.get(teamID=int(self.idTeam1)).values(name)) + " - " +
|
||||
str(Team.objects.get(teamID=int(self.idTeam2)).values(name)))
|
||||
"""
|
||||
return (str(self.matchID))
|
||||
|
||||
class Tipp(models.Model):
|
||||
matchID = models.ForeignKey(Match)
|
||||
tipperID = models.ForeignKey(User)
|
||||
pointsTeam1 = models.PositiveSmallIntegerField()
|
||||
pointsTeam2 = models.PositiveSmallIntegerField()
|
||||
score = models.PositiveIntegerField(blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
unique_together = ("matchID", "tipperID")
|
||||
|
||||
class Mandant(models.Model):
|
||||
name = models.CharField(max_length=32, unique=True)
|
||||
description = models.CharField(max_length=255)
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class Score(models.Model):
|
||||
client = models.ForeignKey(Mandant)
|
||||
exact_high = models.PositiveSmallIntegerField()
|
||||
exact = models.PositiveSmallIntegerField()
|
||||
diff = models.PositiveSmallIntegerField()
|
||||
tendency = models.PositiveSmallIntegerField()
|
||||
def __unicode__(self):
|
||||
return str(self.client)
|
||||
|
||||
class chart(models.Model):
|
||||
team = models.ForeignKey(Team)
|
||||
competition = models.ForeignKey(Competition)
|
||||
points = models.PositiveSmallIntegerField()
|
||||
diff = models.SmallIntegerField()
|
||||
games = models.PositiveSmallIntegerField()
|
||||
|
||||
class Meta:
|
||||
unique_together = ("team", "competition")
|
||||
|
||||
class RelUserMandant(models.Model):
|
||||
user = models.ForeignKey(User)
|
||||
mandant = models.ForeignKey(Mandant)
|
||||
|
||||
class Meta:
|
||||
unique_together = ("user", "mandant")
|
||||
def __unicode__(self):
|
||||
return (str(self.user) + " -> " + str(self.mandant))
|
||||
|
||||
class Post(models.Model):
|
||||
title = models.CharField(max_length=255)
|
||||
slug = models.SlugField(unique=True, max_length=255)
|
||||
content = models.TextField()
|
||||
published = models.BooleanField(default=True)
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
author = models.ForeignKey(User)
|
||||
|
||||
class Meta:
|
||||
ordering = ['-created']
|
||||
|
||||
def __unicode__(self):
|
||||
return u'%s' % self.title
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('tipp.views.blogpost', args=[self.slug])
|
||||
|
||||
|
||||
68
tipp/openliga.py
Executable file
68
tipp/openliga.py
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2013 by Martin Bley <martin@mb-oss.de>
|
||||
#
|
||||
# tippy.py is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# tippy.py is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with tippy.py. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import sys, locale, suds, urllib2, psycopg2
|
||||
|
||||
class OpenLiga(object):
|
||||
version = "0.1"
|
||||
error = ""
|
||||
proxyurl = None
|
||||
debug = None
|
||||
client = None
|
||||
|
||||
def __init__(self, proxyurl=None, debug=False):
|
||||
|
||||
# set locale to environment (for dispaying localized dates)
|
||||
locale.setlocale(locale.LC_TIME, "")
|
||||
|
||||
self.debug = debug
|
||||
|
||||
# get a SUDS client object
|
||||
if self.proxyurl is None:
|
||||
try:
|
||||
self.client = suds.client.Client('http://www.openligadb.de/Webservices/Sportsdata.asmx?WSDL')
|
||||
except (urllib2.URLError):
|
||||
self.error += "Connect to webservice failed."
|
||||
else:
|
||||
try:
|
||||
t = suds.transport.http.HttpTransport()
|
||||
proxy = urllib2.ProxyHandler({'http':proxyurl})
|
||||
opener = urllib2.build_opener(proxy)
|
||||
t.urlopener = opener
|
||||
self.client = suds.client.Client('http://www.openligadb.de/Webservices/Sportsdata.asmx?WSDL', transport=t)
|
||||
except urllib2.URLError as e:
|
||||
self.error += "Connect to webservice failed (via proxy " + proxyurl + "): " + str(e) + "\n"
|
||||
|
||||
def getSeason(self, season, league='bl1'):
|
||||
""" Get the whole season.
|
||||
|
||||
Args: season and league shortcut (optional)
|
||||
"""
|
||||
return(self.client.service.GetMatchdataByLeagueSaison(leagueShortcut=league,leagueSaison=season))
|
||||
|
||||
def getMatchday(self, season, matchdaynumber, league='bl1'):
|
||||
""" Get matchday.
|
||||
|
||||
Args: season, matchdaynumber and league shortcut (optional)
|
||||
"""
|
||||
return(self.client.service.GetMatchdataByGroupLeagueSaison(groupOrderID=matchdaynumber,leagueShortcut=league,leagueSaison=season))
|
||||
|
||||
def getTeams(self, season, league='bl1'):
|
||||
return(self.client.service.GetTeamsByLeagueSaison(leagueShortcut=league,leagueSaison=season))
|
||||
|
||||
|
||||
16
tipp/tests.py
Normal file
16
tipp/tests.py
Normal file
@@ -0,0 +1,16 @@
|
||||
"""
|
||||
This file demonstrates writing tests using the unittest module. These will pass
|
||||
when you run "manage.py test".
|
||||
|
||||
Replace this with more appropriate tests for your application.
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
|
||||
class SimpleTest(TestCase):
|
||||
def test_basic_addition(self):
|
||||
"""
|
||||
Tests that 1 + 1 always equals 2.
|
||||
"""
|
||||
self.assertEqual(1 + 1, 2)
|
||||
3
tipp/updateMatch.py
Normal file
3
tipp/updateMatch.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from tipp.models import Match
|
||||
|
||||
|
||||
486
tipp/views.py
Normal file
486
tipp/views.py
Normal file
@@ -0,0 +1,486 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render_to_response, redirect, render, get_object_or_404
|
||||
from django.contrib.auth import authenticate, login
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.views import password_reset, password_reset_confirm
|
||||
from django.core.context_processors import csrf
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.paginator import Paginator, InvalidPage, EmptyPage, PageNotAnInteger
|
||||
from django.utils import timezone
|
||||
from django.utils.text import slugify
|
||||
from django.db.models import Sum
|
||||
from django.conf import settings
|
||||
from os.path import join as pjoin
|
||||
from tipp.models import *
|
||||
from tipp.forms import *
|
||||
from openliga import *
|
||||
from datetime import datetime
|
||||
from PIL import Image as PImage
|
||||
import urllib2, pytz, os
|
||||
|
||||
timezoneLocal = pytz.timezone('Europe/Berlin')
|
||||
|
||||
@login_required
|
||||
def home(request):
|
||||
ls = get_current_ls()
|
||||
season = get_current_season()
|
||||
|
||||
return redirect("matchday",
|
||||
ls = ls,
|
||||
season = season,
|
||||
matchday=str(get_current_md(ls, season)).zfill(2)
|
||||
)
|
||||
|
||||
@login_required
|
||||
def profile(request, pk):
|
||||
user = User.objects.get(id=pk)
|
||||
profile, created = UserProfile.objects.get_or_create(user=user)
|
||||
|
||||
if profile.avatar:
|
||||
img = profile.avatar.name
|
||||
else:
|
||||
img = None
|
||||
|
||||
debug = []
|
||||
debug.append('avatar: ' + str(img))
|
||||
|
||||
# If it's a HTTP POST, we're interested in processing form data.
|
||||
if request.method == 'POST':
|
||||
# Attempt to grab information from the raw form information.
|
||||
# Note that we make use of both UserForm and UserProfileForm.
|
||||
user_form = UserForm(data=request.POST, instance=user)
|
||||
profile_form = UserProfileForm(data=request.POST, instance=profile)
|
||||
|
||||
# If the two forms are valid...
|
||||
if user_form.is_valid() and profile_form.is_valid():
|
||||
|
||||
# Save the user's form data to the database.
|
||||
user = user_form.save()
|
||||
|
||||
# Now sort out the UserProfile instance.
|
||||
# Since we need to set the user attribute ourselves, we set commit=False.
|
||||
# This delays saving the model until we're ready to avoid integrity problems.
|
||||
profile = profile_form.save(commit=False)
|
||||
profile.user = user
|
||||
|
||||
# Did the user provide a profile picture?
|
||||
# If so, we need to get it from the input form and put it in the UserProfile model.
|
||||
if 'avatar' in request.FILES:
|
||||
profile.avatar = request.FILES['avatar']
|
||||
# Now we save the UserProfile model instance.
|
||||
profile.save()
|
||||
|
||||
# create thumbnail
|
||||
imfn = pjoin(settings.MEDIA_ROOT, profile.avatar.name)
|
||||
im = PImage.open(imfn)
|
||||
im.thumbnail((50,50), PImage.ANTIALIAS)
|
||||
im.save(settings.MEDIA_ROOT + profile.avatar.name)
|
||||
if 'avatar-clear' in request.POST:
|
||||
if 'on' in request.POST['avatar-clear']:
|
||||
image = pjoin(settings.MEDIA_ROOT, img)
|
||||
debug.append('Is the image ' + str(image) + ' a regular file? ' + str(os.path.isfile(image)))
|
||||
if os.path.isfile(image):
|
||||
os.remove(image)
|
||||
profile.save()
|
||||
|
||||
for item in request.POST:
|
||||
debug.append(str(item) + " -> " + str(request.POST[item]))
|
||||
|
||||
|
||||
|
||||
# Invalid form or forms - mistakes or something else?
|
||||
# Print problems to the terminal.
|
||||
# They'll also be shown to the user.
|
||||
else:
|
||||
print user_form.errors, profile_form.errors
|
||||
|
||||
return redirect( '/accounts/profile/' + str(user.id) )
|
||||
# Not a HTTP POST, so we render our form using two ModelForm instances.
|
||||
# These forms will be blank, ready for user input.
|
||||
else:
|
||||
user_form = UserForm(
|
||||
initial={ 'last_name': user.last_name,
|
||||
'first_name': user.first_name,
|
||||
'email': user.email },
|
||||
instance=user
|
||||
)
|
||||
profile_form = UserProfileForm(instance=profile)
|
||||
|
||||
return render(request, 'registration/profile.html', {
|
||||
'user_form': user_form,
|
||||
'profile_form': profile_form,
|
||||
'debug': debug,
|
||||
'img': img}
|
||||
)
|
||||
|
||||
@login_required
|
||||
def update(request, ls, season, cur_md):
|
||||
"""
|
||||
To do:
|
||||
- update table tipp_competition
|
||||
"""
|
||||
|
||||
ol = OpenLiga()
|
||||
md_matches = ol.getMatchday(str(season), int(cur_md) ,ls)
|
||||
|
||||
# Achtung: DateTimeField prüfen
|
||||
for match in md_matches[0]:
|
||||
# Endergebnis holen
|
||||
matchResults = match['matchResults']
|
||||
try:
|
||||
for result in matchResults[0]:
|
||||
if result['resultName'] == "Endergebnis":
|
||||
pointsTeam1=int(result['pointsTeam1'])
|
||||
pointsTeam2=int(result['pointsTeam2'])
|
||||
elif result['resultName'] == "Halbzeitergebnis":
|
||||
pointsTeam1=int(result['pointsTeam1'])
|
||||
pointsTeam2=int(result['pointsTeam2'])
|
||||
except:
|
||||
pointsTeam1=-1
|
||||
pointsTeam2=-1
|
||||
|
||||
m = Match(matchID=unicode(match['matchID']),
|
||||
matchDateTime=datetime.strptime(unicode(match['matchDateTime']), '%Y-%m-%d %H:%M:%S'),
|
||||
group=int(match['groupID']),
|
||||
matchday=int(match['groupOrderID']),
|
||||
idTeam1=Team.objects.get(teamID=int(match['idTeam1'])),
|
||||
idTeam2=Team.objects.get(teamID=int(match['idTeam2'])),
|
||||
pointsTeam1=pointsTeam1,
|
||||
pointsTeam2=pointsTeam2,
|
||||
finished=bool(match['matchIsFinished']),
|
||||
season=match['leagueSaison'],
|
||||
leagueShortcut=match['leagueShortcut']
|
||||
)
|
||||
m.save()
|
||||
pointsTeam1=-1
|
||||
pointsTeam2=-1
|
||||
|
||||
""" evaluate scores """
|
||||
scores = Score.objects.get(client=Mandant.objects.get(name='huse'))
|
||||
finished_matches=Match.objects.filter(finished=True)
|
||||
for match in finished_matches:
|
||||
tipps = Tipp.objects.filter(matchID=match.matchID)
|
||||
for tipp in tipps:
|
||||
score = 0
|
||||
goals_total = match.pointsTeam1 + match.pointsTeam2
|
||||
|
||||
""" Tipp is acurate """
|
||||
if (tipp.pointsTeam1 == match.pointsTeam1 and tipp.pointsTeam2 == match.pointsTeam2):
|
||||
if goals_total >= 5:
|
||||
score = scores.exact_high
|
||||
else:
|
||||
score = scores.exact
|
||||
|
||||
tipp.score = score
|
||||
tipp.save()
|
||||
continue
|
||||
|
||||
""" who won? """
|
||||
winnerReal = None
|
||||
if match.pointsTeam1 > match.pointsTeam2:
|
||||
winnerReal = 1
|
||||
elif (match.pointsTeam2 > match.pointsTeam1):
|
||||
winnerReal = 2
|
||||
elif (match.pointsTeam1 == match.pointsTeam2):
|
||||
winnerReal = 0
|
||||
|
||||
winnerTipp = None
|
||||
if tipp.pointsTeam1 > tipp.pointsTeam2:
|
||||
winnerTipp = 1
|
||||
elif (tipp.pointsTeam2 > tipp.pointsTeam1):
|
||||
winnerTipp = 2
|
||||
elif (tipp.pointsTeam1 == tipp.pointsTeam2):
|
||||
winnerTipp = 0
|
||||
|
||||
diffReal = match.pointsTeam1 - match.pointsTeam2
|
||||
diffTipp = tipp.pointsTeam1 - tipp.pointsTeam2
|
||||
|
||||
if ( winnerTipp == winnerReal ):
|
||||
if ( diffTipp == diffReal ):
|
||||
score = scores.diff
|
||||
else:
|
||||
score = scores.tendency
|
||||
|
||||
tipp.score = score
|
||||
tipp.save()
|
||||
continue
|
||||
|
||||
tipp.score = score
|
||||
tipp.save()
|
||||
continue
|
||||
|
||||
return redirect("matchday", ls=ls, season=season, matchday=cur_md)
|
||||
|
||||
@login_required
|
||||
def matchday(request, ls, season, matchday, template_name='md.html'):
|
||||
debug = ''
|
||||
debug += "Debugging: "
|
||||
has_refresh = True
|
||||
|
||||
""" get matchday closest to current date """
|
||||
md_matches = Match.objects.filter(leagueShortcut=ls, season=season, matchday=int(matchday)).order_by('matchDateTime')
|
||||
|
||||
""" get the current user """
|
||||
user = User.objects.get(username=request.user.username)
|
||||
|
||||
""" get mandants current user is related """
|
||||
mandants = RelUserMandant.objects.filter(user=request.user).values_list('mandant', flat=True)
|
||||
|
||||
""" get mates """
|
||||
tipp_mates = []
|
||||
for m in mandants:
|
||||
rs = RelUserMandant.objects.filter(mandant=m)
|
||||
for r in rs:
|
||||
tipp_mates.append({
|
||||
'mate': r.user,
|
||||
'tipps': [],
|
||||
'sum_score': 0
|
||||
})
|
||||
|
||||
matches = []
|
||||
for match in md_matches:
|
||||
"""
|
||||
create a form for each tipp
|
||||
"""
|
||||
form = TippForm(request.POST or None, prefix=str(match.matchID))
|
||||
|
||||
"""
|
||||
check if Tipp already exists
|
||||
"""
|
||||
try:
|
||||
tipp = Tipp.objects.get(tipperID=user.id,matchID=match.matchID)
|
||||
except ObjectDoesNotExist:
|
||||
tipp = None
|
||||
|
||||
"""
|
||||
if request is a POST, process form data, else just show form
|
||||
"""
|
||||
if form.is_valid():
|
||||
data = form.cleaned_data
|
||||
|
||||
if tipp is not None:
|
||||
""" Tipp exists an needs an UPDATE"""
|
||||
tipp = Tipp(id=tipp.pk,
|
||||
matchID=match,
|
||||
tipperID=user,
|
||||
pointsTeam1=data['tippTeam1'],
|
||||
pointsTeam2=data['tippTeam2']
|
||||
)
|
||||
tipp.save()
|
||||
|
||||
else:
|
||||
""" do INSERT """
|
||||
tipp = Tipp( matchID=match,
|
||||
tipperID=user,
|
||||
pointsTeam1=data['tippTeam1'],
|
||||
pointsTeam2=data['tippTeam2'])
|
||||
tipp.save()
|
||||
|
||||
match_started = timezone.now() >= match.matchDateTime
|
||||
|
||||
if tipp is not None:
|
||||
f = TippForm(prefix=str(match.matchID),
|
||||
initial={'tippTeam1': tipp.pointsTeam1, 'tippTeam2': tipp.pointsTeam2}
|
||||
)
|
||||
else:
|
||||
f = TippForm(prefix=str(match.matchID))
|
||||
|
||||
item = {}
|
||||
item['matchDateTime'] = (match.matchDateTime.astimezone(timezoneLocal).strftime('%a %d.%m, %H:%M'))
|
||||
|
||||
item['iconTeam1']= str(match.idTeam1.icon)
|
||||
item['nameTeam1']= str(match.idTeam1)
|
||||
item['abbrTeam1']= str(match.idTeam1.abbr)
|
||||
item['iconTeam2'] = str(match.idTeam2.icon)
|
||||
item['nameTeam2'] = str(match.idTeam2)
|
||||
item['abbrTeam2']= str(match.idTeam2.abbr)
|
||||
item['started'] = match_started
|
||||
item['finished'] = match.finished
|
||||
|
||||
if (match.pointsTeam1 == -1 or match.pointsTeam2 == -1):
|
||||
item['matchResult'] = "-:-"
|
||||
else:
|
||||
item['matchResult'] = str(match.pointsTeam1) + ":" + str(match.pointsTeam2)
|
||||
|
||||
item['tippFormTeam1'] = f['tippTeam1']
|
||||
item['tippFormTeam2'] = f['tippTeam2']
|
||||
|
||||
if match_started is True:
|
||||
f.fields['tippTeam1'].widget.attrs['disabled'] = True
|
||||
f.fields['tippTeam2'].widget.attrs['disabled'] = True
|
||||
|
||||
for mate in tipp_mates:
|
||||
try:
|
||||
matetipp = Tipp.objects.get(tipperID=mate['mate'],matchID=match.matchID)
|
||||
if match_started is True:
|
||||
mate['tipps'].append(str(matetipp.pointsTeam1) + ":" + str(matetipp.pointsTeam2) + "(" + str(matetipp.score) + ")")
|
||||
if match.finished is True:
|
||||
mate['sum_score'] += matetipp.score
|
||||
else:
|
||||
mate['tipps'].append(u'\u2714')
|
||||
except Exception as e:
|
||||
mate['tipps'].append(u'\u2717')
|
||||
|
||||
matches.append(item)
|
||||
|
||||
# get the newest blogposts
|
||||
posts = []
|
||||
for post in Post.objects.filter(published=True)[:2]:
|
||||
try:
|
||||
avatar = UserProfile.objects.get(user_id=post.author_id).avatar.name
|
||||
except:
|
||||
avatar = None
|
||||
posts.append( (post, avatar) )
|
||||
|
||||
return render(request, 'md.html', {
|
||||
#'debug': debug,
|
||||
#'mds_season': mds_in_season,
|
||||
'cur_md': matchday,
|
||||
'matches': matches,
|
||||
'ls': ls,
|
||||
'season': season,
|
||||
'username': user,
|
||||
'tipp_mates': sorted(tipp_mates, key=lambda k: k['sum_score'], reverse=True),
|
||||
'posts': posts,
|
||||
'has_refresh': has_refresh
|
||||
})
|
||||
|
||||
@login_required
|
||||
def charts(request, ls, season, pos='default', template_name='charts.html'):
|
||||
debug = ''
|
||||
|
||||
if pos == 'default':
|
||||
if get_current_md(ls, season) < 18:
|
||||
pos = 'hin'
|
||||
matches = Match.objects.filter(leagueShortcut=ls, season=season, matchday__lte=17)
|
||||
else:
|
||||
pos = 'rueck'
|
||||
matches = Match.objects.filter(leagueShortcut=ls, season=season, matchday__gte=18)
|
||||
elif pos == 'hin':
|
||||
matches = Match.objects.filter(leagueShortcut=ls, season=season, matchday__lte=17)
|
||||
elif pos == 'rueck':
|
||||
matches = Match.objects.filter(leagueShortcut=ls, season=season, matchday__gte=18)
|
||||
else:
|
||||
matches = Match.objects.filter(leagueShortcut=ls, season=season)
|
||||
|
||||
# get mandants of current user
|
||||
mandants = RelUserMandant.objects.filter(user=request.user).values_list('mandant', flat=True)
|
||||
|
||||
# main loop
|
||||
mandant_dict = {}
|
||||
for m in mandants:
|
||||
mandant = Mandant.objects.get(id=m)
|
||||
|
||||
# get users
|
||||
users = RelUserMandant.objects.filter(mandant=m).values_list('user', flat=True)
|
||||
|
||||
user_dict = {}
|
||||
for userid in users:
|
||||
# get user object, then fetch matches for user
|
||||
user = User.objects.get(id=userid)
|
||||
score = Tipp.objects.filter(matchID__in=matches, tipperID=user).aggregate(Sum('score'))
|
||||
|
||||
user_dict[user.first_name] = score['score__sum']
|
||||
|
||||
mandant_dict[mandant.name] = sorted(user_dict.items(), key=lambda x: x[1], reverse=True)
|
||||
|
||||
return render(request, template_name, {
|
||||
#'debug': debug,
|
||||
'mandant_dict': mandant_dict,
|
||||
'season': season,
|
||||
'ls': ls,
|
||||
'pos': pos
|
||||
})
|
||||
|
||||
|
||||
@login_required
|
||||
def blogindex(request, page):
|
||||
# get the blog posts that are published
|
||||
post_list = []
|
||||
for post in Post.objects.filter(published=True):
|
||||
try:
|
||||
avatar = UserProfile.objects.get(user_id=post.author_id).avatar.name
|
||||
except:
|
||||
avatar = None
|
||||
post_list.append( (post, avatar) )
|
||||
|
||||
p = Paginator(post_list, 5)
|
||||
|
||||
try:
|
||||
posts = p.page(page)
|
||||
except PageNotAnInteger:
|
||||
# If page is not an integer, deliver first page.
|
||||
posts = p.page(1)
|
||||
except EmptyPage:
|
||||
# If page is out of range (e.g. 9999), deliver last page of results.
|
||||
posts = p.page(p.num_pages)
|
||||
|
||||
# now return the rendered template
|
||||
return render(request, 'blogindex.html', {
|
||||
'posts': posts,
|
||||
'ls': get_current_ls(),
|
||||
'season': get_current_season(),
|
||||
'page': page
|
||||
})
|
||||
|
||||
@login_required
|
||||
def blogpost(request, slug):
|
||||
# get the Post object
|
||||
post = get_object_or_404(Post, slug=slug)
|
||||
# now return the rendered template
|
||||
return render(request, 'blogpost.html', {
|
||||
'post': post,
|
||||
'ls': get_current_ls(),
|
||||
'season': get_current_season()
|
||||
})
|
||||
|
||||
@login_required
|
||||
def newBlogpost(request):
|
||||
"""
|
||||
if this is a POST request we need to process the form data
|
||||
"""
|
||||
if request.method == 'POST':
|
||||
# create form instance and populate it with data from the request
|
||||
form = BlogpostForm(request.POST)
|
||||
# check whether it's valid:
|
||||
if form.is_valid():
|
||||
# process the data
|
||||
data = form.cleaned_data
|
||||
slug = slugify(data['title'])
|
||||
p = Post(author_id=request.user.id, slug=slug, title=data['title'], content=data['content'])
|
||||
p.save()
|
||||
|
||||
# ...
|
||||
# redirect to a new URL:
|
||||
return redirect( '/blog/1')
|
||||
|
||||
# if a GET (or any other method) we'll create a blank form
|
||||
else:
|
||||
blogpostForm = BlogpostForm()
|
||||
return render(request, 'newblogpost.html', {
|
||||
'form': blogpostForm,
|
||||
'ls': get_current_ls(),
|
||||
'season': get_current_season()
|
||||
})
|
||||
|
||||
def logout(request):
|
||||
"""
|
||||
Log users out and re-direct them to the main page.
|
||||
"""
|
||||
logout(request)
|
||||
return HttpResponseRedirect('/')
|
||||
|
||||
def get_current_md(ls,season):
|
||||
""" get current matchday """
|
||||
current_md = Match.objects.filter(leagueShortcut=ls, season=season, finished=False).order_by('matchday').values_list('matchday', flat=True).distinct()[0]
|
||||
return(current_md)
|
||||
|
||||
def get_current_ls():
|
||||
return("bl1")
|
||||
|
||||
def get_current_season():
|
||||
return("2015")
|
||||
|
||||
0
tippy/__init__.py
Normal file
0
tippy/__init__.py
Normal file
188
tippy/settings.py
Normal file
188
tippy/settings.py
Normal file
@@ -0,0 +1,188 @@
|
||||
"""
|
||||
Django settings for tippy project.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/1.7/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/1.7/ref/settings/
|
||||
"""
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
import os
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
|
||||
|
||||
# Django settings for tippy project.
|
||||
DEBUG = True
|
||||
TEMPLATE_DEBUG = DEBUG
|
||||
|
||||
ADMINS = (
|
||||
('Martin Bley', 'martin@mb-oss.de'),
|
||||
)
|
||||
|
||||
MANAGERS = ADMINS
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
||||
'NAME': 'django_tippy',
|
||||
'USER': 'tippy',
|
||||
'PASSWORD': 'tippy',
|
||||
'HOST': 'localhost',
|
||||
'PORT': '5432',
|
||||
}
|
||||
}
|
||||
|
||||
# Hosts/domain names that are valid for this site; required if DEBUG is False
|
||||
# See https://docs.djangoproject.com/en/1.4/ref/settings/#allowed-hosts
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
# Local time zone for this installation. Choices can be found here:
|
||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||
# although not all choices may be available on all operating systems.
|
||||
# In a Windows environment this must be set to your system time zone.
|
||||
TIME_ZONE = 'Europe/Berlin'
|
||||
|
||||
# Language code for this installation. All choices can be found here:
|
||||
# http://www.i18nguy.com/unicode/language-identifiers.html
|
||||
LANGUAGE_CODE = 'de-de'
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
# If you set this to False, Django will make some optimizations so as not
|
||||
# to load the internationalization machinery.
|
||||
USE_I18N = True
|
||||
|
||||
# If you set this to False, Django will not format dates, numbers and
|
||||
# calendars according to the current locale.
|
||||
USE_L10N = True
|
||||
|
||||
# If you set this to False, Django will not use timezone-aware datetimes.
|
||||
USE_TZ = True
|
||||
|
||||
# Absolute filesystem path to the directory that will hold user-uploaded files.
|
||||
# Example: "/home/media/media.lawrence.com/media/"
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
|
||||
|
||||
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
|
||||
# trailing slash.
|
||||
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
|
||||
MEDIA_URL = '/media/'
|
||||
|
||||
# Absolute path to the directory static files should be collected to.
|
||||
# Don't put anything in this directory yourself; store your static files
|
||||
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
|
||||
# Example: "/home/media/media.lawrence.com/static/"
|
||||
#STATIC_ROOT = '/opt/TipPy/TipPy/static/'
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/')
|
||||
|
||||
# URL prefix for static files.
|
||||
# Example: "http://media.lawrence.com/static/"
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
# Additional locations of static files
|
||||
STATICFILES_DIRS = (
|
||||
# Put strings here, like "/home/html/static" or "C:/www/django/static".
|
||||
# Always use forward slashes, even on Windows.
|
||||
# Don't forget to use absolute paths, not relative paths.
|
||||
#'/opt/TipPy/TipPy/tipp/static/',
|
||||
)
|
||||
|
||||
# List of finder classes that know how to find static files in
|
||||
# various locations.
|
||||
STATICFILES_FINDERS = (
|
||||
'django.contrib.staticfiles.finders.FileSystemFinder',
|
||||
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
|
||||
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
|
||||
)
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = '-7%ge^nl1b0t0694%ws&0$ft_lo)j4l1f-qv#ku^=$)s(sw6us'
|
||||
|
||||
# List of callables that know how to import templates from various sources.
|
||||
TEMPLATE_LOADERS = (
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
# 'django.template.loaders.eggs.Loader',
|
||||
)
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
# Uncomment the next line for simple clickjacking protection:
|
||||
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'tippy.urls'
|
||||
|
||||
# Python dotted path to the WSGI application used by Django's runserver.
|
||||
WSGI_APPLICATION = 'tippy.wsgi.application'
|
||||
|
||||
TEMPLATE_DIRS = (
|
||||
[os.path.join(BASE_DIR, 'templates')]
|
||||
)
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'django.contrib.humanize',
|
||||
# Uncomment the next line to enable the admin:
|
||||
'django.contrib.admin',
|
||||
# Uncomment the next line to enable admin documentation:
|
||||
'django.contrib.admindocs',
|
||||
'tipp',
|
||||
)
|
||||
|
||||
# URL of the login page.
|
||||
LOGIN_URL = '/login'
|
||||
|
||||
# A sample logging configuration. The only tangible logging
|
||||
# performed by this configuration is to send an email to
|
||||
# the site admins on every HTTP 500 error when DEBUG=False.
|
||||
# See http://docs.djangoproject.com/en/dev/topics/logging for
|
||||
# more details on how to customize your logging configuration.
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'filters': {
|
||||
'require_debug_false': {
|
||||
'()': 'django.utils.log.RequireDebugFalse'
|
||||
}
|
||||
},
|
||||
'handlers': {
|
||||
'mail_admins': {
|
||||
'level': 'ERROR',
|
||||
'filters': ['require_debug_false'],
|
||||
'class': 'django.utils.log.AdminEmailHandler'
|
||||
}
|
||||
},
|
||||
'loggers': {
|
||||
'django.request': {
|
||||
'handlers': ['mail_admins'],
|
||||
'level': 'ERROR',
|
||||
'propagate': True,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
EMAIL_USE_TLS = True
|
||||
EMAIL_HOST = 'hermes.mb-oss.de'
|
||||
EMAIL_PORT = 25
|
||||
EMAIL_HOST_USER = 'tippy@mb-oss.de'
|
||||
#EMAIL_HOST_PASSWORD = 'p@ssword'
|
||||
|
||||
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
|
||||
SERVER_EMAIL = EMAIL_HOST_USER
|
||||
|
||||
SESSION_COOKIE_AGE = 7200
|
||||
|
||||
AUTH_PROFILE_MODULE = 'tippy.UserProfile'
|
||||
|
||||
|
||||
37
tippy/urls.py
Normal file
37
tippy/urls.py
Normal file
@@ -0,0 +1,37 @@
|
||||
from django.conf.urls import patterns, include, url
|
||||
from django.conf import settings
|
||||
|
||||
# Uncomment the next two lines to enable the admin:
|
||||
from django.contrib import admin
|
||||
admin.autodiscover()
|
||||
|
||||
urlpatterns = patterns('',
|
||||
# Examples:
|
||||
url(r'^$', 'tipp.views.home', name='home'),
|
||||
url(r'^login$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}),
|
||||
url(r'^logout$', 'django.contrib.auth.views.logout', {'next_page': '/'}),
|
||||
url(r'^update/(?P<ls>.*)/(?P<season>\d{4})/(?P<cur_md>\d{2})$', 'tipp.views.update', name='update'),
|
||||
url(r'^matchday/(?P<ls>.{3,})/(?P<season>\d{4})/(?P<matchday>\d{2})$', 'tipp.views.matchday', name='matchday'),
|
||||
url(r'^charts/(?P<ls>\w{3,})/(?P<season>\d{4})$', 'tipp.views.charts', name='charts'),
|
||||
url(r'^charts/(?P<ls>\w{3,})/(?P<season>\d{4})/(?P<pos>\w{1,})$', 'tipp.views.charts', name='charts'),
|
||||
url(r'^accounts/profile/(\d+)', 'tipp.views.profile'),
|
||||
url(r'^accounts/', include('django.contrib.auth.urls')),
|
||||
url(r'^blog/newpost$', 'tipp.views.newBlogpost'),
|
||||
url(r'^blog/(?P<page>\d)$', 'tipp.views.blogindex'),
|
||||
url(r'^blog/(?P<slug>[\w\-]+)', 'tipp.views.blogpost'),
|
||||
|
||||
# Uncomment the admin/doc line below to enable admin documentation:
|
||||
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
|
||||
|
||||
# Uncomment the next line to enable the admin:
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
)
|
||||
|
||||
if settings.DEBUG:
|
||||
urlpatterns += patterns('',
|
||||
url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
|
||||
'document_root': settings.MEDIA_ROOT,
|
||||
}),
|
||||
)
|
||||
|
||||
|
||||
28
tippy/wsgi.py
Normal file
28
tippy/wsgi.py
Normal file
@@ -0,0 +1,28 @@
|
||||
"""
|
||||
WSGI config for tippy project.
|
||||
|
||||
This module contains the WSGI application used by Django's development server
|
||||
and any production WSGI deployments. It should expose a module-level variable
|
||||
named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
|
||||
this application via the ``WSGI_APPLICATION`` setting.
|
||||
|
||||
Usually you will have the standard Django WSGI application here, but it also
|
||||
might make sense to replace the whole Django WSGI application with a custom one
|
||||
that later delegates to the Django one. For example, you could introduce WSGI
|
||||
middleware here, or combine a Django application with an application of another
|
||||
framework.
|
||||
|
||||
"""
|
||||
import os
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tippy.settings")
|
||||
|
||||
# This application object is used by any WSGI server configured to use this
|
||||
# file. This includes Django's development server, if the WSGI_APPLICATION
|
||||
# setting points here.
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
application = get_wsgi_application()
|
||||
|
||||
# Apply WSGI middleware here.
|
||||
# from helloworld.wsgi import HelloWorldApplication
|
||||
# application = HelloWorldApplication(application)
|
||||
Reference in New Issue
Block a user