42 Commits
Author SHA1 Message Date
Martin Bley 3322649f05 Code optimizsations 2026-09-19 09:04:26 +02:00
Martin Bley 6b99dd5250 venv is running 2026-09-19 07:58:45 +02:00
Martin Bley d4dbd3d9da Updatet venv 2026-09-19 07:32:04 +02:00
Martin Bley 5b7f847bc6 Models optimiert 2026-09-13 08:51:38 +02:00
Martin Bley 99eaafff00 - getSeason() only for staff members
- new view staff()
- updated bootstrap to version 3.4.1
- updated jquery to 3.6.3
- changed container layout in main view 'matchday'
2023-04-02 21:24:20 +02:00
Martin Bley 446a55f3e5 New design and renaming for the blog which now named chat 2022-10-04 17:29:21 +02:00
Martin Bley 2f970d6eb4 fix for clean logout 2022-09-18 17:59:08 +02:00
Martin Bley c1deabc692 fix for clean logout 2022-09-18 17:57:38 +02:00
Martin Bley fb3e425471 fix for clean logout 2022-09-18 17:48:33 +02:00
Martin Bley 46bc47f046 Added migrations do tipp app 2022-09-18 13:59:06 +02:00
Martin Bley 8db2774f7c Added new file for lib deps 2022-09-18 13:54:36 +02:00
Martin Bley 272498b4ce Revised templates 2022-09-18 13:26:47 +02:00
Martin Bley 12323615c7 First import of migration to python 3 2022-09-18 13:24:58 +02:00
martin 9d6857cfe2 „AUTHORS“ ändern 2022-01-05 19:38:04 +01:00
Martin Bley 565bb3963e Fixed issue #15 2016-12-21 11:04:30 +01:00
amma 3b2deb865e Merge branch 'iss07' (about) 2016-11-23 18:52:20 +01:00
amma a221c0e37d Fixed iss#07 (About) 2016-11-23 18:48:33 +01:00
amma de3e844089 Fixed ticket #14 2016-11-23 17:58:37 +01:00
amma 72be0aebdb Sorted mate table 2016-10-06 21:04:19 +02:00
amma 929b540753 Changed width of TippForm to be able to see the values 2016-10-06 11:33:15 +02:00
amma b44d31d128 Fix of iss11 2016-10-06 11:20:49 +02:00
amma 26833e389a No output in mate list 2016-10-06 10:45:18 +02:00
amma ffed1ef6e8 Fixed issue #13 2016-10-06 09:59:26 +02:00
amma db5ece431b Work on issue 11 2016-09-22 17:31:19 +02:00
amma 20ef745b3f Uncomitted changes 2016-09-22 16:37:05 +02:00
amma 45293586a7 Fixed issues in getSeason() 2016-08-20 13:58:35 +02:00
amma 8f9398ced5 Don't know 2016-07-17 11:48:14 +02:00
amma 589884c4be Fixed long lines 2016-06-24 16:11:43 +02:00
amma 5c3c56ecc3 Implemented selection of mandants when posting blog items 2016-06-23 15:03:12 +02:00
amma 6042838f28 Fixed getSeason() and update() in views.py 2016-06-23 10:51:12 +02:00
amma c2eede9500 Implemented mandant based blog posts 2016-06-17 22:37:43 +02:00
amma e3ef06a41a Minor changes 2016-06-14 12:49:10 +02:00
amma 9be82123da Better update() using a nother query 2016-06-13 21:27:31 +02:00
amma 911b19068c Renewed get_current_md() based on OL method 2016-06-11 17:09:13 +02:00
amma c02f137c0b fixed some issues regarding template 2016-06-10 17:54:59 +02:00
amma 538f6262fd modified for EURO 2016 2016-06-10 17:36:02 +02:00
amma 4b2f7e4641 Finished templates for new HTTP method 2016-06-08 08:15:54 +02:00
amma d99eee4751 Merge branch 'iss02' 2016-06-07 18:20:35 +02:00
amma 5a0a1daa39 finished import function 2016-06-07 18:19:22 +02:00
amma 20f0a836e5 new url for import added 2016-06-07 17:24:15 +02:00
amma c0eb583a69 import function created 2016-06-07 17:22:28 +02:00
amma 7292957497 Don't know 2016-06-07 16:52:22 +02:00
32 changed files with 1590 additions and 922 deletions
+45 -9
View File
@@ -1,10 +1,46 @@
*.pyc # Virtuelle Umgebung
*.swp venv/
bin/ env/
manage.py ENV/
.venv
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Django
*.log
db.sqlite3
media/ media/
old_stuff/ staticfiles/
static/
templates/blogindex.html-media # IDE
tippy/static/ .vscode/
warnings.txt .idea/
*.swp
*.swo
*~
# Umgebungsvariablen
.env
.env.local
+1 -1
View File
@@ -1 +1 @@
Martin Bley <martin@mb-oss.de> Martin Bley <dev@mb-oss.de>
+6
View File
@@ -0,0 +1,6 @@
- getSeason() only for staff members
- new view staff()
- updated bootstrap to version 3.4.1
- updated jquery to 3.6.3
- changed container layout in main view 'matchday'
+16
View File
@@ -0,0 +1,16 @@
"""
ASGI config for TipPy project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'TipPy.settings')
application = get_asgi_application()
+146
View File
@@ -0,0 +1,146 @@
"""
Django settings for TipPy project.
Generated by 'django-admin startproject' using Django 4.0.6.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.0/ref/settings/
"""
from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-jiw8js(^@d)no7tv(oq+ugl3kj=f8@j-kz3bj530&!%!$cjqj9'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
'tipp'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'TipPy.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates']
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'TipPy.wsgi.application'
WSGI_APPLICATION = 'TipPy.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'tippy',
'USER': 'tippy',
'PASSWORD': 'tippy',
'HOST': 'localhost',
'PORT': '5432',
}
}
# Password validation
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/
LANGUAGE_CODE = 'de-de'
TIME_ZONE = 'Europe/Berlin'
USE_I18N = True
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/"
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
if not DEBUG:
STATIC_ROOT = ''
STATICFILES_DIRS = [
#os.path.join(BASE_DIR, 'static/'),
]
# STATIC_ROOT=os.path.join(BASE_DIR,"static/")
# STATIC_URL = 'static/'
# STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'), ]
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# Redirect on logout
LOGOUT_REDIRECT_URL = "home"
+8
View File
@@ -0,0 +1,8 @@
from django.contrib import admin, auth
from django.urls import include, path, re_path
urlpatterns = [
path('', include('tipp.urls')),
path('admin/', admin.site.urls),
]
+16
View File
@@ -0,0 +1,16 @@
"""
WSGI config for TipPy project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'TipPy.settings')
application = get_wsgi_application()
Executable
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "TipPy.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == "__main__":
main()
+8
View File
@@ -0,0 +1,8 @@
asgiref==3.12.1
Django==6.1.1
pillow==12.3.0
psycopg2==2.9.13
pytz==2026.3.post1
sqlparse==0.6.0
suds-community==1.2.0
urllib3==2.8.0
+29
View File
@@ -0,0 +1,29 @@
{% extends "base.html" %}
{% load i18n static %}
{% load humanize %}
{% block head %}
<script type="text/javascript" src="{% static '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>Über TipPy</h2>
<p>TipPy ist eine responsive Web-Applikation für Tippspiele mit
einem "Mobile-First-Ansatz" . Unterstützt werden alle auf
<a href="http://www.OpenLigaDB.de">OpenLigaDB</a> bereitgestellten
Sportarten und Ligen.
TipPy wurde in <a href="http://www.python.org">Python</a> umgesetzt
und benutzt die Frameworks <a href="http://www.django.org">Django</a>
als Web Application Framework, und Twitters <a href="www.getbootstrap.com">
Bootstrap</a> für CSS.</p>
</div>
</div>
</div>
{% endblock %}
+6 -6
View File
@@ -16,13 +16,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap --> <!-- Bootstrap -->
<link href="{{ STATIC_URL }}css/bootstrap.min.css" rel="stylesheet"> <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
<!-- Bootstrap-Theme --> <!-- Bootstrap-Theme -->
<link href="{{ STATIC_URL }}css/bootstrap-theme.min.css" rel="stylesheet"> <link href="{% static 'css/bootstrap-theme.min.css' %}" rel="stylesheet">
<!-- Bootstrap-Theme --> <!-- Bootstrap-Theme -->
<link href="{{ STATIC_URL }}css/tippy-bootstrap.css" rel="stylesheet"> <link href="{% static 'css/tippy-bootstrap.css' %}" rel="stylesheet">
<!-- Unterstützung für Media Queries und HTML5-Elemente im Internet Explorer über HTML5 shim und Respond.js --> <!-- 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 --> <!-- ACHTUNG: Respond.js funktioniert nicht, wenn du die Seite über file:// aufrufst -->
@@ -36,9 +36,9 @@
<body> <body>
<!-- jQuery (wird für Bootstrap JavaScript-Plugins benötigt) --> <!-- 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> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<!-- Binde alle kompilierten Plugins zusammen ein (wie hier unten) oder such dir einzelne Dateien nach Bedarf aus --> <!-- 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> <script src="{% static 'js/bootstrap.min.js'%}"></script>
{% block nav %}{% endblock %} {% block nav %}{% endblock %}
@@ -53,7 +53,7 @@
<div class="col-md-7"> <div class="col-md-7">
<p> <p>
<div class="pull-left"> <div class="pull-left">
© Martin Bley, 2014-2016 | Dank an © Martin Bley, 2014-2023 | Dank an
<a href="http://openligadb.de">OpenLigaDB</a> für die Bereitstellung der <a href="http://openligadb.de">OpenLigaDB</a> für die Bereitstellung der
Spielergebnisse. Spielergebnisse.
</div> </div>
+21 -17
View File
@@ -2,15 +2,15 @@
{% load i18n static %} {% load i18n static %}
{% load humanize %} {% load humanize %}
{% block head %} {% block head %}
<title> TipPy Blog</title> <title> TipPy Blog</title>
{% endblock %} {% endblock %}
{% block nav %} {% block nav %}
{% include "nav.html" with ls=ls season=season %} {% include "nav.html" with ls=ls season=season %}
{% endblock %} {% endblock %}
{% block body %} {% block body %}
<div id="content-main"> <div id="content-main">
<div class="row"> <div class="row">
<div class="col-md-7"> <div class="col-md-7">
<h2>TipPy Blog</h2> <h2>TipPy Blog</h2>
@@ -19,25 +19,29 @@
</p> </p>
</div> </div>
</div> </div>
<ul class="media-list">
{% for post, avatar in posts %} {% for post, avatar in posts %}
<div class="row"> <li class="media">
<div class="col-md-7"> <a href="#" class="pull-left">
<div class="panel panel-default">
<div class="panel-heading">
{{post.author.first_name}} schrieb {{post.created|naturaltime}}
</div>
<div class="panel-body">
{% if avatar %} {% if avatar %}
<img class="img-circle img-responsive pull-left blog" alt="Profile Pic" src="/media/{{avatar}}" /> <img class="img-circle img-responsive pull-left blog" alt="Profile Pic"
src="/media/{{ avatar }}"/>
{% else %} {% else %}
<img class="img-circle img-responsive pull-left blog" alt="Profile Pic" src="/media/profiles/dummy.png" /> <img class="img-circle img-responsive pull-left blog" alt="Profile Pic"
src="/media/profiles/dummy.png"/>
{% endif %} {% endif %}
{{post.content|safe}} </a>
</div> <div class="media-body">
</div> <span class="text-muted pull-right">
</div> <small class="text-muted">{{ post.created|naturaltime }}</small>
</span>
<strong class="text-success">{{ post.author.first_name }}</strong>
<p>{{ post.content|safe }}</p>
</div> </div>
</li>
{% endfor %} {% endfor %}
</ul>
<div class="row"> <div class="row">
<div class="col-md-7"> <div class="col-md-7">
<nav> <nav>
@@ -67,5 +71,5 @@
</nav> </nav>
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
+28
View File
@@ -0,0 +1,28 @@
{% load humanize %}
<hr>
<p class="text-left">
<a class="btn btn-default" href="/blog/newpost" role="button">neuer Post</a>
</p>
<ul class="media-list">
{% for post, avatar in posts %}
<li class="media">
<a href="#" class="pull-left">
{% 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 %}
</a>
<div class="media-body">
<span class="text-muted pull-right">
<small class="text-muted">{{ post.created|naturaltime }}</small>
</span>
<strong class="text-success">{{ post.author.first_name }}</strong>
<p>{{ post.content|safe }}</p>
</div>
</li>
{% endfor %}
</ul>
-33
View File
@@ -1,33 +0,0 @@
{% 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 %}
+54 -47
View File
@@ -2,46 +2,27 @@
{% load i18n static %} {% load i18n static %}
{% load humanize %} {% load humanize %}
{% block head %} {% block head %}
<script type="text/javascript" src="{{ STATIC_URL }}javascript/tippy.js"></script> <script type="text/javascript" src="{% static 'javascript/tippy.js' %}"></script>
{% endblock %} {% endblock %}
{% block nav %} {% block nav %}
{% include "nav.html" with ls=ls season=season %} {% include "nav.html" with ls=ls season=season %}
{% endblock %} {% endblock %}
{% block body %} {% block body %}
<div id="content-main"> <div id="content-main">
<div class="row"> <div class="row">
<div class="col-md-7"> <div class="col-md-6">
<h2>Neueste Nachrichten</h2> <h3>Deine Tipps</h3>
<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}}
</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> <nav>
<ul class="pager"> <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">&larr;</span></a></li> <li data-toggle="tooltip" title="{% trans 'previous' %}" class="previous"><a
{{ cur_md }}. Spieltag href="/matchday/{{ ls }}/{{ season }}/{{ cur_md|add:"-1"|stringformat:"02i" }}"><span
<li data-toggle="tooltip" title="{% trans 'next' %}" class="next"><a href="/matchday/{{ ls }}/{{ season }}/{{ cur_md|add:"1"|stringformat:"02i" }}"><span aria-hidden="true">&rarr;</span></a></li> aria-hidden="true">&larr;</span></a></li>
{{ md_name }}
<li data-toggle="tooltip" title="{% trans 'next' %}" class="next"><a
href="/matchday/{{ ls }}/{{ season }}/{{ cur_md|add:"1"|stringformat:"02i" }}"><span
aria-hidden="true">&rarr;</span></a></li>
</ul> </ul>
</nav> </nav>
<form role="form" action="" method="post">{% csrf_token %} <form role="form" action="" method="post">{% csrf_token %}
@@ -51,23 +32,33 @@
<th>Anstoß</th> <th>Anstoß</th>
<th>Heim</th> <th>Heim</th>
<th>Gast</th> <th>Gast</th>
<th>Erg.></th> <th>Erg.</th>
<th colspan="2">Tipp</th> <th colspan="2">Tipp</th>
</tr> </tr>
{% for match in matches %} {% for match in matches %}
{% if match.started and not match.finished %} {% if match.started and not match.finished %}
<tr class="danger">{% else %}<tr>{% endif %} <tr class="danger">{% else %}
<tr>{% endif %}
<td>{{ match.matchDateTime }}</td> <td>{{ match.matchDateTime }}</td>
<td><img src="{{ STATIC_URL}}{{ match.iconTeam1 }}" /> {% if match.iconURLTeam1 != "" %}
<td><img src="{{ match.iconURLTeam1 }}" width="20"/>
{% else %}
<td><img src="{{ STATIC_URL }}{{ match.iconTeam1 }}"/>
{% endif %}
<span class="hidden-xs"> {{ match.nameTeam1 }}</span> <span class="hidden-xs"> {{ match.nameTeam1 }}</span>
<span class="visible-xs"> {{ match.abbrTeam1 }}</span> <span class="visible-xs"> {{ match.abbrTeam1 }}</span>
</td> </td>
<td><img src="{{ STATIC_URL}}{{ match.iconTeam2 }}" /> {% if match.iconURLTeam1 != "" %}
<td><img src="{{ match.iconURLTeam2 }}" width="20"/>
{% else %}
<td><img src="{{ STATIC_URL }}{{ match.iconTeam2 }}"/>
{% endif %}
<span class="hidden-xs"> {{ match.nameTeam2 }}</span> <span class="hidden-xs"> {{ match.nameTeam2 }}</span>
<span class="visible-xs"> {{ match.abbrTeam2 }}</span> <span class="visible-xs"> {{ match.abbrTeam2 }}</span>
</td> </td>
<td>{{ match.matchResult }}</td> <td>{{ match.matchResult }}</td>
<td>{{ match.tippFormTeam1 }}</td><td>{{ match.tippFormTeam2 }}</td> <td>{{ match.tippFormTeam1 }}</td>
<td>{{ match.tippFormTeam2 }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>
@@ -76,33 +67,49 @@
<span class="glyphicon glyphicon-saved" aria-hidden="true"></span> Tipps abgeben <span class="glyphicon glyphicon-saved" aria-hidden="true"></span> Tipps abgeben
</button> </button>
</form> </form>
</div>
</div> {% for mandant, list in mandant_dict.items %}
<div class="row"> <h3>Mitspieler {{ mandant }}</h3>
<div class="col-md-7">
<h2>Mitspieler</h2>
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-hover table-condensed"> <table class="table table-hover table-condensed">
<tr> <tr>
<th>Tipper</th> <th>Tipper</th>
<th>Gesamt</th> <th>Gesamt</th>
{% for match in matches %} {% for match in matches %}
<th><img src="{{ STATIC_URL }}{{ match.iconTeam1 }}" /><br /><br /> <th>
<img src="{{ STATIC_URL }}{{ match.iconTeam2 }}" /></th> {% if match.iconURLTeam1 != "" %}
<img src="{{ match.iconURLTeam1 }}" width="20"/>
{% else %}
<img src="{{ STATIC_URL }}{{ match.iconTeam1 }}"/>
{% endif %}
<br/><br/>
{% if match.iconURLTeam2 != "" %}
<img src="{{ match.iconURLTeam2 }}" width="20"/>
{% else %}
<img src="{{ STATIC_URL }}{{ match.iconTeam2 }}"/>
{% endif %}
</th>
{% endfor %} {% endfor %}
</tr> </tr>
{% for mate in tipp_mates %} {% for mate in list %}
<tr> <tr>
<td>{{ mate.mate }}</td> <td>{{ mate.mate.first_name }}</td>
<td>{{ mate.sum_score }}</td> <td>{{ mate.sum_score }}</td>
{% for tipp in mate.tipps %} {% for tipp in mate.tipps %}
<td>{{ tipp }}</td> <td>{{ tipp }}</td>
{% endfor %} {% endfor %}
</tr>
{% endfor %} {% endfor %}
</tr>
</table> </table>
</div> </div>
{% endfor %}
</div>
<div class="col-md-6">
<h3>Chat</h3>
{% block chat %}
{% include "chat.xhtml" with posts=posts %}
{% endblock %}
</div>
</div> </div>
</div> </div>
</div>
{% endblock %} {% endblock %}
+5 -2
View File
@@ -9,13 +9,16 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<span class="navbar-brand">TipPy 1.0</span> <a class="navbar-brand" href="/about">TipPy 1.0</a>
</div> </div>
<div class="navbar-collapse collapse"> <div class="navbar-collapse collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="/">Tipps</a></li> <li><a href="/">Tipps</a></li>
<li><a href="/charts/{{ ls }}/{{ season }}{% if pos %}/{{ pos }}{% endif %}">Bestenliste</a></li> <li><a href="/charts/{{ ls }}/{{ season }}{% if pos %}/{{ pos }}{% endif %}">Bestenliste</a></li>
<li><a href="/blog/1">Blog</a></li> <li><a href="/blog/1">Blog</a></li>
{% if request.user.is_active and request.user.is_staff %}
<li><a href="/staff">Staff</a></li>
{% endif %}
</ul> </ul>
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
{% if has_refresh %} {% if has_refresh %}
@@ -32,7 +35,7 @@
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="/accounts/profile/{{user.id}}">Profil ändern</a></li> <li><a href="/accounts/profile/{{user.id}}">Profil ändern</a></li>
<li><a href="/accounts/password_change/">Passwort ändern</a></li> <li><a href="/accounts/password_change/">Passwort ändern</a></li>
<li><a href="/logout">Abmelden</a></li> <li><a href="/accounts/logout">Abmelden</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
+25 -9
View File
@@ -1,19 +1,19 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n static %} {% load i18n static %}
{% block head %} {% block head %}
<title> TipPy Blog</title> <title> TipPy Blog</title>
{% endblock %} {% endblock %}
{% block nav %} {% block nav %}
{% include "nav.html" with ls=ls season=season %} {% include "nav.html" with ls=ls season=season %}
{% endblock %} {% endblock %}
{% block body %} {% block body %}
<div id="content-main"> <div id="content-main">
{% if form.errors %} {% if form_bp.errors %}
<div> <div>
<p class="errornote"> <p class="errornote">
{% if form.errors.items|length == 1 %} {% if form_bp.errors.items|length == 1 %}
{% trans "Please correct the error below." %} {% trans "Please correct the error below." %}
{% else %} {% else %}
{% trans "Please correct the errors below." %} {% trans "Please correct the errors below." %}
@@ -24,10 +24,19 @@
<div class="col-md-8"> <div class="col-md-8">
<form class="form-horizontal" action="" method="post">{% csrf_token %} <form class="form-horizontal" action="" method="post">{% csrf_token %}
<div class="form-group"> <div class="form-group">
{{form.content.errors}} {{ form_bp.content.errors }}
<label for="id_content" class="col-sm-4 control-label required">{% trans 'Content' %}</label>
<div class="col-sm-5"> <div class="col-sm-5">
<textarea class="form-control" maxlength="256" rows="2" id="id_content" name="content"></textarea> <div class="panel-body">
<textarea class="form-control" placeholder="Schreibe einen Kommentar..." id="id_content"
name="content" maxlength="100" rows="2"></textarea>
{% if cnt_mandants > 1 %}
{{ form_mandants.mandants.label_tag }}
{% for choice in form_mandants.mandants %}
<label for="{{ choice.id_for_label }}">
{{ choice.tag }} {{ choice.choice_label }}
</label>
{% endfor %}
{% endif %}
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
@@ -38,5 +47,12 @@
</form> </form>
</div> </div>
</div> </div>
</div> {% if debug %}
<div class="row">
<div class="col-md-8">
<p>{{ debug }}</p>
</div>
</div>
{% endif %}
</div>
{% endblock %} {% endblock %}
+3 -2
View File
@@ -1,5 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load url from future %} {% load admin_urls %}
{% comment %} {% comment %}
Main page to authenticate users. Main page to authenticate users.
{% endcomment %} {% endcomment %}
@@ -20,7 +21,7 @@
{% endif %} {% endif %}
<div class="row"> <div class="row">
<div class="col-md-3"> <div class="col-md-3">
<form class="form-signin" role="form" method="post" action="{% url 'django.contrib.auth.views.login' %}"> <form class="form-signin" role="form" method="post" action="{% url 'login' %}">
<h2 class="form-signin-heading">Bitte melde dich an</h2> <h2 class="form-signin-heading">Bitte melde dich an</h2>
{% csrf_token %} {% csrf_token %}
<input class="form-control" type="text" autofocus="" required="" name="{{form.username.html_name}}" placeholder="Anmeldename" /> <input class="form-control" type="text" autofocus="" required="" name="{{form.username.html_name}}" placeholder="Anmeldename" />
+34
View File
@@ -0,0 +1,34 @@
{% extends "base.html" %}
{% load i18n static %}
{% load humanize %}
{% block head %}
<script type="text/javascript" src="{% static '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-12">
<h3>Wettbewerbe</h3>
{% for comp in competitions %}
{{ comp }}<br/>
{% endfor %}
<h3></h3>
</div>
</div>
{% if debug %}
<div class="row">
<div class="col-md-12">
<h2 class="form-signin-heading">{% trans 'Debug' %}</h2>
{% for line in debug %}
<p>{{ line }}</p>
{% endfor %}
</div>
</div>
{% endif %}
</div>
{% endblock %}
+2 -1
View File
@@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License
along with TipPy. If not, see <http://www.gnu.org/licenses/>. along with TipPy. If not, see <http://www.gnu.org/licenses/>.
""" """
from tipp.models import Team, Match, Tipp, Score, Mandant, RelUserMandant, Competition, Post, UserProfile from tipp.models import *
from django.contrib import admin from django.contrib import admin
class PostAdmin(admin.ModelAdmin): class PostAdmin(admin.ModelAdmin):
@@ -41,4 +41,5 @@ admin.site.register(Score)
admin.site.register(RelUserMandant) admin.site.register(RelUserMandant)
admin.site.register(Competition) admin.site.register(Competition)
admin.site.register(Post, PostAdmin) admin.site.register(Post, PostAdmin)
admin.site.register(RelPostMandant)
+18 -7
View File
@@ -22,32 +22,43 @@ from django import forms
from django.forms import ModelForm from django.forms import ModelForm
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.files.images import get_image_dimensions from django.core.files.images import get_image_dimensions
from tipp.models import Match, Competition, Post, UserProfile from tipp.models import Match, Competition, Post, UserProfile, \
Mandant, RelUserMandant
class NumberInput(forms.TextInput): class NumberInput(forms.TextInput):
input_type = 'number' input_type = 'number'
class TippForm(forms.Form): class TippForm(forms.Form):
tippTeam1 = forms.IntegerField(required=True,widget=NumberInput(attrs={ tippTeam1 = forms.IntegerField(required=True,widget=NumberInput(
attrs={
'cols': '2', 'cols': '2',
'min': '0', 'max': '99', 'step': '1', 'min': '0', 'max': '99', 'step': '1',
'class':'form-inline', 'class':'form-inline',
'role': 'form'} 'role': 'form'
}
)) ))
tippTeam2 = forms.IntegerField(required=True,widget=NumberInput(attrs={ tippTeam2 = forms.IntegerField(required=True,widget=NumberInput(
attrs={
'cols': '2', 'cols': '2',
'min': '0', 'max': '99', 'step': '1', 'min': '0', 'max': '99', 'step': '1',
'class':'form-inline', 'class':'form-inline',
'role': 'form'} 'role': 'form'
}
)) ))
tippTeam1.widget.attrs['style'] = "width:35px" tippTeam1.widget.attrs['style'] = "width:45px"
tippTeam2.widget.attrs['style'] = "width:35px" tippTeam2.widget.attrs['style'] = "width:45px"
class BlogpostForm(ModelForm): class BlogpostForm(ModelForm):
class Meta: class Meta:
model = Post model = Post
fields = ['content'] fields = ['content']
class MandantsForm(forms.Form):
mandants = forms.MultipleChoiceField(
label= "Posten in",
widget=forms.CheckboxSelectMultiple({'checked':'checked'})
)
class UserForm(forms.ModelForm): class UserForm(forms.ModelForm):
class Meta: class Meta:
model = User model = User
+146
View File
@@ -0,0 +1,146 @@
# Generated by Django 4.0.6 on 2022-07-14 15:15
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Competition',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('leagueShortcut', models.CharField(max_length=32)),
('leagueName', models.CharField(max_length=128)),
('season', models.CharField(max_length=4)),
],
),
migrations.CreateModel(
name='Mandant',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=32, unique=True)),
('description', models.CharField(max_length=255)),
],
),
migrations.CreateModel(
name='Post',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('content', models.TextField()),
('published', models.BooleanField(default=True)),
('created', models.DateTimeField(auto_now_add=True)),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'ordering': ['-created'],
},
),
migrations.CreateModel(
name='Team',
fields=[
('teamID', models.IntegerField(primary_key=True, serialize=False, unique=True)),
('name', models.CharField(max_length=200)),
('icon', models.FileField(upload_to='images/team_logos/')),
('abbr', models.CharField(max_length=3)),
('iconURL', models.CharField(max_length=2000)),
],
options={
'managed': True,
},
),
migrations.CreateModel(
name='UserProfile',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('avatar', models.ImageField(blank=True, upload_to='profiles/')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Score',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('exact_high', models.PositiveSmallIntegerField()),
('exact', models.PositiveSmallIntegerField()),
('diff', models.PositiveSmallIntegerField()),
('tendency', models.PositiveSmallIntegerField()),
('client', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tipp.mandant')),
],
),
migrations.CreateModel(
name='Match',
fields=[
('matchID', models.IntegerField(primary_key=True, serialize=False, unique=True)),
('matchDateTime', models.DateTimeField()),
('group', models.IntegerField()),
('matchday', models.IntegerField()),
('matchday_name', models.CharField(max_length=128)),
('pointsTeam1', models.SmallIntegerField()),
('pointsTeam2', models.SmallIntegerField()),
('finished', models.BooleanField()),
('season', models.CharField(max_length=4)),
('leagueShortcut', models.CharField(max_length=12)),
('idTeam1', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='tipp.team')),
('idTeam2', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='tipp.team')),
],
),
migrations.CreateModel(
name='Tipp',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('pointsTeam1', models.PositiveSmallIntegerField()),
('pointsTeam2', models.PositiveSmallIntegerField()),
('score', models.PositiveIntegerField(blank=True, null=True)),
('matchID', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tipp.match')),
('tipperID', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'unique_together': {('matchID', 'tipperID')},
},
),
migrations.CreateModel(
name='RelUserMandant',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('mandant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tipp.mandant')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'unique_together': {('user', 'mandant')},
},
),
migrations.CreateModel(
name='RelPostMandant',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('mandant', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tipp.mandant')),
('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tipp.post')),
],
options={
'unique_together': {('post', 'mandant')},
},
),
migrations.CreateModel(
name='chart',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('points', models.PositiveSmallIntegerField()),
('diff', models.SmallIntegerField()),
('games', models.PositiveSmallIntegerField()),
('competition', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tipp.competition')),
('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tipp.team')),
],
options={
'unique_together': {('team', 'competition')},
},
),
]
View File
+94 -24
View File
@@ -18,83 +18,126 @@ You should have received a copy of the GNU General Public License
along with TipPy. If not, see <http://www.gnu.org/licenses/>. along with TipPy. If not, see <http://www.gnu.org/licenses/>.
""" """
from django.db import models
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db import models
class UserProfile(models.Model): class UserProfile(models.Model):
user = models.OneToOneField(User) user = models.OneToOneField(
User,
on_delete=models.CASCADE
)
avatar = models.ImageField(upload_to="profiles/", blank=True) avatar = models.ImageField(upload_to="profiles/", blank=True)
def __unicode__(self): def __unicode__(self):
return self.user.username return self.user.username
class Competition(models.Model): class Competition(models.Model):
leagueShortcut = models.CharField(max_length=32) leagueShortcut = models.CharField(max_length=32)
leagueName = models.CharField(max_length=128) leagueName = models.CharField(max_length=128)
season = models.CharField(max_length=4) season = models.CharField(max_length=4)
class Meta:
unique_together = ("leagueShortcut", "season")
def __unicode__(self): def __unicode__(self):
return(self.leagueShortcut) return (self.leagueShortcut)
class Team(models.Model): class Team(models.Model):
teamID = models.IntegerField(unique=True, primary_key=True) teamID = models.IntegerField(unique=True, primary_key=True)
name = models.CharField(max_length=200) name = models.CharField(max_length=200)
icon = models.FileField(upload_to="images/team_logos/") icon = models.FileField(upload_to="images/team_logos/")
abbr = models.CharField(max_length=3) abbr = models.CharField(max_length=3)
iconURL = models.CharField(max_length=2000)
def __unicode__(self): def __unicode__(self):
return self.name return self.name
class Meta:
managed = True
app_label = 'tipp'
class Match(models.Model): class Match(models.Model):
matchID = models.IntegerField(unique=True,primary_key=True) matchID = models.IntegerField(unique=True, primary_key=True)
matchDateTime = models.DateTimeField() matchDateTime = models.DateTimeField()
group = models.IntegerField() group = models.IntegerField()
matchday = models.IntegerField() matchday = models.IntegerField()
idTeam1 = models.ForeignKey(Team, related_name='+') matchday_name = models.CharField(max_length=128)
idTeam2 = models.ForeignKey(Team, related_name='+')
competition = models.ForeignKey(
Competition,
on_delete=models.CASCADE
)
idTeam1 = models.ForeignKey(
Team, related_name='+',
on_delete=models.CASCADE
)
idTeam2 = models.ForeignKey(
Team, related_name='+',
on_delete=models.CASCADE
)
pointsTeam1 = models.SmallIntegerField() pointsTeam1 = models.SmallIntegerField()
pointsTeam2 = models.SmallIntegerField() pointsTeam2 = models.SmallIntegerField()
finished = models.BooleanField() finished = models.BooleanField()
season = models.CharField(max_length=4)
leagueShortcut = models.CharField(max_length=12)
def __unicode__(self): 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)) return (str(self.matchID))
class Tipp(models.Model): class Tipp(models.Model):
matchID = models.ForeignKey(Match) matchID = models.ForeignKey(
tipperID = models.ForeignKey(User) Match,
on_delete=models.CASCADE
)
tipperID = models.ForeignKey(
User,
on_delete=models.CASCADE
)
pointsTeam1 = models.PositiveSmallIntegerField() pointsTeam1 = models.PositiveSmallIntegerField()
pointsTeam2 = models.PositiveSmallIntegerField() pointsTeam2 = models.PositiveSmallIntegerField()
score = models.PositiveIntegerField(blank=True, null=True) score = models.PositiveIntegerField(
blank=True, null=True
)
class Meta: class Meta:
unique_together = ("matchID", "tipperID") unique_together = ("matchID", "tipperID")
class Mandant(models.Model): class Mandant(models.Model):
name = models.CharField(max_length=32, unique=True) name = models.CharField(max_length=32, unique=True)
description = models.CharField(max_length=255) description = models.CharField(max_length=255)
def __unicode__(self): def __unicode__(self):
return self.name return self.name
class Score(models.Model): class Score(models.Model):
client = models.ForeignKey(Mandant) client = models.ForeignKey(
Mandant,
on_delete=models.CASCADE
)
exact_high = models.PositiveSmallIntegerField() exact_high = models.PositiveSmallIntegerField()
exact = models.PositiveSmallIntegerField() exact = models.PositiveSmallIntegerField()
diff = models.PositiveSmallIntegerField() diff = models.PositiveSmallIntegerField()
tendency = models.PositiveSmallIntegerField() tendency = models.PositiveSmallIntegerField()
def __unicode__(self): def __unicode__(self):
return str(self.client) return str(self.client)
class chart(models.Model):
team = models.ForeignKey(Team) class Chart(models.Model):
competition = models.ForeignKey(Competition) team = models.ForeignKey(
Team,
on_delete=models.CASCADE
)
competition = models.ForeignKey(
Competition,
on_delete=models.CASCADE
)
points = models.PositiveSmallIntegerField() points = models.PositiveSmallIntegerField()
diff = models.SmallIntegerField() diff = models.SmallIntegerField()
games = models.PositiveSmallIntegerField() games = models.PositiveSmallIntegerField()
@@ -102,20 +145,32 @@ class chart(models.Model):
class Meta: class Meta:
unique_together = ("team", "competition") unique_together = ("team", "competition")
class RelUserMandant(models.Model): class RelUserMandant(models.Model):
user = models.ForeignKey(User) user = models.ForeignKey(
mandant = models.ForeignKey(Mandant) User,
on_delete=models.CASCADE
)
mandant = models.ForeignKey(
Mandant,
on_delete=models.CASCADE
)
class Meta: class Meta:
unique_together = ("user", "mandant") unique_together = ("user", "mandant")
def __unicode__(self): def __unicode__(self):
return (str(self.user) + " -> " + str(self.mandant)) return (str(self.user) + " -> " + str(self.mandant))
class Post(models.Model): class Post(models.Model):
content = models.TextField() content = models.TextField()
published = models.BooleanField(default=True) published = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(User) author = models.ForeignKey(
User,
on_delete=models.CASCADE
)
class Meta: class Meta:
ordering = ['-created'] ordering = ['-created']
@@ -124,3 +179,18 @@ class Post(models.Model):
return u'%s' % self.created return u'%s' % self.created
class RelPostMandant(models.Model):
post = models.ForeignKey(
Post,
on_delete=models.CASCADE
)
mandant = models.ForeignKey(
Mandant,
on_delete=models.CASCADE
)
class Meta:
unique_together = ("post", "mandant")
def __unicode__(self):
return (str(self.post) + " -> " + str(self.mandant))
Executable → Regular
+32 -17
View File
@@ -18,7 +18,15 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with TipPy. If not, see <http://www.gnu.org/licenses/>. # along with TipPy. If not, see <http://www.gnu.org/licenses/>.
# #
import sys, locale, suds, urllib2, psycopg2 import locale
import urllib.error
import urllib.parse
import urllib.request
from zeep import Client
from zeep.transports import Transport
from requests import Session
class OpenLiga(object): class OpenLiga(object):
version = "0.1" version = "0.1"
@@ -34,37 +42,44 @@ class OpenLiga(object):
self.debug = debug self.debug = debug
# get a SUDS client object # get a SOAP client object
if self.proxyurl is None: wsdl_url = 'http://www.openligadb.de/Webservices/Sportsdata.asmx?WSDL'
try: try:
self.client = suds.client.Client('http://www.openligadb.de/Webservices/Sportsdata.asmx?WSDL') if proxyurl is None:
except (urllib2.URLError): self.client = Client(wsdl=wsdl_url)
self.error += "Connect to webservice failed."
else: else:
try: session = Session()
t = suds.transport.http.HttpTransport() session.proxies = {'http': proxyurl, 'https': proxyurl}
proxy = urllib2.ProxyHandler({'http':proxyurl}) transport = Transport(session=session)
opener = urllib2.build_opener(proxy) self.client = Client(wsdl=wsdl_url, transport=transport)
t.urlopener = opener except (urllib.error.URLError, Exception) as e:
self.client = suds.client.Client('http://www.openligadb.de/Webservices/Sportsdata.asmx?WSDL', transport=t) self.error += f"Connect to webservice failed: {str(e)}\n"
except urllib2.URLError as e:
self.error += "Connect to webservice failed (via proxy " + proxyurl + "): " + str(e) + "\n"
def getSeason(self, season, league='bl1'): def getSeason(self, season, league='bl1'):
""" Get the whole season. """ Get the whole season.
Args: season and league shortcut (optional) Args: season and league shortcut (optional)
""" """
return(self.client.service.GetMatchdataByLeagueSaison(leagueShortcut=league,leagueSaison=season)) return self.client.service.GetMatchdataByLeagueSaison(
leagueShortcut=league, leagueSaison=season)
def getMatchday(self, season, matchdaynumber, league='bl1'): def getMatchday(self, season, matchdaynumber, league='bl1'):
""" Get matchday. """ Get matchday.
Args: season, matchdaynumber and league shortcut (optional) Args: season, matchdaynumber and league shortcut (optional)
""" """
return(self.client.service.GetMatchdataByGroupLeagueSaison(groupOrderID=matchdaynumber,leagueShortcut=league,leagueSaison=season)) return self.client.service.GetMatchdataByGroupLeagueSaison(
groupOrderID=matchdaynumber,
leagueShortcut=league,
leagueSaison=season)
def getTeams(self, season, league='bl1'): def getTeams(self, season, league='bl1'):
return(self.client.service.GetTeamsByLeagueSaison(leagueShortcut=league,leagueSaison=season)) return self.client.service.GetTeamsByLeagueSaison(
leagueShortcut=league,
leagueSaison=season)
def getCurrentGroup(self, league):
return self.client.service.GetCurrentGroup(
leagueShortcut=league)
+2 -2
View File
@@ -1,6 +1,6 @@
""" """
This file demonstrates writing tests using the unittest module. These will pass This file demonstrates writing tests using the unittest module.
when you run "manage.py test". These will pass when you run "manage.py test".
Replace this with more appropriate tests for your application. Replace this with more appropriate tests for your application.
""" """
+33
View File
@@ -0,0 +1,33 @@
from django.contrib.auth import views as auth_views
from django.urls import re_path
from django.conf.urls import include
from django.conf import settings
from django.conf.urls.static import static
from . import views
urlpatterns = [
re_path(r'^$', views.home, name='home'),
re_path(r'^getSeason/(?P<ls>.*)/(?P<season>\d{4})$',
views.getSeason),
re_path(r'^update/(?P<ls>.*)/(?P<season>\d{4})/(?P<cur_md>\d{2})$',
views.update, name='update'),
re_path(r'^matchday/(?P<ls>.{3,})/(?P<season>\d{4})/(?P<matchday>\d{2})$',
views.matchday, name='matchday'),
re_path(r'^charts/(?P<ls>\w{3,})/(?P<season>\d{4})$', views.charts,
name='charts'),
re_path(r'^charts/(?P<ls>\w{3,})/(?P<season>\d{4})/(?P<pos>\w{1,})$',
views.charts, name='charts'),
re_path(r'^accounts/profile/(\d+)', views.profile),
re_path(r'^accounts/', include('django.contrib.auth.urls')),
re_path(r'^blog/newpost$', views.newBlogpost),
re_path(r'^blog/(?P<page>\d)$', views.blogindex),
re_path(r'^about$', views.about),
re_path(r'^staff', views.staff),
re_path(r'^accounts/login/', auth_views.LoginView.as_view()),
re_path(r'^accounts/logout/', auth_views.LogoutView.as_view())
]
# Redirect on logout
LOGOUT_REDIRECT_URL = "home"
if settings.DEBUG is True:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
+627 -331
View File
File diff suppressed because it is too large Load Diff
-188
View File
@@ -1,188 +0,0 @@
"""
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 = '/home/martin/dev/tippy/TipPy/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
# 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.
'/home/martin/dev/tippy/TipPy/tippy/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&amp;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'
-36
View File
@@ -1,36 +0,0 @@
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'),
# 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
View File
@@ -1,28 +0,0 @@
"""
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)