Diverse Code Cleanups
*Code wurde PEP-8 gerecht formatiert * Kleine Fehler die der PyCharm Inspector beanstandet wurden korrigiert
This commit is contained in:
committed by
Christian Berg
parent
f34281089d
commit
86a0db050d
4
.idea/kasu.iml
generated
4
.idea/kasu.iml
generated
@@ -3,8 +3,8 @@
|
|||||||
<component name="FacetManager">
|
<component name="FacetManager">
|
||||||
<facet type="django" name="Django">
|
<facet type="django" name="Django">
|
||||||
<configuration>
|
<configuration>
|
||||||
<option name="rootFolder" value="$MODULE_DIR$/src" />
|
<option name="rootFolder" value="$MODULE_DIR$" />
|
||||||
<option name="settingsModule" value="settings.py" />
|
<option name="settingsModule" value="kasu/settings/dev.py" />
|
||||||
<option name="manageScript" value="manage.py" />
|
<option name="manageScript" value="manage.py" />
|
||||||
<option name="environment" value="<map/>" />
|
<option name="environment" value="<map/>" />
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from models import Feed, FeedItem
|
from models import Feed, FeedItem
|
||||||
|
|
||||||
admin.site.register(Feed,
|
admin.site.register(
|
||||||
|
Feed,
|
||||||
list_display=["title", "public_url", "last_update", 'is_functional'],
|
list_display=["title", "public_url", "last_update", 'is_functional'],
|
||||||
list_filter=["is_functional"],
|
list_filter=["is_functional"],
|
||||||
ordering=["title"],
|
ordering=["title"],
|
||||||
@@ -9,7 +10,8 @@ admin.site.register(Feed,
|
|||||||
list_per_page=500,
|
list_per_page=500,
|
||||||
)
|
)
|
||||||
|
|
||||||
admin.site.register(FeedItem,
|
admin.site.register(
|
||||||
|
FeedItem,
|
||||||
list_display=['title', 'feed', 'date_modified'],
|
list_display=['title', 'feed', 'date_modified'],
|
||||||
list_filter=['feed'],
|
list_filter=['feed'],
|
||||||
search_fields=['feed__title', 'feed__public_url', 'title'],
|
search_fields=['feed__title', 'feed__public_url', 'title'],
|
||||||
|
|||||||
@@ -2,12 +2,13 @@ import django.contrib.syndication.views
|
|||||||
from .models import FeedItem
|
from .models import FeedItem
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyMethodMayBeStatic
|
||||||
class LatestFeedItems(django.contrib.syndication.views.Feed):
|
class LatestFeedItems(django.contrib.syndication.views.Feed):
|
||||||
link = "http://aol.animanga.at/"
|
link = "http://aol.animanga.at/"
|
||||||
description = "Aktuelle Nachrichten aus der Austrian Otaku League"
|
description = "Aktuelle Nachrichten aus der Austrian Otaku League"
|
||||||
title = "AOL - Newsfeed"
|
title = "AOL - Newsfeed"
|
||||||
|
|
||||||
def items(self, obj):
|
def items(self):
|
||||||
return FeedItem.objects.get_recent_items()
|
return FeedItem.objects.get_recent_items()
|
||||||
|
|
||||||
def item_title(self, item):
|
def item_title(self, item):
|
||||||
|
|||||||
@@ -6,53 +6,14 @@ Universal Feed Parser (http://feedparser.org)
|
|||||||
from aggregator.models import Feed
|
from aggregator.models import Feed
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = "Updates all RSS Feeds"
|
help = "Updates all RSS Feeds"
|
||||||
|
|
||||||
def parse_feed(self, feed, verbose=True):
|
|
||||||
parsed_feed = feedparser.parse(feed.feed_url)
|
|
||||||
html_parser = HTMLParser.HTMLParser()
|
|
||||||
for entry in parsed_feed:
|
|
||||||
title = entry.title.encode(parsed_feed.encoding, "xmlcharrefreplace")
|
|
||||||
guid = entry.get("id", entry.link).encode(parsed_feed.encoding, "xmlcharrefreplace")
|
|
||||||
link = entry.link.encode(parsed_feed.encoding, "xmlcharrefreplace")
|
|
||||||
if verbose:
|
|
||||||
print '>' , title
|
|
||||||
|
|
||||||
if not guid:
|
|
||||||
guid = link
|
|
||||||
|
|
||||||
if hasattr(entry, "summary"):
|
|
||||||
content = entry.summary
|
|
||||||
elif hasattr(entry, "content"):
|
|
||||||
content = entry.content[0].value
|
|
||||||
elif hasattr(entry, "description"):
|
|
||||||
content = entry.description
|
|
||||||
else:
|
|
||||||
content = u""
|
|
||||||
content = content.encode(parsed_feed.encoding, "xmlcharrefreplace")
|
|
||||||
|
|
||||||
try:
|
|
||||||
if entry.has_key('modified_parsed'):
|
|
||||||
date_modified = datetime.fromtimestamp(time.mktime(entry.modified_parsed))
|
|
||||||
elif parsed_feed.feed.has_key('modified_parsed'):
|
|
||||||
date_modified = datetime.fromtimestamp(time.mktime(parsed_feed.feed.modified_parsed))
|
|
||||||
elif parsed_feed.has_key('modified'):
|
|
||||||
date_modified = datetime.fromtimestamp(time.mktime(parsed_feed.modified))
|
|
||||||
else:
|
|
||||||
date_modified = datetime.now()
|
|
||||||
except TypeError:
|
|
||||||
date_modified = datetime.now()
|
|
||||||
|
|
||||||
try:
|
|
||||||
feed.feeditem_set.get(guid=guid)
|
|
||||||
except FeedItem.DoesNotExist:
|
|
||||||
feed.feeditem_set.create(title=title, link=link, summary=content, guid=guid, date_modified=date_modified)
|
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
verbose = int(options['verbosity']) > 0
|
verbose = int(options['verbosity']) > 0
|
||||||
for feed in Feed.objects.filter(is_functional=True):
|
for feed in Feed.objects.filter(is_functional=True):
|
||||||
if (verbose):
|
if verbose:
|
||||||
print
|
print
|
||||||
print "%s - URL: %s" % (feed.title, feed.feed_url)
|
print "%s - URL: %s" % (feed.title, feed.feed_url)
|
||||||
print '=' * 80
|
print '=' * 80
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 05.02.2011
|
Created on 05.02.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@@ -14,8 +14,8 @@ import django.db.models
|
|||||||
import feedparser
|
import feedparser
|
||||||
import urllib2
|
import urllib2
|
||||||
|
|
||||||
class FeedManager(django.db.models.Manager):
|
|
||||||
|
|
||||||
|
class FeedManager(django.db.models.Manager):
|
||||||
def active(self):
|
def active(self):
|
||||||
site = settings.SITE_ID
|
site = settings.SITE_ID
|
||||||
feeds = self.filter(is_functional=True, site=site)
|
feeds = self.filter(is_functional=True, site=site)
|
||||||
@@ -28,12 +28,13 @@ class FeedManager(django.db.models.Manager):
|
|||||||
feed.parse()
|
feed.parse()
|
||||||
return feeds
|
return feeds
|
||||||
|
|
||||||
class FeedItemManager(django.db.models.Manager):
|
|
||||||
|
|
||||||
|
class FeedItemManager(django.db.models.Manager):
|
||||||
def recent_items(self, max_items=10, site=None):
|
def recent_items(self, max_items=10, site=None):
|
||||||
site = site or settings.SITE_ID
|
site = site or settings.SITE_ID
|
||||||
return self.select_related().filter(feed__site=site)[:max_items]
|
return self.select_related().filter(feed__site=site)[:max_items]
|
||||||
|
|
||||||
|
|
||||||
class Feed(models.Model):
|
class Feed(models.Model):
|
||||||
title = models.CharField(max_length=500)
|
title = models.CharField(max_length=500)
|
||||||
site = models.ForeignKey(Site)
|
site = models.ForeignKey(Site)
|
||||||
@@ -61,9 +62,12 @@ class Feed(models.Model):
|
|||||||
|
|
||||||
link = feed_entry.link
|
link = feed_entry.link
|
||||||
guid = feed_entry.get("id", link)
|
guid = feed_entry.get("id", link)
|
||||||
summary = html_parser.unescape(feed_entry.get("summary",
|
summary = html_parser.unescape(
|
||||||
feed_entry.get("description", feed_entry.get("content", u""))
|
feed_entry.get("summary", feed_entry.get(
|
||||||
|
"description",
|
||||||
|
feed_entry.get("content", u"")
|
||||||
))
|
))
|
||||||
|
)
|
||||||
date_modified = feed_entry.get("published_parsed", parsed_feed.get("published_parsed", timezone.now))
|
date_modified = feed_entry.get("published_parsed", parsed_feed.get("published_parsed", timezone.now))
|
||||||
date_modified = timezone.make_aware(datetime(*date_modified[:6]), timezone.get_current_timezone())
|
date_modified = timezone.make_aware(datetime(*date_modified[:6]), timezone.get_current_timezone())
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from django.contrib.sitemaps import Sitemap
|
from django.contrib.sitemaps import Sitemap
|
||||||
from models import FeedItem
|
from models import FeedItem
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyMethodMayBeStatic
|
||||||
class FeedItemSitemap(Sitemap):
|
class FeedItemSitemap(Sitemap):
|
||||||
changefreq = "never"
|
changefreq = "never"
|
||||||
priority = 0.5
|
priority = 0.5
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from django import template
|
from django import template
|
||||||
from aggregator.models import Feed
|
from models import Feed
|
||||||
|
|
||||||
|
|
||||||
class FeedListNode(template.Node):
|
class FeedListNode(template.Node):
|
||||||
@@ -12,6 +12,7 @@ class FeedListNode(template.Node):
|
|||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
def do_get_feed_list(parser, token):
|
def do_get_feed_list(parser, token):
|
||||||
"""
|
"""
|
||||||
{% get_feed_list as feed_list %}
|
{% get_feed_list as feed_list %}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 19.09.2011
|
Created on 19.09.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
# import stuff we need from django
|
# import stuff we need from django
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from . import models
|
from . import models
|
||||||
@@ -44,17 +44,20 @@ class PageAdmin(admin.ModelAdmin):
|
|||||||
'classes': ('collapse', 'closed'),
|
'classes': ('collapse', 'closed'),
|
||||||
}),
|
}),
|
||||||
('Meta Data', {
|
('Meta Data', {
|
||||||
'fields': ('content_type', 'slug', ('parent', 'position'),
|
'fields': (
|
||||||
'status', 'template',)
|
'content_type', 'slug', ('parent', 'position'),
|
||||||
|
'status', 'template',
|
||||||
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
class Media:
|
class Media(object):
|
||||||
js = [
|
js = [
|
||||||
'/static/js/tiny_mce/tiny_mce.js',
|
'/static/js/tiny_mce/tiny_mce.js',
|
||||||
'/static/js/tinymce_setup.js',
|
'/static/js/tinymce_setup.js',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(models.Article, ArticleAdmin)
|
admin.site.register(models.Article, ArticleAdmin)
|
||||||
admin.site.register(models.Page, PageAdmin)
|
admin.site.register(models.Page, PageAdmin)
|
||||||
admin.site.register(models.Category, CategoryAdmin)
|
admin.site.register(models.Category, CategoryAdmin)
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
# -*- encoding: UTF-8 -*-
|
# -*- encoding: UTF-8 -*-
|
||||||
'''
|
"""
|
||||||
Created on 30.09.2011
|
Created on 30.09.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from . import models
|
from . import models
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ def content_menus(request):
|
|||||||
# erzeuge das Top-Level Menü
|
# erzeuge das Top-Level Menü
|
||||||
top_menu_items = []
|
top_menu_items = []
|
||||||
top_level_pages = cache.get('top_level_pages')
|
top_level_pages = cache.get('top_level_pages')
|
||||||
if top_level_pages == None:
|
if top_level_pages is None:
|
||||||
top_level_pages = models.Page.objects.filter(parent=None)
|
top_level_pages = models.Page.objects.filter(parent=None)
|
||||||
top_level_pages = top_level_pages.exclude(slug='index')
|
top_level_pages = top_level_pages.exclude(slug='index')
|
||||||
top_level_pages = top_level_pages.order_by('position')
|
top_level_pages = top_level_pages.order_by('position')
|
||||||
@@ -31,7 +31,7 @@ def content_menus(request):
|
|||||||
|
|
||||||
# Entdecke die aktuell geöffnete Seite
|
# Entdecke die aktuell geöffnete Seite
|
||||||
all_pages = cache.get('all_pages')
|
all_pages = cache.get('all_pages')
|
||||||
if all_pages == None:
|
if all_pages is None:
|
||||||
all_pages = models.Page.objects.values_list('path', 'id')
|
all_pages = models.Page.objects.values_list('path', 'id')
|
||||||
all_pages = dict((path, page_id) for path, page_id in all_pages)
|
all_pages = dict((path, page_id) for path, page_id in all_pages)
|
||||||
cache.set('all_pages', all_pages, 360)
|
cache.set('all_pages', all_pages, 360)
|
||||||
|
|||||||
@@ -7,13 +7,14 @@ from django.utils.feedgenerator import Rss201rev2Feed
|
|||||||
from models import Article
|
from models import Article
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyMethodMayBeStatic
|
||||||
class LatestNews(Feed):
|
class LatestNews(Feed):
|
||||||
link = "http://www.kasu.at/"
|
link = "http://www.kasu.at/"
|
||||||
description = _("Current news from Kasu")
|
description = _("Current news from Kasu")
|
||||||
title = "Kasu - traditonelle asiatische Spielkultur"
|
title = "Kasu - traditonelle asiatische Spielkultur"
|
||||||
feed_type = Rss201rev2Feed
|
feed_type = Rss201rev2Feed
|
||||||
|
|
||||||
def items(self, obj):
|
def items(self):
|
||||||
return Article.objects.published()[:10]
|
return Article.objects.published()[:10]
|
||||||
|
|
||||||
def item_title(self, item):
|
def item_title(self, item):
|
||||||
@@ -23,7 +24,7 @@ class LatestNews(Feed):
|
|||||||
return item.author.username
|
return item.author.username
|
||||||
|
|
||||||
def item_categories(self, item):
|
def item_categories(self, item):
|
||||||
return (item.category.name,)
|
return item.category.name,
|
||||||
|
|
||||||
def item_description(self, item):
|
def item_description(self, item):
|
||||||
return item.content
|
return item.content
|
||||||
@@ -32,6 +33,7 @@ class LatestNews(Feed):
|
|||||||
return datetime.combine(item.date_created, time())
|
return datetime.combine(item.date_created, time())
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyMethodMayBeStatic
|
||||||
class LatestComments(Feed):
|
class LatestComments(Feed):
|
||||||
"""Feed of latest comments on the current site."""
|
"""Feed of latest comments on the current site."""
|
||||||
|
|
||||||
@@ -41,8 +43,10 @@ class LatestComments(Feed):
|
|||||||
feed_type = Rss201rev2Feed
|
feed_type = Rss201rev2Feed
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
qs = comments.get_model().objects.filter(site__pk=settings.SITE_ID,
|
qs = comments.get_model().objects.filter(
|
||||||
is_public=True, is_removed=False)
|
site__pk=settings.SITE_ID,
|
||||||
|
is_public=True, is_removed=False
|
||||||
|
)
|
||||||
return qs.order_by('-submit_date')[:40]
|
return qs.order_by('-submit_date')[:40]
|
||||||
|
|
||||||
def item_author_name(self, item):
|
def item_author_name(self, item):
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 04.10.2011
|
Created on 04.10.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
import django.forms
|
import django.forms
|
||||||
from django.template.defaultfilters import slugify
|
from django.template.defaultfilters import slugify
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
@@ -17,8 +17,12 @@ class ArticleForm(forms.ModelForm):
|
|||||||
required_css_class = 'required'
|
required_css_class = 'required'
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
fields = ('headline_de', 'content_de', 'headline_en', 'content_en',
|
fields = (
|
||||||
'category', 'image')
|
'headline_de', 'content_de',
|
||||||
|
'headline_en', 'content_en',
|
||||||
|
'category',
|
||||||
|
'image'
|
||||||
|
)
|
||||||
model = models.Article
|
model = models.Article
|
||||||
|
|
||||||
def save(self, force_insert=False, force_update=False, commit=True):
|
def save(self, force_insert=False, force_update=False, commit=True):
|
||||||
|
|||||||
@@ -1,21 +1,26 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from content.models import Article, Category
|
import re
|
||||||
from django.contrib.auth.models import User
|
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.template.defaultfilters import slugify
|
from django.template.defaultfilters import slugify
|
||||||
from django.utils.datetime_safe import datetime
|
from django.utils.datetime_safe import datetime
|
||||||
import re
|
|
||||||
import xlrd #@UnresolvedImport
|
|
||||||
|
|
||||||
|
from content.models import Article, Category
|
||||||
|
import xlrd
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyPep8
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = "Importiert die alten Daten aus einer CSV Datei" # @ReservedAssignment
|
help = "Importiert die alten Daten aus einer CSV Datei" # @ReservedAssignment
|
||||||
date_header_regex = r"""<h1><span class=\"small\">(?P<date>[\d\.]*)[\ -]*</span>[\ -]*(?P<title>.*)</h1>(?P<content>.*)"""
|
date_header_regex = r"""<h1><span class=\"small\">(?P<date>[\d\.]*)[\ -]*</span>[\ -]*(?P<title>.*)</h1>(?P<content>.*)"""
|
||||||
header_regex = r"""<h1>[\ -]*(?P<title>.*)</h1>(?P<content>.*)"""
|
header_regex = r"""<h1>[\ -]*(?P<title>.*)</h1>(?P<content>.*)"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.author = User.objects.get(username="xeniac")
|
self.author = get_user_model().objects.get(username="xeniac")
|
||||||
self.category = Category.objects.get(slug='allgemeines')
|
self.category = Category.objects.get(slug='allgemeines')
|
||||||
|
super(Command, self).__init__()
|
||||||
|
|
||||||
def create_article(self):
|
def create_article(self):
|
||||||
self.slug = slugify(self.headline[:50])
|
self.slug = slugify(self.headline[:50])
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth import get_user_model
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.utils.datetime_safe import datetime
|
from django.utils.datetime_safe import datetime
|
||||||
from events.models import Event, Location
|
from events.models import Event, Location
|
||||||
import xlrd # @UnresolvedImport
|
import xlrd
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = "Importiert die alten Events" # @ReservedAssignment
|
help = "Importiert die alten Events" # @ReservedAssignment
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.author = User.objects.get(username="xeniac")
|
self.author = get_user_model().objects.get(username="xeniac")
|
||||||
|
super(Command, self).__init__()
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
try:
|
try:
|
||||||
@@ -22,7 +23,6 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
table = xls_file.sheet_by_index(0)
|
table = xls_file.sheet_by_index(0)
|
||||||
for row in xrange(1, table.nrows):
|
for row in xrange(1, table.nrows):
|
||||||
|
|
||||||
name = table.cell_value(row, 0)
|
name = table.cell_value(row, 0)
|
||||||
print name
|
print name
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
@@ -9,10 +11,12 @@ from django.utils.safestring import mark_safe
|
|||||||
from django.utils.translation import get_language, ugettext as _
|
from django.utils.translation import get_language, ugettext as _
|
||||||
from imagekit.models import ImageSpecField
|
from imagekit.models import ImageSpecField
|
||||||
from imagekit.processors import SmartResize
|
from imagekit.processors import SmartResize
|
||||||
from utils import STATUS_CHOICES, STATUS_WAITING, STATUS_PUBLISHED, \
|
|
||||||
STATUS_REJECTED, cleaner, OverwriteStorage # @UnusedImport
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
|
from utils import STATUS_CHOICES, STATUS_WAITING, STATUS_PUBLISHED, \
|
||||||
|
cleaner
|
||||||
|
|
||||||
|
|
||||||
CONTENT_CHOICES = (
|
CONTENT_CHOICES = (
|
||||||
(0, u'Django View'),
|
(0, u'Django View'),
|
||||||
(1, u'HTML'),
|
(1, u'HTML'),
|
||||||
@@ -21,7 +25,7 @@ CONTENT_CHOICES = (
|
|||||||
|
|
||||||
|
|
||||||
def get_upload_path(instance, filename):
|
def get_upload_path(instance, filename):
|
||||||
'''
|
"""
|
||||||
Generates the desired file path and filename for an uploaded Image.
|
Generates the desired file path and filename for an uploaded Image.
|
||||||
With this function Django can save the uploaded images to subfolders that
|
With this function Django can save the uploaded images to subfolders that
|
||||||
also have a meaning for humans.
|
also have a meaning for humans.
|
||||||
@@ -30,7 +34,7 @@ def get_upload_path(instance, filename):
|
|||||||
@type instance: a instace of an models.Model sub-class.
|
@type instance: a instace of an models.Model sub-class.
|
||||||
@param filename: The filename of the uploaded image.
|
@param filename: The filename of the uploaded image.
|
||||||
@type filename: String
|
@type filename: String
|
||||||
'''
|
"""
|
||||||
extension = filename[filename.rfind('.') + 1:]
|
extension = filename[filename.rfind('.') + 1:]
|
||||||
if isinstance(instance, Category):
|
if isinstance(instance, Category):
|
||||||
return "categories/%s.%s" % (instance.slug, extension)
|
return "categories/%s.%s" % (instance.slug, extension)
|
||||||
@@ -61,7 +65,7 @@ class Article(ImageModel):
|
|||||||
image = models.ImageField(_('Image'), upload_to='news/',
|
image = models.ImageField(_('Image'), upload_to='news/',
|
||||||
blank=True, null=True)
|
blank=True, null=True)
|
||||||
slug = models.SlugField(_('Slug'), unique_for_month='date_created')
|
slug = models.SlugField(_('Slug'), unique_for_month='date_created')
|
||||||
author = models.ForeignKey('auth.User', verbose_name=_('Author'))
|
author = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('Author'))
|
||||||
status = models.SmallIntegerField(_('Status'), choices=STATUS_CHOICES,
|
status = models.SmallIntegerField(_('Status'), choices=STATUS_CHOICES,
|
||||||
default=STATUS_PUBLISHED)
|
default=STATUS_PUBLISHED)
|
||||||
date_created = models.DateField(_('Created'), blank=True)
|
date_created = models.DateField(_('Created'), blank=True)
|
||||||
@@ -117,13 +121,13 @@ class Article(ImageModel):
|
|||||||
|
|
||||||
|
|
||||||
class Page(models.Model):
|
class Page(models.Model):
|
||||||
'''
|
"""
|
||||||
Eine Seite auf der Homepage. Sie kann eine "statische" HTML Seite,
|
Eine Seite auf der Homepage. Sie kann eine "statische" HTML Seite,
|
||||||
die URL einer dynamische Django View, oder ein PDF Dokument sein.
|
die URL einer dynamische Django View, oder ein PDF Dokument sein.
|
||||||
Jede Seite kann neben Deutsch auch auf Englisch angeboten werden.
|
Jede Seite kann neben Deutsch auch auf Englisch angeboten werden.
|
||||||
Ist keine englische Übersetzung vorhanden, wird die deutsche Version
|
Ist keine englische Übersetzung vorhanden, wird die deutsche Version
|
||||||
angeboten.
|
angeboten.
|
||||||
'''
|
"""
|
||||||
menu_name_de = models.CharField(
|
menu_name_de = models.CharField(
|
||||||
'Menü Name',
|
'Menü Name',
|
||||||
max_length=255,
|
max_length=255,
|
||||||
@@ -164,8 +168,8 @@ class Page(models.Model):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def content(self):
|
def content(self):
|
||||||
return mark_safe(getattr(self, "content_%s" % get_language()) or \
|
cont = getattr(self, "content_%s" % get_language()) or self.content_de
|
||||||
self.content_de)
|
return mark_safe(cont)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def css_class(self):
|
def css_class(self):
|
||||||
@@ -173,8 +177,8 @@ class Page(models.Model):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def menu_name(self):
|
def menu_name(self):
|
||||||
return getattr(self, "menu_name_%s" % get_language()) or \
|
return getattr(self,
|
||||||
self.menu_name_de
|
"menu_name_%s" % get_language()) or self.menu_name_de
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pdf_file(self):
|
def pdf_file(self):
|
||||||
@@ -185,12 +189,12 @@ class Page(models.Model):
|
|||||||
return getattr(self, "title_%s" % get_language()) or self.title_de
|
return getattr(self, "title_%s" % get_language()) or self.title_de
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
if self.parent == None:
|
if self.parent is None:
|
||||||
self.path = self.slug
|
self.path = self.slug
|
||||||
else:
|
else:
|
||||||
self.path = path.join(self.parent.path, self.slug)
|
self.path = path.join(self.parent.path, self.slug)
|
||||||
|
|
||||||
if self.content_type == None:
|
if self.content_type is None:
|
||||||
if self.pdf_de:
|
if self.pdf_de:
|
||||||
self.content_type = 2
|
self.content_type = 2
|
||||||
if self.content_de:
|
if self.content_de:
|
||||||
@@ -205,14 +209,14 @@ class Page(models.Model):
|
|||||||
_(u'Please upload a PDF-File to this PDF-Page.'))
|
_(u'Please upload a PDF-File to this PDF-Page.'))
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
path = '/' + self.path
|
aboslute_url = '/' + self.path
|
||||||
if self.content_type == 1:
|
if self.content_type == 1:
|
||||||
path += '.html'
|
aboslute_url += '.html'
|
||||||
elif self.content_type == 2:
|
elif self.content_type == 2:
|
||||||
path += '.pdf'
|
aboslute_url += '.pdf'
|
||||||
else:
|
else:
|
||||||
path += '/'
|
aboslute_url += '/'
|
||||||
return path
|
return aboslute_url
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
ordering = ['parent__id', 'position']
|
ordering = ['parent__id', 'position']
|
||||||
@@ -258,5 +262,6 @@ def force_cache_update(sender, instance, **kwargs):
|
|||||||
cache.delete('all_pages')
|
cache.delete('all_pages')
|
||||||
cache.delete('top_level_pages')
|
cache.delete('top_level_pages')
|
||||||
|
|
||||||
|
|
||||||
models.signals.post_delete.connect(force_cache_update, sender=Page)
|
models.signals.post_delete.connect(force_cache_update, sender=Page)
|
||||||
models.signals.post_save.connect(force_cache_update, sender=Page)
|
models.signals.post_save.connect(force_cache_update, sender=Page)
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
from imagekit.specs import ImageSpec
|
from imagekit.specs import ImageSpec
|
||||||
from imagekit import processors
|
from imagekit import processors
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyPep8
|
||||||
class ResizeArticle(processors.Resize):
|
class ResizeArticle(processors.Resize):
|
||||||
width = 210
|
width = 210
|
||||||
height = 130
|
height = 130
|
||||||
crop = True
|
crop = True
|
||||||
|
|
||||||
|
|
||||||
class Article(ImageSpec):
|
class Article(ImageSpec):
|
||||||
pre_cache = True
|
pre_cache = True
|
||||||
processors = [ResizeArticle]
|
processors = [ResizeArticle]
|
||||||
@@ -45,11 +45,11 @@
|
|||||||
<ul class="list" style="margin: 20px;">
|
<ul class="list" style="margin: 20px;">
|
||||||
{% if active_category %}
|
{% if active_category %}
|
||||||
{% for date in date_list %}
|
{% for date in date_list %}
|
||||||
<li class="date"><a href="{% url "article-archive" category=active_category.slug year=date|date:'Y' %}">{{active_category.name}}: {{ date|date:'Y' }}</a></li>
|
<li class="date"><a href="{% url 'article-archive' category=active_category.slug year=date|date:'Y' %}">{{active_category.name}}: {{ date|date:'Y' }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% for date in date_list %}
|
{% for date in date_list %}
|
||||||
<li class="date"><a href="{% url "article-archive" year=date|date:'Y' %}">{{ date|date:'Y' }}</a></li>
|
<li class="date"><a href="{% url 'article-archive' year=date|date:'Y' %}">{{ date|date:'Y' }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
<article class="article">
|
<article class="article">
|
||||||
<h3><a href="{{article.get_absolute_url}}">{{article.headline}}</a></h3>
|
<h3><a href="{{article.get_absolute_url}}">{{article.headline}}</a></h3>
|
||||||
<ul class="info">
|
<ul class="info">
|
||||||
<li><img src="{{STATIC_URL}}icons/calendar.png" alt="{% trans 'created on' %}:" title="{% trans 'created on' %}"/> <time datetime="{{article.date_created|date:"c"}}">{{ article.date_created|date }}</time></li>
|
<li><img src="{{STATIC_URL}}icons/calendar.png" alt="{% trans 'created on' %}:" title="{% trans 'created on' %}"/> <time datetime="{{article.date_created|date:'c'}}">{{ article.date_created|date }}</time></li>
|
||||||
<li><img src="{{STATIC_URL}}icons/user_red.png" alt="{% trans 'by' %}:" title="{% trans 'by' %}"/> <span class="author">{{ article.author }}</span></li>
|
<li><img src="{{STATIC_URL}}icons/user_red.png" alt="{% trans 'by' %}:" title="{% trans 'by' %}"/> <span class="author">{{ article.author }}</span></li>
|
||||||
<li><img src="{{STATIC_URL}}icons/comments.png" alt="{% trans 'comments' %}:" title="{% trans 'comments' %}"/> <a href="{{article.get_absolute_url}}#comments" >{{comment_count}} {% trans "comments" %}</a></li>
|
<li><img src="{{STATIC_URL}}icons/comments.png" alt="{% trans 'comments' %}:" title="{% trans 'comments' %}"/> <a href="{{article.get_absolute_url}}#comments" >{{comment_count}} {% trans "comments" %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -89,6 +89,6 @@
|
|||||||
|
|
||||||
{% block additional_buttonbar %}
|
{% block additional_buttonbar %}
|
||||||
{% if perms.content.add_article %}
|
{% if perms.content.add_article %}
|
||||||
<a href="{% url "add-article" %}" class="button"><img src="{{ STATIC_URL }}icons/note_add.png" alt="" /> {% trans "Add Article" %}</a>
|
<a href="{% url 'add-article' %}" class="button"><img src="{{ STATIC_URL }}icons/note_add.png" alt="" /> {% trans "Add Article" %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
{% block date_list %}
|
{% block date_list %}
|
||||||
<h2>{% trans "Archive" %} {{month|date:'E'}}</h2>
|
<h2>{% trans "Archive" %} {{month|date:'E'}}</h2>
|
||||||
<div class="buttonbar">
|
<div class="buttonbar">
|
||||||
<a href="{% url "article-archive" year=month|date:'Y' %}" class="button"><img src="{{ STATIC_URL }}icons/arrow_undo.png" alt="{% trans 'back' %}" /> {% trans 'back' %}</a>
|
<a href="{% url 'article-archive' year=month|date:'Y' %}" class="button"><img src="{{ STATIC_URL }}icons/arrow_undo.png" alt="{% trans 'back' %}" /> {% trans 'back' %}</a>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
<ul class="list" style="margin: 20px;">
|
<ul class="list" style="margin: 20px;">
|
||||||
{% if active_category %}
|
{% if active_category %}
|
||||||
{% for date in date_list %}
|
{% for date in date_list %}
|
||||||
<li class="date"><a href="{% url "article-archive" category=active_category.slug year=year|date:'Y' month=date|date:'m' %}">{{active_category.name}}: {{ date|date:'F' }}</a></li>
|
<li class="date"><a href="{% url 'article-archive' category=active_category.slug year=year|date:'Y' month=date|date:'m' %}">{{active_category.name}}: {{ date|date:'F' }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% for date in date_list %}
|
{% for date in date_list %}
|
||||||
<li class="date"><a href="{% url "article-archive" year=year|date:'Y' month=date|date:'m' %}">{{ date|date:'F' }}</a></li>
|
<li class="date"><a href="{% url 'article-archive' year=year|date:'Y' month=date|date:'m' %}">{{ date|date:'F' }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -29,8 +29,8 @@
|
|||||||
<p> </p>
|
<p> </p>
|
||||||
|
|
||||||
<ul class="info">
|
<ul class="info">
|
||||||
<li class="user"><strong>{% trans 'Author' %}:</strong> <a href="{% url "membership-details" article.author %}" itemprop="author">{{article.author}}</a></li>
|
<li class="user"><strong>{% trans 'Author' %}:</strong> <a href="{% url 'membership-details' article.author %}" itemprop="author">{{article.author}}</a></li>
|
||||||
<li class="date"><strong>{% trans 'Created on' %}: </strong><time date="{{article.date_created|date:"c"}}">{{ article.date_created|date }}</time></li>
|
<li class="date"><strong>{% trans 'Created on' %}: </strong><time date="{{article.date_created|date:'c'}}">{{ article.date_created|date }}</time></li>
|
||||||
<li class="category"><strong>{% trans "Category"%}: </strong><a href="{{ article.category.get_absolute_url }}" itemprop="articleSection">{{article.category.name}}</a></li>
|
<li class="category"><strong>{% trans "Category"%}: </strong><a href="{{ article.category.get_absolute_url }}" itemprop="articleSection">{{article.category.name}}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@@ -49,6 +49,6 @@
|
|||||||
|
|
||||||
{% block buttonbar %}
|
{% block buttonbar %}
|
||||||
{% if perms.content.change_article %}
|
{% if perms.content.change_article %}
|
||||||
<a href="{% url "edit-article" article.id %}" class="button"><img src="{{STATIC_URL}}icons/note_edit.png" alt="" />{% trans "Edit Article" %}</a>
|
<a href="{% url 'edit-article' article.id %}" class="button"><img src="{{STATIC_URL}}icons/note_edit.png" alt="" />{% trans "Edit Article" %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -33,13 +33,13 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@page {
|
@page {
|
||||||
margin-right: 0mm;
|
margin-right: 0;
|
||||||
margin-bottom: 0mm;
|
margin-bottom: 0;
|
||||||
margin-top: 35mm;
|
margin-top: 35mm;
|
||||||
margin-left: 2cm;
|
margin-left: 2cm;
|
||||||
@frame header {
|
@frame header {
|
||||||
-pdf-frame-content : page_header;
|
-pdf-frame-content : page_header;
|
||||||
top: 0mm;
|
top: 0;
|
||||||
margin: 5mm;
|
margin: 5mm;
|
||||||
height: 4cm;
|
height: 4cm;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
'''
|
"""
|
||||||
Created on 10.06.2012
|
Created on 10.06.2012
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from django import template
|
from django import template
|
||||||
from django.utils.datastructures import SortedDict
|
from django.utils.datastructures import SortedDict
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
@@ -40,4 +41,5 @@ def get_fieldset(parser, token):
|
|||||||
)
|
)
|
||||||
return FieldSetNode(form, variable_name, fields)
|
return FieldSetNode(form, variable_name, fields)
|
||||||
|
|
||||||
|
|
||||||
get_fieldset = register.tag(get_fieldset)
|
get_fieldset = register.tag(get_fieldset)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class ArticleArchiveMixin(object):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyAttributeOutsideInit
|
||||||
class ArticleArchiveIndex(ArticleArchiveMixin, generic.ArchiveIndexView):
|
class ArticleArchiveIndex(ArticleArchiveMixin, generic.ArchiveIndexView):
|
||||||
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
|
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
|
||||||
date_field = 'date_created'
|
date_field = 'date_created'
|
||||||
@@ -83,7 +84,7 @@ class ArticleForm(PermissionRequiredMixin, generic.UpdateView):
|
|||||||
form_class = forms.ArticleForm
|
form_class = forms.ArticleForm
|
||||||
permission_required = 'content.change_article'
|
permission_required = 'content.change_article'
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self, **kwargs):
|
||||||
if self.kwargs.get('pk', None):
|
if self.kwargs.get('pk', None):
|
||||||
return models.Article.objects.get(pk=self.kwargs['pk'])
|
return models.Article.objects.get(pk=self.kwargs['pk'])
|
||||||
else:
|
else:
|
||||||
@@ -91,6 +92,7 @@ class ArticleForm(PermissionRequiredMixin, generic.UpdateView):
|
|||||||
|
|
||||||
|
|
||||||
class ImageList(generic.View):
|
class ImageList(generic.View):
|
||||||
|
# noinspection PyMethodMayBeStatic
|
||||||
def get(self, kwargs):
|
def get(self, kwargs):
|
||||||
image_list = []
|
image_list = []
|
||||||
response = HttpResponse(content_type='text/javascript')
|
response = HttpResponse(content_type='text/javascript')
|
||||||
@@ -137,7 +139,6 @@ class PageEditForm(PermissionRequiredMixin, generic.UpdateView):
|
|||||||
|
|
||||||
|
|
||||||
class PageHtml(generic.DetailView):
|
class PageHtml(generic.DetailView):
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
try:
|
try:
|
||||||
return models.Page.objects.get(path=self.kwargs['path'],
|
return models.Page.objects.get(path=self.kwargs['path'],
|
||||||
@@ -152,7 +153,6 @@ class PageHtml(generic.DetailView):
|
|||||||
|
|
||||||
|
|
||||||
class PagePdf(generic.DeleteView):
|
class PagePdf(generic.DeleteView):
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
try:
|
try:
|
||||||
return models.Page.objects.get(path=self.kwargs['path'],
|
return models.Page.objects.get(path=self.kwargs['path'],
|
||||||
@@ -175,7 +175,7 @@ class PagePdf(generic.DeleteView):
|
|||||||
|
|
||||||
|
|
||||||
class PageList(generic.View):
|
class PageList(generic.View):
|
||||||
|
# noinspection PyMethodMayBeStatic
|
||||||
def get(self, kwargs):
|
def get(self, kwargs):
|
||||||
response = HttpResponse(content_type='text/javascript')
|
response = HttpResponse(content_type='text/javascript')
|
||||||
response.write('var tinyMCELinkList = new Array(')
|
response.write('var tinyMCELinkList = new Array(')
|
||||||
@@ -213,4 +213,5 @@ class StartPage(generic.TemplateView):
|
|||||||
'recent_comment_list': recent_comment_list,
|
'recent_comment_list': recent_comment_list,
|
||||||
}
|
}
|
||||||
return context
|
return context
|
||||||
|
|
||||||
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
|
queryset = models.Article.objects.filter(status=models.STATUS_PUBLISHED)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 19.09.2011
|
Created on 19.09.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
# import stuff we need from django
|
# import stuff we need from django
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from events.models import Event, Photo, Location
|
from events.models import Event, Photo, Location
|
||||||
|
|||||||
@@ -1,24 +1,31 @@
|
|||||||
'''
|
"""
|
||||||
Created on 03.10.2011
|
Created on 03.10.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from . import models
|
from . import models
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
from utils.html5.widgets import DateTimeInput
|
from utils.html5.widgets import DateTimeInput
|
||||||
|
|
||||||
|
user_query = get_user_model().objects.all()
|
||||||
|
|
||||||
|
|
||||||
class PhotoUploadForm(forms.Form):
|
class PhotoUploadForm(forms.Form):
|
||||||
error_css_class = 'error'
|
error_css_class = 'error'
|
||||||
required_css_class = 'required'
|
required_css_class = 'required'
|
||||||
|
photographer = forms.ModelChoiceField(user_query, required=True,)
|
||||||
photographer = forms.ModelChoiceField(User.objects.all(), required=True,)
|
|
||||||
event = forms.ModelChoiceField(models.Event.objects.all(), required=True,)
|
event = forms.ModelChoiceField(models.Event.objects.all(), required=True,)
|
||||||
upload = forms.FileField(label=_('Images'), required=True,
|
upload = forms.FileField(
|
||||||
widget=forms.widgets.ClearableFileInput(attrs={'multiple': 'multiple',
|
label=_('Images'),
|
||||||
'accept': "image/gif,image/png,image/jpeg"})
|
required=True,
|
||||||
|
widget=forms.widgets.ClearableFileInput(
|
||||||
|
attrs={
|
||||||
|
'multiple': 'multiple',
|
||||||
|
'accept': "image/gif,image/png,image/jpeg"
|
||||||
|
}
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ CHOICES_VERTICAL = (
|
|||||||
|
|
||||||
|
|
||||||
def get_upload_path(instance, filename):
|
def get_upload_path(instance, filename):
|
||||||
'''
|
"""
|
||||||
Generates the desired file path and filename for an uploaded Image.
|
Generates the desired file path and filename for an uploaded Image.
|
||||||
With this function Django can save the uploaded images to subfolders that
|
With this function Django can save the uploaded images to subfolders that
|
||||||
also have a meaning for humans.
|
also have a meaning for humans.
|
||||||
@@ -40,7 +40,7 @@ def get_upload_path(instance, filename):
|
|||||||
@type instance: a instace of an models.Model sub-class.
|
@type instance: a instace of an models.Model sub-class.
|
||||||
@param filename: The filename of the uploaded image.
|
@param filename: The filename of the uploaded image.
|
||||||
@type filename: String
|
@type filename: String
|
||||||
'''
|
"""
|
||||||
extension = filename[filename.rfind('.') + 1:]
|
extension = filename[filename.rfind('.') + 1:]
|
||||||
if isinstance(instance, Event):
|
if isinstance(instance, Event):
|
||||||
if instance.id:
|
if instance.id:
|
||||||
@@ -57,9 +57,9 @@ def get_upload_path(instance, filename):
|
|||||||
|
|
||||||
|
|
||||||
def post_save_image(sender, instance=None, created=False, raw=False, **kwargs):
|
def post_save_image(sender, instance=None, created=False, raw=False, **kwargs):
|
||||||
'''
|
"""
|
||||||
Reganerate the images.
|
Reganerate the images.
|
||||||
'''
|
"""
|
||||||
os.remove(instance.display.path)
|
os.remove(instance.display.path)
|
||||||
os.remove(instance.callout.path)
|
os.remove(instance.callout.path)
|
||||||
os.remove(instance.thumbnail.path)
|
os.remove(instance.thumbnail.path)
|
||||||
@@ -121,7 +121,7 @@ class ImageModel(models.Model):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
return None
|
return None
|
||||||
if anchor_horizontal and anchor_vertical:
|
if anchor_horizontal and anchor_vertical:
|
||||||
return (self.anchor_horizontal, self.anchor_vertical)
|
return self.anchor_horizontal, self.anchor_vertical
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -130,7 +130,6 @@ class ImageModel(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
class EventManager(models.Manager):
|
class EventManager(models.Manager):
|
||||||
|
|
||||||
def current_event(self):
|
def current_event(self):
|
||||||
try:
|
try:
|
||||||
current = self.filter(start__lte=now())
|
current = self.filter(start__lte=now())
|
||||||
@@ -300,14 +299,23 @@ class Photo(ImageModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
event = models.ForeignKey(Event)
|
event = models.ForeignKey(Event)
|
||||||
description = models.TextField(_("Description"), max_length=300,
|
description = models.TextField(
|
||||||
blank=True)
|
_("Description"),
|
||||||
photographer = models.ForeignKey('auth.User')
|
max_length=300,
|
||||||
on_startpage = models.BooleanField(_("Startpage"), default=False,
|
blank=True
|
||||||
help_text=_('Display this Photo on the Startpage Teaser'))
|
)
|
||||||
|
photographer = models.ForeignKey(settings.AUTH_USER_MODEL)
|
||||||
|
on_startpage = models.BooleanField(
|
||||||
|
_("Startpage"),
|
||||||
|
default=False,
|
||||||
|
help_text=_('Display this Photo on the Startpage Teaser')
|
||||||
|
)
|
||||||
created_date = models.DateTimeField(_("Published on"))
|
created_date = models.DateTimeField(_("Published on"))
|
||||||
views = models.PositiveIntegerField(_("Number of views"), editable=False,
|
views = models.PositiveIntegerField(
|
||||||
default=0)
|
_("Number of views"),
|
||||||
|
editable=False,
|
||||||
|
default=0
|
||||||
|
)
|
||||||
objects = PhotoManager()
|
objects = PhotoManager()
|
||||||
metadata = None
|
metadata = None
|
||||||
orientation = 1
|
orientation = 1
|
||||||
@@ -340,12 +348,12 @@ class Photo(ImageModel):
|
|||||||
self.metadata.write()
|
self.metadata.write()
|
||||||
|
|
||||||
def rotate(self, rotate):
|
def rotate(self, rotate):
|
||||||
'''
|
"""
|
||||||
Sets an the Exif tag in an image to set the right direction.
|
Sets an the Exif tag in an image to set the right direction.
|
||||||
This provides lossless image rotation.
|
This provides lossless image rotation.
|
||||||
@param rotate: 'clockwise' or 'counter-clockwise' the direction in
|
@param rotate: 'clockwise' or 'counter-clockwise' the direction in
|
||||||
which we should rotate the image in 90° steps.
|
which we should rotate the image in 90° steps.
|
||||||
'''
|
"""
|
||||||
if not self.metadata:
|
if not self.metadata:
|
||||||
self.read_metadata()
|
self.read_metadata()
|
||||||
if rotate == 'clockwise':
|
if rotate == 'clockwise':
|
||||||
@@ -369,8 +377,10 @@ class Photo(ImageModel):
|
|||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('event-photo', kwargs={'event': self.event.id,
|
return reverse(
|
||||||
'pk': self.id})
|
'event-photo',
|
||||||
|
kwargs={'event': self.event.id, 'pk': self.id}
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def next_photo(self):
|
def next_photo(self):
|
||||||
@@ -381,12 +391,13 @@ class Photo(ImageModel):
|
|||||||
return self.get_previous_by_created_date(event=self.event)
|
return self.get_previous_by_created_date(event=self.event)
|
||||||
|
|
||||||
def save(self, **kwargs):
|
def save(self, **kwargs):
|
||||||
'''
|
"""
|
||||||
Triggers to save related Event to save. This should force an update for
|
Triggers to save related Event to save. This should force an update for
|
||||||
the denormalized Photo count.
|
the denormalized Photo count.
|
||||||
'''
|
"""
|
||||||
ImageModel.save(self, **kwargs)
|
ImageModel.save(self, **kwargs)
|
||||||
self.save_metadata()
|
self.save_metadata()
|
||||||
self.event.save()
|
self.event.save()
|
||||||
|
|
||||||
|
|
||||||
models.signals.post_save.connect(post_save_image, sender=Photo)
|
models.signals.post_save.connect(post_save_image, sender=Photo)
|
||||||
|
|||||||
@@ -1,40 +1,48 @@
|
|||||||
from imagekit.specs import ImageSpec
|
from imagekit.specs import ImageSpec
|
||||||
from imagekit import processors
|
from imagekit import processors
|
||||||
|
|
||||||
|
|
||||||
class ResizeDisplay(processors.Resize):
|
class ResizeDisplay(processors.Resize):
|
||||||
width = 780
|
width = 780
|
||||||
crop = False
|
crop = False
|
||||||
upscale = False
|
upscale = False
|
||||||
|
|
||||||
|
|
||||||
# first we define our thumbnail resize processor
|
# first we define our thumbnail resize processor
|
||||||
class ResizeCallout(processors.Resize):
|
class ResizeCallout(processors.Resize):
|
||||||
width = 620
|
width = 620
|
||||||
height = 300
|
height = 300
|
||||||
crop = True
|
crop = True
|
||||||
|
|
||||||
|
|
||||||
class ResizeAdmin(processors.Resize):
|
class ResizeAdmin(processors.Resize):
|
||||||
width = 60
|
width = 60
|
||||||
height = 60
|
height = 60
|
||||||
crop = True
|
crop = True
|
||||||
|
|
||||||
|
|
||||||
class ResizeThumbnail(processors.Resize):
|
class ResizeThumbnail(processors.Resize):
|
||||||
width = 140
|
width = 140
|
||||||
height = 140
|
height = 140
|
||||||
crop = True
|
crop = True
|
||||||
|
|
||||||
|
|
||||||
# Different Image Sizes
|
# Different Image Sizes
|
||||||
class Admin(ImageSpec):
|
class Admin(ImageSpec):
|
||||||
pre_cache = False
|
pre_cache = False
|
||||||
processors = [processors.Transpose, ResizeAdmin]
|
processors = [processors.Transpose, ResizeAdmin]
|
||||||
|
|
||||||
|
|
||||||
class Display(ImageSpec):
|
class Display(ImageSpec):
|
||||||
pre_cache = False
|
pre_cache = False
|
||||||
processors = [processors.Transpose, ResizeDisplay]
|
processors = [processors.Transpose, ResizeDisplay]
|
||||||
|
|
||||||
|
|
||||||
class Callout(ImageSpec):
|
class Callout(ImageSpec):
|
||||||
pre_cache = False
|
pre_cache = False
|
||||||
processors = [processors.Transpose, ResizeCallout]
|
processors = [processors.Transpose, ResizeCallout]
|
||||||
|
|
||||||
|
|
||||||
class Thumbnail(ImageSpec):
|
class Thumbnail(ImageSpec):
|
||||||
pre_cache = False
|
pre_cache = False
|
||||||
processors = [processors.Transpose, ResizeThumbnail]
|
processors = [processors.Transpose, ResizeThumbnail]
|
||||||
@@ -2,20 +2,24 @@
|
|||||||
{% load i18n comments %}
|
{% load i18n comments %}
|
||||||
|
|
||||||
{% block maincontent %}
|
{% block maincontent %}
|
||||||
<header>
|
<form action="" method="post" class="grid_12">
|
||||||
<form action="" method="post">
|
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
<header>
|
||||||
<h1 class="grid_12">Dieses Photo wirklich löschen?</h1>
|
<h1 class="grid_12">Dieses Photo wirklich löschen?</h1>
|
||||||
</header>
|
</header>
|
||||||
|
<p>Sind Sie sicher, dass Sie das Bild “{{photo.name}}” löschen wollen?</p>
|
||||||
<img src="{{photo.display.url}}" alt="{{photo.name}}" title="{{photo.name}}" class="grid_10 push_1"/>
|
<img src="{{photo.display.url}}" alt="{{photo.name}}" title="{{photo.name}}" class="grid_10 push_1"/>
|
||||||
<br class="clear"/>
|
<br class="clear"/>
|
||||||
<p>Sind Sie sicher, dass Sie das Bild “{{photo.name}}” löschen wollen?</p>
|
<p> </p>
|
||||||
<p class="buttonbar">
|
<p class="buttonbar">
|
||||||
<a href="{% url 'event-photo-list' photo.event.id %}" class="button" style="float: left;"><img src="{{STATIC_URL}}icons/cancel.png" alt="{% trans 'Cancel' %}" /> {% trans 'Cancel' %}</a>
|
<a href="{% url 'event-photo-list' photo.event.id %}" class="button" style="float: left;"><img
|
||||||
<button type="submit"><img src="{{STATIC_URL}}icons/delete.png" alt="{% trans 'Delete' %}" /> {% trans 'Delete' %}</button>
|
src="{{STATIC_URL}}icons/cancel.png" alt="{% trans 'Cancel' %}"/> {% trans 'Cancel' %}</a>
|
||||||
</form>
|
<button type="submit"><img src="{{STATIC_URL}}icons/delete.png" alt="{% trans 'Delete' %}"/>
|
||||||
|
{% trans 'Delete' %}
|
||||||
|
</button>
|
||||||
</p>
|
</p>
|
||||||
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
{% block buttonbar %}{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<li><a href="{{ current_top_page.get_absolute_url }}" {% ifequal current_page current_top_page %}class="active"{% endifequal %}>{{current_top_page.menu_name}}</a></li>
|
<li><a href="{{ current_top_page.get_absolute_url }}" {% ifequal current_page current_top_page %}class="active"{% endifequal %}>{{current_top_page.menu_name}}</a></li>
|
||||||
{% if perms.event.add_photo %}
|
{% if perms.event.add_photo %}
|
||||||
<li><a href="/gallery/upload/" {% ifequal current_path 'gallery/upload' %}class="active"{% endifequal %}>{% trans 'Upload' %}</a></li>
|
<li><a href="/gallery/upload/" class="{% ifequal current_path 'gallery/upload' %}active{% endifequal %}">{% trans 'Upload' %}</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<li><a href="{{ current_top_page.get_absolute_url }}" {% ifequal current_page current_top_page %}class="active"{% endifequal %}>{{current_top_page.menu_name}}</a></li>
|
<li><a href="{{ current_top_page.get_absolute_url }}" {% ifequal current_page current_top_page %}class="active"{% endifequal %}>{{current_top_page.menu_name}}</a></li>
|
||||||
{% if perms.event.add_photo %}
|
{% if perms.event.add_photo %}
|
||||||
<li><a href="/gallery/upload/" {% ifequal current_path 'gallery/upload' %}class="active"{% endifequal %}>{% trans 'Upload' %}</a></li>
|
<li><a href="/gallery/upload/" class="{% ifequal current_path 'gallery/upload' %}active{% endifequal %}">{% trans 'Upload' %}</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
from . import models, forms
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from django.contrib.auth.decorators import permission_required
|
from django.contrib.auth.decorators import permission_required
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth import get_user_model
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.http import HttpResponse, Http404
|
from django.http import HttpResponse, Http404
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
@@ -13,8 +13,11 @@ from django.utils.translation import ugettext as _
|
|||||||
from django.views import generic
|
from django.views import generic
|
||||||
from icalendar import Calendar, Event
|
from icalendar import Calendar, Event
|
||||||
import pyexiv2
|
import pyexiv2
|
||||||
|
|
||||||
from utils.mixins import PermissionRequiredMixin
|
from utils.mixins import PermissionRequiredMixin
|
||||||
|
|
||||||
|
from . import models, forms
|
||||||
|
|
||||||
|
|
||||||
class DeleteEventPhoto(generic.DeleteView):
|
class DeleteEventPhoto(generic.DeleteView):
|
||||||
model = models.Photo
|
model = models.Photo
|
||||||
@@ -22,6 +25,7 @@ class DeleteEventPhoto(generic.DeleteView):
|
|||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
return models.Photo.objects.get(pk=self.kwargs['pk'])
|
return models.Photo.objects.get(pk=self.kwargs['pk'])
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
return reverse('event-photo-list', args=[self.object.event.id])
|
return reverse('event-photo-list', args=[self.object.event.id])
|
||||||
|
|
||||||
@@ -29,18 +33,22 @@ class DeleteEventPhoto(generic.DeleteView):
|
|||||||
def dispatch(self, *args, **kwargs):
|
def dispatch(self, *args, **kwargs):
|
||||||
return super(DeleteEventPhoto, self).dispatch(*args, **kwargs)
|
return super(DeleteEventPhoto, self).dispatch(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class EventArchiveIndex(generic.ArchiveIndexView):
|
class EventArchiveIndex(generic.ArchiveIndexView):
|
||||||
allow_empty = True
|
allow_empty = True
|
||||||
context_object_name = 'event_list'
|
context_object_name = 'event_list'
|
||||||
date_field = 'start'
|
date_field = 'start'
|
||||||
model = models.Event
|
model = models.Event
|
||||||
paginate_by = 5
|
queryset = model.objects.all()
|
||||||
|
paginate_by = 15
|
||||||
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = generic.ArchiveIndexView.get_context_data(self, **kwargs)
|
context = generic.ArchiveIndexView.get_context_data(self, **kwargs)
|
||||||
context['is_archive'] = True
|
context['is_archive'] = True
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class EventArchiveMonth(generic.MonthArchiveView):
|
class EventArchiveMonth(generic.MonthArchiveView):
|
||||||
date_field = 'start'
|
date_field = 'start'
|
||||||
make_object_list = True
|
make_object_list = True
|
||||||
@@ -54,6 +62,7 @@ class EventArchiveMonth(generic.MonthArchiveView):
|
|||||||
context['is_archive'] = True
|
context['is_archive'] = True
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class EventArchiveYear(generic.YearArchiveView):
|
class EventArchiveYear(generic.YearArchiveView):
|
||||||
date_field = 'start'
|
date_field = 'start'
|
||||||
make_object_list = True
|
make_object_list = True
|
||||||
@@ -67,6 +76,7 @@ class EventArchiveYear(generic.YearArchiveView):
|
|||||||
context['is_archive'] = True
|
context['is_archive'] = True
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class EventDetail(generic.DetailView):
|
class EventDetail(generic.DetailView):
|
||||||
model = models.Event
|
model = models.Event
|
||||||
|
|
||||||
@@ -75,16 +85,17 @@ class EventDetail(generic.DetailView):
|
|||||||
context['form'] = forms.PhotoUploadForm(initial={'event': self.object, 'photographer': self.request.user})
|
context['form'] = forms.PhotoUploadForm(initial={'event': self.object, 'photographer': self.request.user})
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class EventForm(PermissionRequiredMixin, generic.UpdateView):
|
class EventForm(PermissionRequiredMixin, generic.UpdateView):
|
||||||
form_class = forms.EventForm
|
form_class = forms.EventForm
|
||||||
permission_required = 'events.add_event'
|
permission_required = 'events.add_event'
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
'''
|
"""
|
||||||
If an id has been submitted, try return the existing Event for an update,
|
If an id has been submitted, try return the existing Event for an update,
|
||||||
else creates a new one.
|
else creates a new one.
|
||||||
@param queryset:
|
@param queryset:
|
||||||
'''
|
"""
|
||||||
if self.kwargs.get('pk'):
|
if self.kwargs.get('pk'):
|
||||||
event = models.Event.objects.get(pk=self.kwargs['pk'])
|
event = models.Event.objects.get(pk=self.kwargs['pk'])
|
||||||
if event.event_series:
|
if event.event_series:
|
||||||
@@ -94,15 +105,17 @@ class EventForm(PermissionRequiredMixin, generic.UpdateView):
|
|||||||
else:
|
else:
|
||||||
return models.Event()
|
return models.Event()
|
||||||
|
|
||||||
|
|
||||||
class EventGallery(generic.ListView):
|
class EventGallery(generic.ListView):
|
||||||
template_name = 'events/photo_gallery.html'
|
template_name = 'events/photo_gallery.html'
|
||||||
queryset = models.Event.objects.filter(start__lt=timezone.now(), photo_count__gt=0)
|
queryset = models.Event.objects.filter(start__lt=timezone.now(), photo_count__gt=0)
|
||||||
paginate_by = 12
|
paginate_by = 12
|
||||||
|
|
||||||
|
|
||||||
class EventListIcal(generic.View):
|
class EventListIcal(generic.View):
|
||||||
'''
|
"""
|
||||||
Generates an returns an iCal File with all upcoming events.
|
Generates an returns an iCal File with all upcoming events.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def add_event(self, event):
|
def add_event(self, event):
|
||||||
ics_event = Event()
|
ics_event = Event()
|
||||||
@@ -130,6 +143,7 @@ class EventListIcal(generic.View):
|
|||||||
response.write(self.calendar.to_ical())
|
response.write(self.calendar.to_ical())
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
class EventPhoto(generic.UpdateView):
|
class EventPhoto(generic.UpdateView):
|
||||||
form_class = forms.EditPhotoForm
|
form_class = forms.EditPhotoForm
|
||||||
model = models.Photo
|
model = models.Photo
|
||||||
@@ -144,6 +158,7 @@ class EventPhoto(generic.UpdateView):
|
|||||||
else:
|
else:
|
||||||
return generic.UpdateView.post(self, request, *args, **kwargs)
|
return generic.UpdateView.post(self, request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class EventPhotoList(generic.ListView):
|
class EventPhotoList(generic.ListView):
|
||||||
context_object_name = 'photo_list'
|
context_object_name = 'photo_list'
|
||||||
paginate_by = 36
|
paginate_by = 36
|
||||||
@@ -161,6 +176,7 @@ class EventPhotoList(generic.ListView):
|
|||||||
except models.Event.DoesNotExist:
|
except models.Event.DoesNotExist:
|
||||||
raise Http404(_('Event does not exist'))
|
raise Http404(_('Event does not exist'))
|
||||||
|
|
||||||
|
|
||||||
class EventPhotoUpload(generic.FormView):
|
class EventPhotoUpload(generic.FormView):
|
||||||
form_class = forms.PhotoUploadForm
|
form_class = forms.PhotoUploadForm
|
||||||
template_name = 'events/photo_upload.html'
|
template_name = 'events/photo_upload.html'
|
||||||
@@ -175,24 +191,20 @@ class EventPhotoUpload(generic.FormView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
'''
|
"""
|
||||||
Set the current logged in user a default value for the photographer.
|
Set the current logged in user a default value for the photographer.
|
||||||
'''
|
"""
|
||||||
return {
|
return {
|
||||||
'photographer': self.request.user,
|
'photographer': self.request.user,
|
||||||
}
|
}
|
||||||
|
|
||||||
def post(self, *args, **kwargs):
|
def post(self, *args, **kwargs):
|
||||||
'''
|
"""
|
||||||
|
|
||||||
'''
|
"""
|
||||||
self.event = models.Event.objects.get(id=self.request.REQUEST.get('event'))
|
self.event = models.Event.objects.get(id=self.request.REQUEST.get('event'))
|
||||||
photographer = self.request.POST.get('photographer')
|
photographer = self.request.POST.get('photographer', self.request.user.id)
|
||||||
if photographer:
|
photographer = get_user_model().objects.get(id=photographer)
|
||||||
photographer = User.objects.get(id=photographer)
|
|
||||||
else:
|
|
||||||
photographer = self.request.user
|
|
||||||
|
|
||||||
self.counter = 1
|
self.counter = 1
|
||||||
for upload in self.request.FILES.getlist('upload'):
|
for upload in self.request.FILES.getlist('upload'):
|
||||||
name = upload.name
|
name = upload.name
|
||||||
@@ -221,8 +233,9 @@ class EventPhotoUpload(generic.FormView):
|
|||||||
description = exif_data['Exif.Image.ImageDescription'].value
|
description = exif_data['Exif.Image.ImageDescription'].value
|
||||||
except:
|
except:
|
||||||
description = ''
|
description = ''
|
||||||
return (created_date, description)
|
return created_date, description
|
||||||
|
|
||||||
|
|
||||||
class UpcomingEvents(generic.ListView):
|
class UpcomingEvents(generic.ListView):
|
||||||
queryset = models.Event.objects.upcoming(limit=None)
|
queryset = models.Event.objects.upcoming(limit=None)
|
||||||
paginate_by = 12
|
paginate_by = 16
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ Compiler library and Java version 6 or later."""
|
|||||||
|
|
||||||
for arg in args:
|
for arg in args:
|
||||||
if not arg.endswith(".js"):
|
if not arg.endswith(".js"):
|
||||||
arg = arg + ".js"
|
arg += ".js"
|
||||||
to_compress = os.path.expanduser(arg)
|
to_compress = os.path.expanduser(arg)
|
||||||
if os.path.exists(to_compress):
|
if os.path.exists(to_compress):
|
||||||
to_compress_min = "%s.min.js" % "".join(arg.rsplit(".js"))
|
to_compress_min = "%s.min.js" % "".join(arg.rsplit(".js"))
|
||||||
|
|||||||
2
kasu/static/js/tiny_mce/tiny_mce_src.js
vendored
2
kasu/static/js/tiny_mce/tiny_mce_src.js
vendored
@@ -5716,5 +5716,5 @@ tinymce.html.Writer = function(settings) {
|
|||||||
// Perform a binary search for the position
|
// Perform a binary search for the position
|
||||||
while (startIndex <= endIndex) {
|
while (startIndex <= endIndex) {
|
||||||
index = Math.floor((startIndex + endIndex) / 2);
|
index = Math.floor((startIndex + endIndex) / 2);
|
||||||
|
};
|
||||||
// Move selection to node and
|
// Move selection to node and
|
||||||
@@ -156,7 +156,7 @@
|
|||||||
<h3>Skin support example</h3>
|
<h3>Skin support example</h3>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
This page displays the two skins that TinyMCE comes with. You can make your own by creating a CSS file in themes/advanced/skins/<yout skin>/ui.css
|
This page displays the two skins that TinyMCE comes with. You can make your own by creating a CSS file in themes/advanced/skins/>yout skin</ui.css
|
||||||
There are more examples on how to use TinyMCE in the <a href="http://tinymce.moxiecode.com/examples/">Wiki</a>.
|
There are more examples on how to use TinyMCE in the <a href="http://tinymce.moxiecode.com/examples/">Wiki</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 28.09.2011
|
Created on 28.09.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
@@ -290,9 +290,9 @@ class MassMailer(object):
|
|||||||
html_template = None
|
html_template = None
|
||||||
|
|
||||||
def __init__(self, subject=None, template=None, context=None):
|
def __init__(self, subject=None, template=None, context=None):
|
||||||
'''
|
"""
|
||||||
|
|
||||||
'''
|
"""
|
||||||
self.mail_queue = set()
|
self.mail_queue = set()
|
||||||
self.recipients = set()
|
self.recipients = set()
|
||||||
self.subject = subject
|
self.subject = subject
|
||||||
@@ -357,9 +357,9 @@ class MassMailer(object):
|
|||||||
self.headers[name] = value
|
self.headers[name] = value
|
||||||
|
|
||||||
def send(self):
|
def send(self):
|
||||||
'''
|
"""
|
||||||
Process the E-Mails and send them
|
Process the E-Mails and send them
|
||||||
'''
|
"""
|
||||||
self.process_mails()
|
self.process_mails()
|
||||||
if len(self.mail_queue) == 0:
|
if len(self.mail_queue) == 0:
|
||||||
self.log.info('No recipients for eMail "%s", bye!', self.subject)
|
self.log.info('No recipients for eMail "%s", bye!', self.subject)
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ def set_dirty(event=None, season=None, user=None):
|
|||||||
elif user:
|
elif user:
|
||||||
key_to_add = user
|
key_to_add = user
|
||||||
queue_name = 'kyu_dan_ranking_queue'
|
queue_name = 'kyu_dan_ranking_queue'
|
||||||
|
if key_to_add and queue_name:
|
||||||
recalculation_queue = cache.get(queue_name, set())
|
recalculation_queue = cache.get(queue_name, set())
|
||||||
recalculation_queue.add(key_to_add)
|
recalculation_queue.add(key_to_add)
|
||||||
cache.set(queue_name, recalculation_queue, 360)
|
cache.set(queue_name, recalculation_queue, 360)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
'''
|
"""
|
||||||
Created on 19.09.2011
|
Created on 19.09.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
# import stuff we need from django
|
# import stuff we need from django
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from . import models, set_dirty
|
from . import models, set_dirty
|
||||||
@@ -45,7 +45,6 @@ class EventRankingAdmin(admin.ModelAdmin):
|
|||||||
list_display = ('placement', 'user', 'event', 'avg_placement', 'avg_score',
|
list_display = ('placement', 'user', 'event', 'avg_placement', 'avg_score',
|
||||||
'hanchan_count', 'good_hanchans', 'won_hanchans', 'dirty')
|
'hanchan_count', 'good_hanchans', 'won_hanchans', 'dirty')
|
||||||
list_display_links = ('user',)
|
list_display_links = ('user',)
|
||||||
list_filter = ('event',)
|
|
||||||
actions = [recalculate]
|
actions = [recalculate]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
'''
|
"""
|
||||||
Created on 04.10.2011
|
Created on 04.10.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth import get_user_model
|
||||||
import django.forms
|
import django.forms
|
||||||
from django.forms.models import BaseInlineFormSet, inlineformset_factory
|
from django.forms.models import BaseInlineFormSet, inlineformset_factory
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
@@ -30,10 +30,10 @@ class HanchanForm(forms.ModelForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def clean_start(self):
|
def clean_start(self):
|
||||||
u'''
|
u"""
|
||||||
Das Datum darf nicht in der Zukunft liegen und es muss innerhalb der
|
Das Datum darf nicht in der Zukunft liegen und es muss innerhalb der
|
||||||
Dauer des Events liegen.
|
Dauer des Events liegen.
|
||||||
'''
|
"""
|
||||||
start = self.cleaned_data['start']
|
start = self.cleaned_data['start']
|
||||||
event = self.cleaned_data['event']
|
event = self.cleaned_data['event']
|
||||||
if start > timezone.now():
|
if start > timezone.now():
|
||||||
@@ -58,8 +58,8 @@ class HanchanAdminForm(HanchanForm):
|
|||||||
class PlayerForm(forms.ModelForm):
|
class PlayerForm(forms.ModelForm):
|
||||||
error_css_class = 'error'
|
error_css_class = 'error'
|
||||||
required_css_class = 'required'
|
required_css_class = 'required'
|
||||||
player_choices = User.objects.filter(groups__in=(1, 2)).distinct()
|
player_choices = get_user_model().objects.filter(groups__in=(1, 2))
|
||||||
player_choices = player_choices.order_by('username')
|
player_choices = player_choices.order_by('username').distinct()
|
||||||
user = forms.ModelChoiceField(player_choices, required=True)
|
user = forms.ModelChoiceField(player_choices, required=True)
|
||||||
comment = forms.CharField(
|
comment = forms.CharField(
|
||||||
widget=forms.widgets.TextInput(attrs={'maxlength': 255}),
|
widget=forms.widgets.TextInput(attrs={'maxlength': 255}),
|
||||||
|
|||||||
@@ -4,9 +4,8 @@
|
|||||||
Generate Randum Mahjong Hanchans to the the Raning System
|
Generate Randum Mahjong Hanchans to the the Raning System
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib import auth
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.utils.translation import ugettext_lazy as _
|
|
||||||
from events.models import Event
|
from events.models import Event
|
||||||
from mahjong_ranking import models
|
from mahjong_ranking import models
|
||||||
import random
|
import random
|
||||||
@@ -85,7 +84,7 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
num_hanchans = int(options.get('hanchans', 4))
|
num_hanchans = int(options.get('hanchans', 4))
|
||||||
self.user_list = list(User.objects.all())
|
self.user_list = list(auth.get_user_model().objects.all())
|
||||||
|
|
||||||
for event in Event.objects.all():
|
for event in Event.objects.all():
|
||||||
for i in range(random.randrange(2,8)):
|
for i in range(random.randrange(2,8)):
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
'''
|
"""
|
||||||
Created on 23.05.2011
|
Created on 23.05.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from mahjong_ranking import models
|
from mahjong_ranking import models
|
||||||
@@ -11,10 +11,10 @@ from . import logger
|
|||||||
|
|
||||||
|
|
||||||
class DenormalizationUpdateMiddleware(object):
|
class DenormalizationUpdateMiddleware(object):
|
||||||
'''
|
"""
|
||||||
This Class deferres the recalculation for the Otaku XP at the end of a
|
This Class deferres the recalculation for the Otaku XP at the end of a
|
||||||
response.
|
response.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def process_response(self, request, response):
|
def process_response(self, request, response):
|
||||||
if request.method != 'POST':
|
if request.method != 'POST':
|
||||||
@@ -57,7 +57,7 @@ class DenormalizationUpdateMiddleware(object):
|
|||||||
user_id=user_id, season_id=season_id)[0]
|
user_id=user_id, season_id=season_id)[0]
|
||||||
ranking.recalculate()
|
ranking.recalculate()
|
||||||
else:
|
else:
|
||||||
logger.error('Season: %i; User %i - existiert nicht!', season_id, user_id)
|
logger.error('Season: %i; Benutzer Nr. %i - existiert nicht!', season_id, user_id)
|
||||||
cache.set('ladder_ranking_queue', ladder_ranking_queue, 360)
|
cache.set('ladder_ranking_queue', ladder_ranking_queue, 360)
|
||||||
transaction.commit()
|
transaction.commit()
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
from datetime import date, timedelta
|
from datetime import date, timedelta
|
||||||
from django.contrib.auth.models import User
|
from django.conf import settings
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
@@ -20,12 +20,12 @@ ladder_seasons = set()
|
|||||||
|
|
||||||
|
|
||||||
class EventRanking(models.Model):
|
class EventRanking(models.Model):
|
||||||
'''
|
"""
|
||||||
Event Rankings funktionieren genauso wie Season Rankings.
|
Event Rankings funktionieren genauso wie Season Rankings.
|
||||||
Sie beschränken sich aber auf einen Event und werden nur dann angestossen,
|
Sie beschränken sich aber auf einen Event und werden nur dann angestossen,
|
||||||
wenn der Event als Turnier markiert wurde.
|
wenn der Event als Turnier markiert wurde.
|
||||||
'''
|
"""
|
||||||
user = models.ForeignKey(User)
|
user = models.ForeignKey(settings.AUTH_USER_MODEL)
|
||||||
event = models.ForeignKey(Event)
|
event = models.ForeignKey(Event)
|
||||||
placement = models.PositiveIntegerField(blank=True, null=True)
|
placement = models.PositiveIntegerField(blank=True, null=True)
|
||||||
avg_placement = models.FloatField(default=4)
|
avg_placement = models.FloatField(default=4)
|
||||||
@@ -42,7 +42,7 @@ class EventRanking(models.Model):
|
|||||||
return reverse('event-ranking', args=[self.tourney_id])
|
return reverse('event-ranking', args=[self.tourney_id])
|
||||||
|
|
||||||
def recalculate(self):
|
def recalculate(self):
|
||||||
'''
|
"""
|
||||||
Berechnet die durschnittliche Platzierung und Punkte, u.v.m. neu.
|
Berechnet die durschnittliche Platzierung und Punkte, u.v.m. neu.
|
||||||
|
|
||||||
Diese Daten werden benötigt um die Platzierung zu erstellen. Sie
|
Diese Daten werden benötigt um die Platzierung zu erstellen. Sie
|
||||||
@@ -52,7 +52,7 @@ class EventRanking(models.Model):
|
|||||||
Das Eigenschaft dirty ist ein altes Überbleibsel, um das Objekt
|
Das Eigenschaft dirty ist ein altes Überbleibsel, um das Objekt
|
||||||
zur neuberrechnung zu markieren. Mittlerweile wird ein lokaler
|
zur neuberrechnung zu markieren. Mittlerweile wird ein lokaler
|
||||||
Cache dafür verwendet, das ist schneller.
|
Cache dafür verwendet, das ist schneller.
|
||||||
'''
|
"""
|
||||||
logger.info(u'Recalculate EventRanking for Player %s in %s', self.user, self.event.name) # @IgnorePep8
|
logger.info(u'Recalculate EventRanking for Player %s in %s', self.user, self.event.name) # @IgnorePep8
|
||||||
event_hanchans = Player.objects.valid_hanchans(user=self.user_id, event=self.event_id) # @IgnorePep8
|
event_hanchans = Player.objects.valid_hanchans(user=self.user_id, event=self.event_id) # @IgnorePep8
|
||||||
aggregator = event_hanchans.aggregate(
|
aggregator = event_hanchans.aggregate(
|
||||||
@@ -72,16 +72,20 @@ class EventRanking(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
class Hanchan(models.Model):
|
class Hanchan(models.Model):
|
||||||
'''
|
"""
|
||||||
Ein komplette Runde Mahjong, die aus genau 4 Spielern bestehen muss.
|
Ein komplette Runde Mahjong, die aus genau 4 Spielern bestehen muss.
|
||||||
Es werden aber noch andere Tests durchgeführt, ob sie gültig ist.
|
Es werden aber noch andere Tests durchgeführt, ob sie gültig ist.
|
||||||
Außerdem gehört jede Hanchan zu einer Veranstaltung.
|
Außerdem gehört jede Hanchan zu einer Veranstaltung.
|
||||||
'''
|
"""
|
||||||
comment = models.TextField(_('Comment'), blank=True)
|
comment = models.TextField(_('Comment'), blank=True)
|
||||||
confirmed = models.BooleanField(_('Has been Confirmed'), default=True, help_text=_('Only valid and confirmed Hanchans will be counted in the rating.')) # @IgnorePep8
|
confirmed = models.BooleanField(_('Has been Confirmed'), default=True, help_text=_('Only valid and confirmed Hanchans will be counted in the rating.')) # @IgnorePep8
|
||||||
event = models.ForeignKey(Event)
|
event = models.ForeignKey(Event)
|
||||||
player_names = models.CharField(max_length=127, editable=False)
|
player_names = models.CharField(max_length=127, editable=False)
|
||||||
players = models.ManyToManyField(User, through='Player',verbose_name=_('Players')) # @IgnorePep8
|
players = models.ManyToManyField(
|
||||||
|
settings.AUTH_USER_MODEL,
|
||||||
|
through='Player',
|
||||||
|
verbose_name=_('Players')
|
||||||
|
)
|
||||||
season = models.ForeignKey('LadderSeason', blank=True, null=True, editable=False) # @IgnorePep8
|
season = models.ForeignKey('LadderSeason', blank=True, null=True, editable=False) # @IgnorePep8
|
||||||
start = models.DateTimeField(_('Start'), help_text=_('This is crucial to get the right Hanchans that scores')) # @IgnorePep8
|
start = models.DateTimeField(_('Start'), help_text=_('This is crucial to get the right Hanchans that scores')) # @IgnorePep8
|
||||||
valid = models.BooleanField(_('Is Valid'), default=False)
|
valid = models.BooleanField(_('Is Valid'), default=False)
|
||||||
@@ -95,14 +99,14 @@ class Hanchan(models.Model):
|
|||||||
return "Hanchan am {0:%d.%m.%Y} um {0:%H:%M} ({1})".format(self.start, self.player_names)
|
return "Hanchan am {0:%d.%m.%Y} um {0:%H:%M} ({1})".format(self.start, self.player_names)
|
||||||
|
|
||||||
def check_validity(self):
|
def check_validity(self):
|
||||||
'''
|
"""
|
||||||
Prüft ob die Hanchan gültig ist.
|
Prüft ob die Hanchan gültig ist.
|
||||||
|
|
||||||
4 Spieler müssen genau 100.000 Punkte erreichen, mehr sind nur erlaubt
|
4 Spieler müssen genau 100.000 Punkte erreichen, mehr sind nur erlaubt
|
||||||
wenn midestens ein Spieler ins Minus (auf 0) geraten ist. Ansonsten
|
wenn midestens ein Spieler ins Minus (auf 0) geraten ist. Ansonsten
|
||||||
wird die Hanchan als ungültig markiert aber trotzdem abgespeichert,
|
wird die Hanchan als ungültig markiert aber trotzdem abgespeichert,
|
||||||
außerdem wird die Begründung zurück gegeben, was nicht gestimmt hat.
|
außerdem wird die Begründung zurück gegeben, was nicht gestimmt hat.
|
||||||
'''
|
"""
|
||||||
logger.debug("Hanchan wird geprüft ob er valide ist...")
|
logger.debug("Hanchan wird geprüft ob er valide ist...")
|
||||||
if not self.pk:
|
if not self.pk:
|
||||||
self.valid = False
|
self.valid = False
|
||||||
@@ -132,7 +136,7 @@ class Hanchan(models.Model):
|
|||||||
return 'Wir wissen nicht warum, aber das kann nicht passen...'
|
return 'Wir wissen nicht warum, aber das kann nicht passen...'
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
'''
|
"""
|
||||||
Prüft ob wichtige Vorrausetzungen gegeben sind und aktualisiert ein
|
Prüft ob wichtige Vorrausetzungen gegeben sind und aktualisiert ein
|
||||||
paar Zwischenspeicher, bevor gespeichert wird.
|
paar Zwischenspeicher, bevor gespeichert wird.
|
||||||
|
|
||||||
@@ -143,7 +147,7 @@ class Hanchan(models.Model):
|
|||||||
|
|
||||||
Die Gültigkeit wird geprüft und die Sasion in der die Hanchan liegt
|
Die Gültigkeit wird geprüft und die Sasion in der die Hanchan liegt
|
||||||
wird aktualisert.
|
wird aktualisert.
|
||||||
'''
|
"""
|
||||||
logger.debug("Hanchan clean() wurde getriggert!")
|
logger.debug("Hanchan clean() wurde getriggert!")
|
||||||
|
|
||||||
# if self.pk and self.player_set.distinct().count() != 4:
|
# if self.pk and self.player_set.distinct().count() != 4:
|
||||||
@@ -156,10 +160,10 @@ class Hanchan(models.Model):
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
def compute_player_placements(self):
|
def compute_player_placements(self):
|
||||||
u'''
|
u"""
|
||||||
Bestimmt die Platzierung eines der Spieler einer Hanchan und speichert
|
Bestimmt die Platzierung eines der Spieler einer Hanchan und speichert
|
||||||
diese beim jeweiligen Spieler ab.
|
diese beim jeweiligen Spieler ab.
|
||||||
'''
|
"""
|
||||||
logger.debug("Berechne die Platzierungen neu...")
|
logger.debug("Berechne die Platzierungen neu...")
|
||||||
attending_players = self.player_set.select_related('hanchan', 'user')
|
attending_players = self.player_set.select_related('hanchan', 'user')
|
||||||
attending_players = attending_players.order_by('-score')
|
attending_players = attending_players.order_by('-score')
|
||||||
@@ -182,9 +186,9 @@ class Hanchan(models.Model):
|
|||||||
player.save(season_id=self.season_id, mark_dirty=True)
|
player.save(season_id=self.season_id, mark_dirty=True)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
'''
|
"""
|
||||||
URL zur Hanchanliste des Events wo diese Hanchan gelistet wurde.
|
URL zur Hanchanliste des Events wo diese Hanchan gelistet wurde.
|
||||||
'''
|
"""
|
||||||
url = reverse('event-hanchan-list', kwargs={'event': self.event.pk})
|
url = reverse('event-hanchan-list', kwargs={'event': self.event.pk})
|
||||||
return u'%(url)s#%(pk)d' % {'url': url, 'pk': self.pk}
|
return u'%(url)s#%(pk)d' % {'url': url, 'pk': self.pk}
|
||||||
|
|
||||||
@@ -201,12 +205,12 @@ class Hanchan(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
class KyuDanRanking(models.Model):
|
class KyuDanRanking(models.Model):
|
||||||
u'''
|
u"""
|
||||||
Die Einstufung des Spieles im Kyu bzw. Dan System.
|
Die Einstufung des Spieles im Kyu bzw. Dan System.
|
||||||
Im Gegensatz zum Ladder Ranking ist das nicht Saison gebunden.
|
Im Gegensatz zum Ladder Ranking ist das nicht Saison gebunden.
|
||||||
daher läuft es getrennt.
|
daher läuft es getrennt.
|
||||||
'''
|
"""
|
||||||
user = models.OneToOneField(User)
|
user = models.OneToOneField(settings.AUTH_USER_MODEL)
|
||||||
dan = models.PositiveSmallIntegerField(blank=True, null=True)
|
dan = models.PositiveSmallIntegerField(blank=True, null=True)
|
||||||
dan_points = models.PositiveIntegerField(default=0)
|
dan_points = models.PositiveIntegerField(default=0)
|
||||||
kyu = models.PositiveSmallIntegerField(default=10, blank=True, null=True)
|
kyu = models.PositiveSmallIntegerField(default=10, blank=True, null=True)
|
||||||
@@ -229,11 +233,11 @@ class KyuDanRanking(models.Model):
|
|||||||
return u"%s - %d. Kyu" % (self.user.username, self.kyu)
|
return u"%s - %d. Kyu" % (self.user.username, self.kyu)
|
||||||
|
|
||||||
def append_3_in_a_row_bonuspoints(self, hanchan):
|
def append_3_in_a_row_bonuspoints(self, hanchan):
|
||||||
u'''
|
u"""
|
||||||
Wenn der Spieler 3 Siege in folge hatte, bekommt er so viele Punkte
|
Wenn der Spieler 3 Siege in folge hatte, bekommt er so viele Punkte
|
||||||
das er einen Dan Rang aufsteigt. Dies wird als Kommentar abgespeichert,
|
das er einen Dan Rang aufsteigt. Dies wird als Kommentar abgespeichert,
|
||||||
um es besser nachvollziehen zu können.
|
um es besser nachvollziehen zu können.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
if self.dan and hanchan.placement == 1:
|
if self.dan and hanchan.placement == 1:
|
||||||
self.wins_in_a_row += 1
|
self.wins_in_a_row += 1
|
||||||
@@ -259,12 +263,12 @@ class KyuDanRanking(models.Model):
|
|||||||
self.dan_points += bonus_points
|
self.dan_points += bonus_points
|
||||||
|
|
||||||
def append_tournament_bonuspoints(self, player):
|
def append_tournament_bonuspoints(self, player):
|
||||||
'''
|
"""
|
||||||
Prüft ob es die letzte Hanchan in einem Turnier war. Wenn ja werden
|
Prüft ob es die letzte Hanchan in einem Turnier war. Wenn ja werden
|
||||||
bei Bedarf Bonuspunkte vergeben, falls der Spieler das Turnier gewonnen
|
bei Bedarf Bonuspunkte vergeben, falls der Spieler das Turnier gewonnen
|
||||||
hat.
|
hat.
|
||||||
:param player: Ein Player Objekt
|
:param player: Ein Player Objekt
|
||||||
'''
|
"""
|
||||||
bonus_points = 0
|
bonus_points = 0
|
||||||
current_event = player.hanchan.event
|
current_event = player.hanchan.event
|
||||||
if not current_event.is_tournament:
|
if not current_event.is_tournament:
|
||||||
@@ -300,10 +304,10 @@ class KyuDanRanking(models.Model):
|
|||||||
return reverse('player-kyu-score', args=[self.user.username])
|
return reverse('player-kyu-score', args=[self.user.username])
|
||||||
|
|
||||||
def recalculate(self):
|
def recalculate(self):
|
||||||
'''
|
"""
|
||||||
Fetches all valid Hanchans from this Player and recalculates his
|
Fetches all valid Hanchans from this Player and recalculates his
|
||||||
Kyu/Dan Ranking.
|
Kyu/Dan Ranking.
|
||||||
'''
|
"""
|
||||||
logger.debug("recalculating Kyu/Dan punkte for %s...", self.user)
|
logger.debug("recalculating Kyu/Dan punkte for %s...", self.user)
|
||||||
valid_hanchans = Player.objects.valid_hanchans(user=self.user_id)
|
valid_hanchans = Player.objects.valid_hanchans(user=self.user_id)
|
||||||
valid_hanchans = valid_hanchans.order_by('hanchan__start')
|
valid_hanchans = valid_hanchans.order_by('hanchan__start')
|
||||||
@@ -326,10 +330,10 @@ class KyuDanRanking(models.Model):
|
|||||||
self.save(force_update=True)
|
self.save(force_update=True)
|
||||||
|
|
||||||
def update_points(self, player):
|
def update_points(self, player):
|
||||||
'''
|
"""
|
||||||
Berechne die Kyu bzw. Dan Punkte für ein Spiel neu.
|
Berechne die Kyu bzw. Dan Punkte für ein Spiel neu.
|
||||||
:param player: Das Player Objekt das neuberechnet werden soll.
|
:param player: Das Player Objekt das neuberechnet werden soll.
|
||||||
'''
|
"""
|
||||||
player.bonus_points = 0
|
player.bonus_points = 0
|
||||||
player.comment = ""
|
player.comment = ""
|
||||||
player.dan_points = None
|
player.dan_points = None
|
||||||
@@ -403,7 +407,7 @@ class KyuDanRanking(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
class LadderRanking(models.Model):
|
class LadderRanking(models.Model):
|
||||||
user = models.ForeignKey(User)
|
user = models.ForeignKey(settings.AUTH_USER_MODEL)
|
||||||
season = models.ForeignKey('LadderSeason')
|
season = models.ForeignKey('LadderSeason')
|
||||||
placement = models.PositiveIntegerField(blank=True, null=True)
|
placement = models.PositiveIntegerField(blank=True, null=True)
|
||||||
avg_placement = models.FloatField(blank=True, null=True)
|
avg_placement = models.FloatField(blank=True, null=True)
|
||||||
@@ -441,9 +445,9 @@ class LadderRanking(models.Model):
|
|||||||
class LadderSeasonManager(models.Manager):
|
class LadderSeasonManager(models.Manager):
|
||||||
|
|
||||||
def current(self):
|
def current(self):
|
||||||
'''
|
"""
|
||||||
Returns the current season and caches the result for 12 hours
|
Returns the current season and caches the result for 12 hours
|
||||||
'''
|
"""
|
||||||
current_season = cache.get('current_mahjong_season')
|
current_season = cache.get('current_mahjong_season')
|
||||||
if not current_season:
|
if not current_season:
|
||||||
try:
|
try:
|
||||||
@@ -456,10 +460,10 @@ class LadderSeasonManager(models.Manager):
|
|||||||
return current_season
|
return current_season
|
||||||
|
|
||||||
def get_by_date(self, deadline):
|
def get_by_date(self, deadline):
|
||||||
'''
|
"""
|
||||||
returns the season that where running on the given date.
|
returns the season that where running on the given date.
|
||||||
:param deadline: the date you're intrested in
|
:param deadline: the date you're intrested in
|
||||||
'''
|
"""
|
||||||
try:
|
try:
|
||||||
season = self.filter(start__lte=deadline, end__gte=deadline)
|
season = self.filter(start__lte=deadline, end__gte=deadline)
|
||||||
return season[0]
|
return season[0]
|
||||||
@@ -468,9 +472,9 @@ class LadderSeasonManager(models.Manager):
|
|||||||
|
|
||||||
|
|
||||||
class LadderSeason(models.Model):
|
class LadderSeason(models.Model):
|
||||||
u'''
|
u"""
|
||||||
Eine Saison für das Kasu interne Ladder-Ranking.
|
Eine Saison für das Kasu interne Ladder-Ranking.
|
||||||
'''
|
"""
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(max_length=100)
|
||||||
start = models.DateField()
|
start = models.DateField()
|
||||||
end = models.DateField()
|
end = models.DateField()
|
||||||
@@ -488,10 +492,13 @@ class LadderSeason(models.Model):
|
|||||||
def recalculate(self):
|
def recalculate(self):
|
||||||
logger.info(u'Recalculate LadderSeason %s', self.name)
|
logger.info(u'Recalculate LadderSeason %s', self.name)
|
||||||
self.ladderranking_set.update(placement=None)
|
self.ladderranking_set.update(placement=None)
|
||||||
|
ladderrankings_for_placement = self.ladderranking_set.filter(
|
||||||
|
hanchan_count__gt=MIN_HANCHANS_FOR_LADDER
|
||||||
|
).order_by(
|
||||||
|
'avg_placement', '-avg_score'
|
||||||
|
)
|
||||||
placement = 1
|
placement = 1
|
||||||
ladder_rankings = self.ladderranking_set.filter(hanchan_count__gt=MIN_HANCHANS_FOR_LADDER) # @IgnorePep8
|
for ranking in ladderrankings_for_placement:
|
||||||
ladder_rankings = ladder_rankings.order_by('avg_placement', '-avg_score') # @IgnorePep8
|
|
||||||
for ranking in ladder_rankings:
|
|
||||||
ranking.placement = placement
|
ranking.placement = placement
|
||||||
ranking.save(force_update=True)
|
ranking.save(force_update=True)
|
||||||
placement += 1
|
placement += 1
|
||||||
@@ -556,12 +563,28 @@ class PlayerManager(models.Manager):
|
|||||||
|
|
||||||
class Player(models.Model):
|
class Player(models.Model):
|
||||||
hanchan = models.ForeignKey(Hanchan)
|
hanchan = models.ForeignKey(Hanchan)
|
||||||
user = models.ForeignKey(User)
|
user = models.ForeignKey(settings.AUTH_USER_MODEL)
|
||||||
score = models.PositiveIntegerField(default=0)
|
score = models.PositiveIntegerField(default=0)
|
||||||
placement = models.PositiveSmallIntegerField(blank=True, null=True, default=None) # @IgnorePep8
|
placement = models.PositiveSmallIntegerField(
|
||||||
kyu_points = models.PositiveSmallIntegerField(blank=True, null=True, default=None) # @IgnorePep8
|
blank=True,
|
||||||
dan_points = models.PositiveSmallIntegerField(blank=True, null=True, default=None) # @IgnorePep8
|
null=True,
|
||||||
bonus_points = models.PositiveSmallIntegerField(blank=True, null=True, default=0) # @IgnorePep8
|
default=None
|
||||||
|
)
|
||||||
|
kyu_points = models.PositiveSmallIntegerField(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
default=None
|
||||||
|
)
|
||||||
|
dan_points = models.PositiveSmallIntegerField(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
default=None
|
||||||
|
)
|
||||||
|
bonus_points = models.PositiveSmallIntegerField(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
default=0
|
||||||
|
)
|
||||||
comment = models.TextField(_('Comment'), blank=True)
|
comment = models.TextField(_('Comment'), blank=True)
|
||||||
objects = PlayerManager()
|
objects = PlayerManager()
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
{% for player in hanchan.player_set.all %}
|
{% for player in hanchan.player_set.all %}
|
||||||
<div class="player" >
|
<div class="player" >
|
||||||
<a href="{% url 'player-ladder-score' player.user %}"><img
|
<a href="{% url 'player-ladder-score' player.user %}"><img
|
||||||
{% if player.user.get_profile.thumbnail %}src="{{player.user.get_profile.thumbnail.url}}"{% else %}src="{{STATIC_URL}}img/unknown_thumbnail.png"{% endif %}
|
src="{% if player.user.get_profile.thumbnail %}{{player.user.get_profile.thumbnail.url}}{% else %}{{STATIC_URL}}img/unknown_thumbnail.png{% endif %}"
|
||||||
class="avatar" alt=""
|
class="avatar" alt=""
|
||||||
title="{% if player.dan_points != None %}Dan P.: {{player.dan_points}}{% else %}Kyu P.: {{player.kyu_points}}{% endif %} - {{player.comment}}"/></a>
|
title="{% if player.dan_points != None %}Dan P.: {{player.dan_points}}{% else %}Kyu P.: {{player.kyu_points}}{% endif %} - {{player.comment}}"/></a>
|
||||||
<h4>{{player.placement}}. - <a href="{% url 'player-ladder-score' player.user %}">{{ player.user }}</a></h4>
|
<h4>{{player.placement}}. - <a href="{% url 'player-ladder-score' player.user %}">{{ player.user }}</a></h4>
|
||||||
|
|||||||
@@ -2,9 +2,8 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block additional_nav_elements %}
|
{% block additional_nav_elements %}
|
||||||
<a href="{% url 'season_ranking-archive' %}" {% if is_archive %}class="active"{% endif %}>{% trans 'Archive' %}</a>
|
<a href="{% url 'season_ranking-archive' %}" class="{% if is_archive %}active{% endif %}">{% trans 'Archive' %}</a>
|
||||||
{% if perms.events.add_event %}
|
{% if perms.events.add_event %}
|
||||||
<a href="{% url 'event-form' %}" {% ifequal request.path '/events/add/' %}class="active"{% endifequal %}>{% trans 'Add Event' %}</a>
|
<a href="{% url 'event-form' %}" class="{% ifequal request.path '/events/add/' %}active{% endifequal %}">{% trans 'Add Event' %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th rowspan="2">{% trans 'Date' %}</th>
|
<th rowspan="2">{% trans 'Date' %}</th>
|
||||||
<th rowspan="2">{% trans 'Event' %}</th>
|
<th rowspan="2">{% trans 'Event' %}</th>
|
||||||
<th rowspan="2">{% trans 'Start' %}<//th>
|
<th rowspan="2">{% trans 'Start' %}</th>
|
||||||
<th rowspan="2">{% trans 'Placement' %}</th>
|
<th rowspan="2">{% trans 'Placement' %}</th>
|
||||||
<th colspan="4">{% trans 'Players' %}</th>
|
<th colspan="4">{% trans 'Players' %}</th>
|
||||||
<th rowspan="2">{% trans 'Dan Points' %}</th>
|
<th rowspan="2">{% trans 'Dan Points' %}</th>
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>1.</th>
|
<th>1.</th>
|
||||||
<th>2.</th>
|
<th>2.</th>
|
||||||
<th>3.<//th>
|
<th>3.</th>
|
||||||
<th>4.</th>
|
<th>4.</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -46,10 +46,10 @@
|
|||||||
<td>{{ result.comment }}</td>
|
<td>{{ result.comment }}</td>
|
||||||
<td>
|
<td>
|
||||||
{% if perms.mahjong_ranking.delete_hanchan %}
|
{% if perms.mahjong_ranking.delete_hanchan %}
|
||||||
<a href="{% url 'delete-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_delete.png" alt="{% trans 'Delete' %}" title="{% trans 'Delete Hanchan' %}"/>
|
<a href="{% url 'delete-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_delete.png" alt="{% trans 'Delete' %}" title="{% trans 'Delete Hanchan' %}"/></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.mahjong_ranking.change_hanchan %}
|
{% if perms.mahjong_ranking.change_hanchan %}
|
||||||
<a href="{% url 'edit-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_edit.png" alt="{% trans 'Edit' %}" title="{% trans 'Edit Hanchan' %}"/>
|
<a href="{% url 'edit-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_edit.png" alt="{% trans 'Edit' %}" title="{% trans 'Edit Hanchan' %}"/></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<table>
|
<table>
|
||||||
<thead><tr>
|
<thead><tr>
|
||||||
<th>{% trans 'Event' %}</th>
|
<th>{% trans 'Event' %}</th>
|
||||||
<th>{% trans 'Start' %}<//th>
|
<th>{% trans 'Start' %}</th>
|
||||||
<th colspan="4">{% trans 'Players' %}</th>
|
<th colspan="4">{% trans 'Players' %}</th>
|
||||||
<th>{% trans 'Placement' %}</th>
|
<th>{% trans 'Placement' %}</th>
|
||||||
<th>{% trans 'Kyu Points' %}</th>
|
<th>{% trans 'Kyu Points' %}</th>
|
||||||
@@ -36,10 +36,10 @@
|
|||||||
<td>{{ result.comment }}</td>
|
<td>{{ result.comment }}</td>
|
||||||
<td>
|
<td>
|
||||||
{% if perms.mahjong_ranking.delete_hanchan %}
|
{% if perms.mahjong_ranking.delete_hanchan %}
|
||||||
<a href="{% url 'delete-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_delete.png" alt="{% trans 'Delete' %}" title="{% trans 'Delete Hanchan' %}"/>
|
<a href="{% url 'delete-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_delete.png" alt="{% trans 'Delete' %}" title="{% trans 'Delete Hanchan' %}"/></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.mahjong_ranking.change_hanchan %}
|
{% if perms.mahjong_ranking.change_hanchan %}
|
||||||
<a href="{% url 'edit-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_edit.png" alt="{% trans 'Edit' %}" title="{% trans 'Edit Hanchan' %}"/>
|
<a href="{% url 'edit-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_edit.png" alt="{% trans 'Edit' %}" title="{% trans 'Edit Hanchan' %}"/></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th rowspan="2">{% trans 'Date' %}</th>
|
<th rowspan="2">{% trans 'Date' %}</th>
|
||||||
<th rowspan="2">{% trans 'Event' %}</th>
|
<th rowspan="2">{% trans 'Event' %}</th>
|
||||||
<th rowspan="2">{% trans 'Start' %}<//th>
|
<th rowspan="2">{% trans 'Start' %}</th>
|
||||||
<th rowspan="2">{% trans 'Placement' %}</th>
|
<th rowspan="2">{% trans 'Placement' %}</th>
|
||||||
<th colspan="4">{% trans 'Players' %}</th>
|
<th colspan="4">{% trans 'Players' %}</th>
|
||||||
<th rowspan="2">{% trans 'Kyu Points' %}</th>
|
<th rowspan="2">{% trans 'Kyu Points' %}</th>
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>1.</th>
|
<th>1.</th>
|
||||||
<th>2.</th>
|
<th>2.</th>
|
||||||
<th>3.<//th>
|
<th>3.</th>
|
||||||
<th>4.</th>
|
<th>4.</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -43,10 +43,10 @@
|
|||||||
<td class="center">{{result.kyu_points}}</td>
|
<td class="center">{{result.kyu_points}}</td>
|
||||||
<td>
|
<td>
|
||||||
{% if perms.mahjong_ranking.delete_hanchan %}
|
{% if perms.mahjong_ranking.delete_hanchan %}
|
||||||
<a href="{% url 'delete-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_delete.png" alt="{% trans 'Delete' %}" title="{% trans 'Delete Hanchan' %}"/>
|
<a href="{% url 'delete-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_delete.png" alt="{% trans 'Delete' %}" title="{% trans 'Delete Hanchan' %}"/></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.mahjong_ranking.change_hanchan %}
|
{% if perms.mahjong_ranking.change_hanchan %}
|
||||||
<a href="{% url 'edit-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_edit.png" alt="{% trans 'Edit' %}" title="{% trans 'Edit Hanchan' %}"/>
|
<a href="{% url 'edit-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_edit.png" alt="{% trans 'Edit' %}" title="{% trans 'Edit Hanchan' %}"/></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th rowspan="2">{% trans 'Date' %}</th>
|
<th rowspan="2">{% trans 'Date' %}</th>
|
||||||
<th rowspan="2">{% trans 'Event' %}</th>
|
<th rowspan="2">{% trans 'Event' %}</th>
|
||||||
<th rowspan="2">{% trans 'Start' %}<//th>
|
<th rowspan="2">{% trans 'Start' %}</th>
|
||||||
<th rowspan="2">{% trans 'Placement' %}</th>
|
<th rowspan="2">{% trans 'Placement' %}</th>
|
||||||
<th colspan="4">{% trans 'Players' %}</th>
|
<th colspan="4">{% trans 'Players' %}</th>
|
||||||
<th rowspan="2"></th>
|
<th rowspan="2"></th>
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>1.</th>
|
<th>1.</th>
|
||||||
<th>2.</th>
|
<th>2.</th>
|
||||||
<th>3.<//th>
|
<th>3.</th>
|
||||||
<th>4.</th>
|
<th>4.</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -42,10 +42,10 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
<td>
|
<td>
|
||||||
{% if perms.mahjong_ranking.delete_hanchan %}
|
{% if perms.mahjong_ranking.delete_hanchan %}
|
||||||
<a href="{% url 'delete-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_delete.png" alt="{% trans 'Delete' %}" title="{% trans 'Delete Hanchan' %}"/>
|
<a href="{% url 'delete-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_delete.png" alt="{% trans 'Delete' %}" title="{% trans 'Delete Hanchan' %}"/></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.mahjong_ranking.change_hanchan %}
|
{% if perms.mahjong_ranking.change_hanchan %}
|
||||||
<a href="{% url 'edit-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_edit.png" alt="{% trans 'Edit' %}" title="{% trans 'Edit Hanchan' %}"/>
|
<a href="{% url 'edit-hanchan' result.hanchan.pk %}"><img src="{{STATIC_URL}}icons/table_edit.png" alt="{% trans 'Edit' %}" title="{% trans 'Edit Hanchan' %}"/></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
'''
|
"""
|
||||||
Created on 03.10.2011
|
Created on 03.10.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from django.conf.urls import * # @UnusedWildImport
|
from django.conf.urls import * # @UnusedWildImport
|
||||||
import views
|
import views
|
||||||
|
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns(
|
||||||
url(r'^$',
|
'',
|
||||||
views.LadderRankingList.as_view(),
|
url(r'^$', views.LadderRankingList.as_view(), name="mahjong-ladder"),
|
||||||
name="mahjong-ladder"),
|
|
||||||
url(r'archive/$',
|
url(r'archive/$',
|
||||||
views.LadderRankingList.as_view(),
|
views.LadderRankingList.as_view(),
|
||||||
kwargs={'is_archive': True},
|
kwargs={'is_archive': True},
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
import urllib
|
||||||
|
|
||||||
from django.contrib import auth, messages
|
from django.contrib import auth, messages
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.http import HttpResponseRedirect, Http404
|
import django.forms
|
||||||
|
import django.http
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
from events.models import Event
|
|
||||||
from mahjong_ranking import forms, models
|
|
||||||
from utils.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
|
||||||
import django.forms
|
|
||||||
import xlwt
|
import xlwt
|
||||||
from django import http
|
|
||||||
import urllib
|
from events.models import Event
|
||||||
|
from . import forms, models
|
||||||
from membership.models import Membership
|
from membership.models import Membership
|
||||||
|
from utils.mixins import LoginRequiredMixin, PermissionRequiredMixin
|
||||||
|
|
||||||
|
|
||||||
kyu_dan_order = {
|
kyu_dan_order = {
|
||||||
'+full_name': ('user__last_name', 'user__first_name'),
|
'+full_name': ('user__last_name', 'user__first_name'),
|
||||||
@@ -29,10 +31,10 @@ kyu_dan_order = {
|
|||||||
|
|
||||||
|
|
||||||
class DeleteHanchan(PermissionRequiredMixin, generic.DeleteView):
|
class DeleteHanchan(PermissionRequiredMixin, generic.DeleteView):
|
||||||
'''
|
"""
|
||||||
Fragt zuerst nach, ob die Hanchan wirklich gelöscht werden soll.
|
Fragt zuerst nach, ob die Hanchan wirklich gelöscht werden soll.
|
||||||
Wir die Frage mit "Ja" beantwortet, wird die die Hanchan gelöscht.
|
Wir die Frage mit "Ja" beantwortet, wird die die Hanchan gelöscht.
|
||||||
'''
|
"""
|
||||||
form_class = forms.HanchanForm
|
form_class = forms.HanchanForm
|
||||||
model = models.Hanchan
|
model = models.Hanchan
|
||||||
permission_required = 'mahjong_ranking.delete_hanchan'
|
permission_required = 'mahjong_ranking.delete_hanchan'
|
||||||
@@ -44,10 +46,10 @@ class DeleteHanchan(PermissionRequiredMixin, generic.DeleteView):
|
|||||||
|
|
||||||
|
|
||||||
class HanchanForm(PermissionRequiredMixin, generic.UpdateView):
|
class HanchanForm(PermissionRequiredMixin, generic.UpdateView):
|
||||||
'''
|
"""
|
||||||
Ein Formular um eine neue Hanchan anzulegen, bzw. eine bestehende zu
|
Ein Formular um eine neue Hanchan anzulegen, bzw. eine bestehende zu
|
||||||
bearbeitsen
|
bearbeitsen
|
||||||
'''
|
"""
|
||||||
form_class = forms.HanchanForm
|
form_class = forms.HanchanForm
|
||||||
model = models.Hanchan
|
model = models.Hanchan
|
||||||
permission_required = 'mahjong_ranking.add_hanchan'
|
permission_required = 'mahjong_ranking.add_hanchan'
|
||||||
@@ -60,7 +62,7 @@ class HanchanForm(PermissionRequiredMixin, generic.UpdateView):
|
|||||||
else:
|
else:
|
||||||
formset.save()
|
formset.save()
|
||||||
self.object = form.save()
|
self.object = form.save()
|
||||||
return HttpResponseRedirect(self.get_success_url())
|
return django.http.HttpResponseRedirect(self.get_success_url())
|
||||||
|
|
||||||
def form_invalid(self, form, formset):
|
def form_invalid(self, form, formset):
|
||||||
return self.render_to_response(self.get_context_data(
|
return self.render_to_response(self.get_context_data(
|
||||||
@@ -106,10 +108,10 @@ class HanchanForm(PermissionRequiredMixin, generic.UpdateView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
'''
|
"""
|
||||||
|
|
||||||
:param request:
|
:param request:
|
||||||
'''
|
"""
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
form = self.get_form(self.get_form_class())
|
form = self.get_form(self.get_form_class())
|
||||||
formset = self.get_formset()
|
formset = self.get_formset()
|
||||||
@@ -131,9 +133,9 @@ class HanchanForm(PermissionRequiredMixin, generic.UpdateView):
|
|||||||
|
|
||||||
|
|
||||||
class EventHanchanList(generic.ListView):
|
class EventHanchanList(generic.ListView):
|
||||||
'''
|
"""
|
||||||
Auflistung aller Hanchan die während der Veranstaltung gespielt wurden.
|
Auflistung aller Hanchan die während der Veranstaltung gespielt wurden.
|
||||||
'''
|
"""
|
||||||
model = models.Hanchan
|
model = models.Hanchan
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
@@ -144,7 +146,7 @@ class EventHanchanList(generic.ListView):
|
|||||||
queryset = queryset.order_by('start')
|
queryset = queryset.order_by('start')
|
||||||
return queryset
|
return queryset
|
||||||
except models.Event.DoesNotExist:
|
except models.Event.DoesNotExist:
|
||||||
raise Http404(_('Event does not exist'))
|
raise django.http.Http404(_('Event does not exist'))
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = generic.ListView.get_context_data(self, **kwargs)
|
context = generic.ListView.get_context_data(self, **kwargs)
|
||||||
@@ -153,10 +155,10 @@ class EventHanchanList(generic.ListView):
|
|||||||
|
|
||||||
|
|
||||||
class EventRankingList(generic.ListView):
|
class EventRankingList(generic.ListView):
|
||||||
'''
|
"""
|
||||||
Anzeige des Eventrankings, daß erstellt wurde falls der Termin als internes
|
Anzeige des Eventrankings, daß erstellt wurde falls der Termin als internes
|
||||||
Turnier markiert wurde.
|
Turnier markiert wurde.
|
||||||
'''
|
"""
|
||||||
model = models.EventRanking
|
model = models.EventRanking
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
@@ -166,7 +168,7 @@ class EventRankingList(generic.ListView):
|
|||||||
queryset = queryset.prefetch_related()
|
queryset = queryset.prefetch_related()
|
||||||
return queryset
|
return queryset
|
||||||
except models.Event.DoesNotExist:
|
except models.Event.DoesNotExist:
|
||||||
raise Http404(_('Event does not exist'))
|
raise django.http.Http404(_('Event does not exist'))
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = generic.ListView.get_context_data(self, **kwargs)
|
context = generic.ListView.get_context_data(self, **kwargs)
|
||||||
@@ -175,10 +177,9 @@ class EventRankingList(generic.ListView):
|
|||||||
|
|
||||||
|
|
||||||
class KyuDanRankingList(generic.ListView):
|
class KyuDanRankingList(generic.ListView):
|
||||||
'''
|
"""
|
||||||
Anzeige aller Spiele mit ihrem Kyu bzw Dan Grad.
|
Anzeige aller Spiele mit ihrem Kyu bzw Dan Grad.
|
||||||
'''
|
"""
|
||||||
models.KyuDanRanking
|
|
||||||
default_order = '-score'
|
default_order = '-score'
|
||||||
order_by = ''
|
order_by = ''
|
||||||
paginate_by = 25
|
paginate_by = 25
|
||||||
@@ -213,7 +214,7 @@ class LadderRankingList(generic.ListView):
|
|||||||
else:
|
else:
|
||||||
self.season = models.LadderSeason.objects.current()
|
self.season = models.LadderSeason.objects.current()
|
||||||
except models.LadderSeason.DoesNotExist:
|
except models.LadderSeason.DoesNotExist:
|
||||||
raise Http404(_('Season does not exist'))
|
raise django.http.Http404(_('Season does not exist'))
|
||||||
queryset = models.LadderRanking.objects.filter(season=self.season, placement__isnull=False).select_related()
|
queryset = models.LadderRanking.objects.filter(season=self.season, placement__isnull=False).select_related()
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
@@ -238,7 +239,7 @@ class LadderRankingExcel(generic.View):
|
|||||||
|
|
||||||
def get(self, request, **kwargs):
|
def get(self, request, **kwargs):
|
||||||
self.queryset = self.team.members.all()
|
self.queryset = self.team.members.all()
|
||||||
response = http.HttpResponse(mimetype=u'application/msexcel')
|
response = django.http.HttpResponse(mimetype=u'application/msexcel')
|
||||||
|
|
||||||
filename = urllib.quote(self.filename.encode('utf-8'))
|
filename = urllib.quote(self.filename.encode('utf-8'))
|
||||||
response['Content-Disposition'] = "attachment; filename*=UTF-8''%s" % filename
|
response['Content-Disposition'] = "attachment; filename*=UTF-8''%s" % filename
|
||||||
@@ -277,12 +278,11 @@ class LadderRankingExcel(generic.View):
|
|||||||
self.set_col(sheet, current_row, 9, profile.weight or None)
|
self.set_col(sheet, current_row, 9, profile.weight or None)
|
||||||
self.set_col(sheet, current_row, 10, profile.emergency_contact or None)
|
self.set_col(sheet, current_row, 10, profile.emergency_contact or None)
|
||||||
self.set_col(sheet, current_row, 11, profile.emergency_phone or None)
|
self.set_col(sheet, current_row, 11, profile.emergency_phone or None)
|
||||||
except models.MemberProfile.DoesNotExist:
|
except Membership.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
current_row += 1
|
current_row += 1
|
||||||
|
|
||||||
for column in range(0, 13):
|
for column in range(0, 13):
|
||||||
print column, self.max_colwidth[column]
|
|
||||||
sheet.col(column).width = (self.max_colwidth[column] + 1) * 256
|
sheet.col(column).width = (self.max_colwidth[column] + 1) * 256
|
||||||
|
|
||||||
workbook.save(response)
|
workbook.save(response)
|
||||||
@@ -294,10 +294,10 @@ class PlayerScore(LoginRequiredMixin, generic.ListView):
|
|||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
try:
|
try:
|
||||||
self.user = auth.models.User.objects.get(username=self.kwargs.get('username'))
|
self.user = auth.get_user_model().objects.get(username=self.kwargs.get('username'))
|
||||||
self.membership = Membership.objects.get_or_create(user=self.user)[0]
|
self.membership = Membership.objects.get_or_create(user=self.user)[0]
|
||||||
except auth.models.User.DoesNotExist:
|
except auth.get_user_model().DoesNotExist:
|
||||||
raise Http404(_("No user found matching the name %s") % self.kwargs.get('username'))
|
raise django.http.Http404(_("No user found matching the name %s") % self.kwargs.get('username'))
|
||||||
return generic.ListView.get(self, request, *args, **kwargs)
|
return generic.ListView.get(self, request, *args, **kwargs)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
@@ -305,13 +305,13 @@ class PlayerScore(LoginRequiredMixin, generic.ListView):
|
|||||||
context['membership'] = self.membership
|
context['membership'] = self.membership
|
||||||
try:
|
try:
|
||||||
context['kyu_dan_ranking'] = models.KyuDanRanking.objects.get(user=self.user)
|
context['kyu_dan_ranking'] = models.KyuDanRanking.objects.get(user=self.user)
|
||||||
except:
|
except models.KyuDanRanking.DoesNotExist:
|
||||||
context['ranking'] = None
|
context['ranking'] = None
|
||||||
try:
|
try:
|
||||||
context['ladder_ranking'] = models.LadderRanking.objects.get(
|
context['ladder_ranking'] = models.LadderRanking.objects.get(
|
||||||
user=self.user,
|
user=self.user,
|
||||||
season=models.LadderSeason.objects.current())
|
season=models.LadderSeason.objects.current())
|
||||||
except:
|
except models.LadderRanking.DoesNotExist:
|
||||||
context['ladder_ranking'] = models.LadderRanking(user=self.user)
|
context['ladder_ranking'] = models.LadderRanking(user=self.user)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
@@ -343,10 +343,8 @@ class PlayerLadderScore(PlayerScore):
|
|||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = PlayerScore.get_context_data(self, **kwargs)
|
context = PlayerScore.get_context_data(self, **kwargs)
|
||||||
|
|
||||||
season_list = models.LadderRanking.objects.filter(user=self.user).select_related('user')
|
season_list = models.LadderRanking.objects.filter(user=self.user).select_related('user')
|
||||||
season_list = season_list.values_list('id', 'season__name')
|
season_list = season_list.values_list('id', 'season__name')
|
||||||
|
|
||||||
context['season'] = self.season
|
context['season'] = self.season
|
||||||
context['seasons_select_form'] = forms.SeasonSelectForm(user=self.user)
|
context['seasons_select_form'] = forms.SeasonSelectForm(user=self.user)
|
||||||
context['seasons_select_field'] = django.forms.ChoiceField(choices=season_list)
|
context['seasons_select_field'] = django.forms.ChoiceField(choices=season_list)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 19.09.2011
|
Created on 19.09.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
# import stuff we need from django
|
# import stuff we need from django
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from membership.models import Membership, ActivationRequest
|
from membership.models import Membership, ActivationRequest
|
||||||
@@ -15,6 +15,8 @@ def activate_user(modeladmin, request, queryset):
|
|||||||
membership = Membership.objects.get(username=activation.user.username)
|
membership = Membership.objects.get(username=activation.user.username)
|
||||||
membership.save()
|
membership.save()
|
||||||
activation.activate()
|
activation.activate()
|
||||||
|
|
||||||
|
|
||||||
activate_user.short_description = _('Activate selected User')
|
activate_user.short_description = _('Activate selected User')
|
||||||
|
|
||||||
|
|
||||||
@@ -22,6 +24,8 @@ def cleanup_activation(modeladmin, request, queryset):
|
|||||||
for activation in queryset:
|
for activation in queryset:
|
||||||
if activation.expired:
|
if activation.expired:
|
||||||
activation.user.delete()
|
activation.user.delete()
|
||||||
|
|
||||||
|
|
||||||
cleanup_activation.short_description = _("Cleanup selected Activation Requests")
|
cleanup_activation.short_description = _("Cleanup selected Activation Requests")
|
||||||
|
|
||||||
|
|
||||||
@@ -39,7 +43,8 @@ class MembershipAdmin(admin.ModelAdmin):
|
|||||||
)
|
)
|
||||||
list_editable = ('confirmed', 'paid_until',)
|
list_editable = ('confirmed', 'paid_until',)
|
||||||
list_display_links = ('nickname',)
|
list_display_links = ('nickname',)
|
||||||
fieldsets = ((None, {
|
fieldsets = (
|
||||||
|
(None, {
|
||||||
'fields': ('gender', ('first_name', 'last_name'), ('email', 'website'))
|
'fields': ('gender', ('first_name', 'last_name'), ('email', 'website'))
|
||||||
}),
|
}),
|
||||||
(_('Membership'), {
|
(_('Membership'), {
|
||||||
@@ -50,6 +55,8 @@ class MembershipAdmin(admin.ModelAdmin):
|
|||||||
)
|
)
|
||||||
ordering = ('nickname',)
|
ordering = ('nickname',)
|
||||||
search_fields = ('nickname', 'first_name', 'last_name',)
|
search_fields = ('nickname', 'first_name', 'last_name',)
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Membership, MembershipAdmin)
|
admin.site.register(Membership, MembershipAdmin)
|
||||||
|
|
||||||
|
|
||||||
@@ -59,4 +66,5 @@ class RegistrationAdmin(admin.ModelAdmin):
|
|||||||
search_fields = ('user__username', 'user__first_name')
|
search_fields = ('user__username', 'user__first_name')
|
||||||
actions = [cleanup_activation, activate_user]
|
actions = [cleanup_activation, activate_user]
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(ActivationRequest, RegistrationAdmin)
|
admin.site.register(ActivationRequest, RegistrationAdmin)
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
'''
|
"""
|
||||||
Created on 03.10.2011
|
Created on 03.10.2011
|
||||||
|
|
||||||
@author: Christian
|
@author: Christian
|
||||||
'''
|
"""
|
||||||
from . import models
|
from . import models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User
|
from django.contrib import auth
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from utils.html5 import forms
|
from utils.html5 import forms
|
||||||
@@ -26,29 +26,25 @@ class MembershipForm(forms.ModelForm):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def clean_birthday(self):
|
def clean_birthday(self):
|
||||||
if self.cleaned_data['membership'] \
|
if self.cleaned_data['membership'] and not self.cleaned_data['birthday']:
|
||||||
and not self.cleaned_data['birthday']:
|
|
||||||
raise forms.ValidationError(_('For your membership, we need this. \
|
raise forms.ValidationError(_('For your membership, we need this. \
|
||||||
Please fill out this field yet.'))
|
Please fill out this field yet.'))
|
||||||
return self.cleaned_data['birthday']
|
return self.cleaned_data['birthday']
|
||||||
|
|
||||||
def clean_telephone(self):
|
def clean_telephone(self):
|
||||||
if self.cleaned_data['membership'] \
|
if self.cleaned_data['membership'] and not self.cleaned_data['telephone']:
|
||||||
and not self.cleaned_data['telephone']:
|
|
||||||
raise forms.ValidationError(_('For your membership, we need this. \
|
raise forms.ValidationError(_('For your membership, we need this. \
|
||||||
Please fill out this field yet.'))
|
Please fill out this field yet.'))
|
||||||
return self.cleaned_data['telephone']
|
return self.cleaned_data['telephone']
|
||||||
|
|
||||||
def clean_street_name(self):
|
def clean_street_name(self):
|
||||||
if self.cleaned_data['membership'] \
|
if self.cleaned_data['membership'] and not self.cleaned_data['street_name']:
|
||||||
and not self.cleaned_data['street_name']:
|
|
||||||
raise forms.ValidationError(_('For your membership, we need this. \
|
raise forms.ValidationError(_('For your membership, we need this. \
|
||||||
Please fill out this field yet.'))
|
Please fill out this field yet.'))
|
||||||
return self.cleaned_data['street_name']
|
return self.cleaned_data['street_name']
|
||||||
|
|
||||||
def clean_post_code(self):
|
def clean_post_code(self):
|
||||||
if self.cleaned_data['membership'] \
|
if self.cleaned_data['membership'] and not self.cleaned_data['post_code']:
|
||||||
and not self.cleaned_data['post_code']:
|
|
||||||
raise forms.ValidationError(_('For your membership, we need this. \
|
raise forms.ValidationError(_('For your membership, we need this. \
|
||||||
Please fill out this field yet.'))
|
Please fill out this field yet.'))
|
||||||
return self.cleaned_data['post_code']
|
return self.cleaned_data['post_code']
|
||||||
@@ -87,25 +83,27 @@ class RegistrationForm(forms.ModelForm):
|
|||||||
recaptcha = forms.ReCaptchaField()
|
recaptcha = forms.ReCaptchaField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = auth.get_user_model()
|
||||||
fields = ('first_name', 'last_name', 'username', 'email',)
|
fields = ('first_name', 'last_name', 'username', 'email',)
|
||||||
|
|
||||||
def clean_username(self):
|
def clean_username(self):
|
||||||
'''
|
"""
|
||||||
Validate that the username is not already in use.
|
Validate that the username is not already in use.
|
||||||
'''
|
"""
|
||||||
try:
|
try:
|
||||||
User.objects.get(username__iexact=self.cleaned_data['username'])
|
auth.get_user_model().objects.get(
|
||||||
except User.DoesNotExist:
|
username__iexact=self.cleaned_data['username']
|
||||||
|
)
|
||||||
|
except auth.get_user_model().DoesNotExist:
|
||||||
return self.cleaned_data['username']
|
return self.cleaned_data['username']
|
||||||
raise forms.ValidationError(_(u'This username is already taken. \
|
raise forms.ValidationError(_(u'This username is already taken. \
|
||||||
Please choose another.'))
|
Please choose another.'))
|
||||||
|
|
||||||
def clean_email(self):
|
def clean_email(self):
|
||||||
'''
|
"""
|
||||||
Validate that the supplied email address is unique for the site.
|
Validate that the supplied email address is unique for the site.
|
||||||
'''
|
"""
|
||||||
if User.objects.filter(email__iexact=self.cleaned_data['email']):
|
if auth.get_user_model().objects.filter(email__iexact=self.cleaned_data['email']):
|
||||||
raise forms.ValidationError(_(u'This email address is already in \
|
raise forms.ValidationError(_(u'This email address is already in \
|
||||||
use. Please supply a different email address.'))
|
use. Please supply a different email address.'))
|
||||||
return self.cleaned_data['email']
|
return self.cleaned_data['email']
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
from django.utils.translation import ugettext_lazy as _
|
|
||||||
from membership.models import ActivationRequest
|
from membership.models import ActivationRequest
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = "Delete all expired user registrations from the database"
|
help = "Delete all expired user registrations from the database"
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
|
|
||||||
for activation in ActivationRequest.objects.expired():
|
for activation in ActivationRequest.objects.expired():
|
||||||
activation.user.delete()
|
activation.user.delete()
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ It might help your debugging to know or you might want to contact the user to
|
|||||||
tell them you have fixed the problem.
|
tell them you have fixed the problem.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.conf import settings
|
||||||
|
from django.contrib import auth
|
||||||
from django.contrib.sessions.models import Session
|
from django.contrib.sessions.models import Session
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand
|
||||||
from django.utils.translation import ugettext_lazy as _
|
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
|
|
||||||
|
|
||||||
@@ -19,29 +19,32 @@ class Command(BaseCommand):
|
|||||||
args = '<session_key session_key ...>'
|
args = '<session_key session_key ...>'
|
||||||
help = 'If the session still exists find it and show the related User'
|
help = 'If the session still exists find it and show the related User'
|
||||||
option_list = BaseCommand.option_list + (
|
option_list = BaseCommand.option_list + (
|
||||||
make_option('--delete',
|
make_option(
|
||||||
|
'--delete',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='delete',
|
dest='delete',
|
||||||
default=False,
|
default=False,
|
||||||
help='Delete the Useraccount'),
|
help='Delete the Useraccount'
|
||||||
make_option('--ban',
|
),
|
||||||
|
make_option(
|
||||||
|
'--ban',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='ban',
|
dest='ban',
|
||||||
default=False,
|
default=False,
|
||||||
help='Ban the Useraccount'),
|
help='Ban the Useraccount'
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
for session_key in args:
|
for session_key in args:
|
||||||
try:
|
try:
|
||||||
session = Session.objects.get(session_key=session_key)
|
session = Session.objects.get(session_key=session_key)
|
||||||
uid = session.get_decoded().get('_auth_user_id')
|
uid = session.get_decoded().get('_auth_user_id')
|
||||||
user = User.objects.get(pk=uid)
|
user = auth.get_user_model().objects.get(pk=uid)
|
||||||
except Session.DoesNotExist:
|
except Session.DoesNotExist:
|
||||||
self.stderr.write('Session "%s" does not exist' % session_key)
|
self.stderr.write('Session "%s" does not exist' % session_key)
|
||||||
continue
|
continue
|
||||||
except User.DoesNotExist:
|
except settings.AUTH_USER_MODEL.DoesNotExist:
|
||||||
self.stderr.write('Session "%s" has no registed User' % session_key)
|
self.stderr.write('Session "%s" has no registed User' % session_key)
|
||||||
continue
|
continue
|
||||||
if options['delete']:
|
if options['delete']:
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ from . import PAID_MEMBERSHIP_GROUP
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from django.core.exceptions import FieldError
|
from django.core.exceptions import FieldError
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@@ -23,29 +22,29 @@ GENDER_CHOICES = (
|
|||||||
|
|
||||||
|
|
||||||
def get_upload_path(instance, filename):
|
def get_upload_path(instance, filename):
|
||||||
'''
|
"""
|
||||||
Erstellt den Pfad und Dateinamen für den Upload dynmisch.
|
Erstellt den Pfad und Dateinamen für den Upload dynmisch.
|
||||||
|
|
||||||
@param instance: The Membership Object for the uploaded image
|
@param instance: The Membership Object for the uploaded image
|
||||||
@param filename: the filename of the uploaded image
|
@param filename: the filename of the uploaded image
|
||||||
'''
|
"""
|
||||||
extension = path.splitext(filename)[1]
|
extension = path.splitext(filename)[1]
|
||||||
return 'membership/%s%s' % (instance.user.username, extension)
|
return 'membership/%s%s' % (instance.user.username, extension)
|
||||||
|
|
||||||
|
|
||||||
class ActivationManager(models.Manager):
|
class ActivationManager(models.Manager):
|
||||||
'''
|
"""
|
||||||
Manages pending user registrations
|
Manages pending user registrations
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def activate(self, activation_key):
|
def activate(self, activation_key):
|
||||||
'''
|
"""
|
||||||
searches the pending registrations for the given activation key.
|
searches the pending registrations for the given activation key.
|
||||||
Set the corresponding user to active, if the key was found
|
Set the corresponding user to active, if the key was found
|
||||||
and the key has not expired yet.s
|
and the key has not expired yet.s
|
||||||
|
|
||||||
@param activation_key: the key found in the activation email
|
@param activation_key: the key found in the activation email
|
||||||
'''
|
"""
|
||||||
try:
|
try:
|
||||||
activation_request = self.get(activation_key=activation_key)
|
activation_request = self.get(activation_key=activation_key)
|
||||||
if activation_request.expired():
|
if activation_request.expired():
|
||||||
@@ -61,10 +60,10 @@ class ActivationManager(models.Manager):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def create_pending_registration(self, user):
|
def create_pending_registration(self, user):
|
||||||
'''
|
"""
|
||||||
creates a PendingActivation instance with an random activation key.
|
creates a PendingActivation instance with an random activation key.
|
||||||
@param user: the user that requests activation.
|
@param user: the user that requests activation.
|
||||||
'''
|
"""
|
||||||
salt = str(random.random())
|
salt = str(random.random())
|
||||||
activation_key = hashlib.sha1(salt + user.username).hexdigest()
|
activation_key = hashlib.sha1(salt + user.username).hexdigest()
|
||||||
|
|
||||||
@@ -78,12 +77,16 @@ class ActivationManager(models.Manager):
|
|||||||
|
|
||||||
|
|
||||||
class ActivationRequest(models.Model):
|
class ActivationRequest(models.Model):
|
||||||
'''
|
"""
|
||||||
Each ActivationRequest contains an activation key and an user.
|
Each ActivationRequest contains an activation key and an user.
|
||||||
The key will be send by email to the user
|
The key will be send by email to the user
|
||||||
if the user clicks on the link he can activate his in_active account.
|
if the user clicks on the link he can activate his in_active account.
|
||||||
'''
|
"""
|
||||||
user = models.ForeignKey(User, unique=True, verbose_name=_('user'))
|
user = models.ForeignKey(
|
||||||
|
settings.AUTH_USER_MODEL,
|
||||||
|
unique=True,
|
||||||
|
verbose_name=_('user')
|
||||||
|
)
|
||||||
activation_key = models.CharField(_('activation key'), max_length=40)
|
activation_key = models.CharField(_('activation key'), max_length=40)
|
||||||
objects = ActivationManager()
|
objects = ActivationManager()
|
||||||
|
|
||||||
@@ -115,6 +118,7 @@ class ActivationRequest(models.Model):
|
|||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
expired.boolean = True
|
expired.boolean = True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -135,28 +139,26 @@ class ActivationRequest(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
class MembershipManager(models.Manager):
|
class MembershipManager(models.Manager):
|
||||||
|
|
||||||
def get(self, *args, **kwargs):
|
def get(self, *args, **kwargs):
|
||||||
'''
|
"""
|
||||||
First try's to fetch the requested Membership Object from the Database,
|
First try's to fetch the requested Membership Object from the Database,
|
||||||
if the requestetd Membership does not Exists (yet) try to fetch the
|
if the requestetd Membership does not Exists (yet) try to fetch the
|
||||||
corresponding User, and create the Membership with the filled in
|
corresponding User, and create the Membership with the filled in
|
||||||
Userdata.
|
Userdata.
|
||||||
'''
|
"""
|
||||||
try:
|
try:
|
||||||
if 'username' in kwargs:
|
if 'username' in kwargs:
|
||||||
return models.Manager.get(self,
|
return models.Manager.get(self,
|
||||||
user__username=kwargs['username']
|
user__username=kwargs['username'])
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
return models.Manager.get(self, *args, **kwargs)
|
return models.Manager.get(self, *args, **kwargs)
|
||||||
except FieldError:
|
except FieldError:
|
||||||
user = User.objects.get(*args, **kwargs)
|
user = settings.AUTH_USER_MODEL.objects.get(*args, **kwargs)
|
||||||
except Membership.DoesNotExist:
|
except Membership.DoesNotExist:
|
||||||
if 'user' in kwargs:
|
if 'user' in kwargs:
|
||||||
user = User.objects.get(pk=kwargs['user'].id)
|
user = settings.AUTH_USER_MODEL.objects.get(pk=kwargs['user'].id)
|
||||||
else:
|
else:
|
||||||
user = User.objects.get(*args, **kwargs)
|
user = settings.AUTH_USER_MODEL.objects.get(*args, **kwargs)
|
||||||
|
|
||||||
membership = Membership(
|
membership = Membership(
|
||||||
user=user,
|
user=user,
|
||||||
@@ -169,7 +171,10 @@ class MembershipManager(models.Manager):
|
|||||||
|
|
||||||
|
|
||||||
class Membership(models.Model):
|
class Membership(models.Model):
|
||||||
user = models.OneToOneField(User)
|
user = models.ForeignKey(
|
||||||
|
settings.AUTH_USER_MODEL,
|
||||||
|
unique=True
|
||||||
|
)
|
||||||
nickname = models.SlugField(_('Nickname'), unique=True)
|
nickname = models.SlugField(_('Nickname'), unique=True)
|
||||||
gender = models.CharField(
|
gender = models.CharField(
|
||||||
_("Gender"),
|
_("Gender"),
|
||||||
@@ -186,39 +191,46 @@ class Membership(models.Model):
|
|||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
membership = models.BooleanField(_('Membership'),
|
membership = models.BooleanField(
|
||||||
|
_('Membership'),
|
||||||
default=False,
|
default=False,
|
||||||
help_text=_('Yes, I confirm that I am in agreement with the statutes \
|
help_text=_('Yes, I confirm that I am in agreement with the statutes \
|
||||||
and would like to become a member.')
|
and would like to become a member.')
|
||||||
)
|
)
|
||||||
birthday = models.DateField(_("Birthday Date"), blank=True, null=True)
|
birthday = models.DateField(_("Birthday Date"), blank=True, null=True)
|
||||||
telephone = models.CharField(_("Telephone"),
|
telephone = models.CharField(
|
||||||
|
_("Telephone"),
|
||||||
max_length=30,
|
max_length=30,
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
street_name = models.CharField(_("Address"),
|
street_name = models.CharField(
|
||||||
|
_("Address"),
|
||||||
max_length=75,
|
max_length=75,
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
post_code = models.PositiveSmallIntegerField(_("Postcode"),
|
post_code = models.PositiveSmallIntegerField(
|
||||||
|
_("Postcode"),
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
city = models.CharField(_("Town/City"),
|
city = models.CharField(
|
||||||
|
_("Town/City"),
|
||||||
max_length=75,
|
max_length=75,
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True
|
null=True
|
||||||
)
|
)
|
||||||
deposit = models.PositiveSmallIntegerField(default=0, editable=False)
|
deposit = models.PositiveSmallIntegerField(default=0, editable=False)
|
||||||
registration_date = models.DateField(auto_now_add=True, editable=False)
|
registration_date = models.DateField(auto_now_add=True, editable=False)
|
||||||
paid_until = models.DateField(_('Paid until'),
|
paid_until = models.DateField(
|
||||||
|
_('Paid until'),
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
editable=True
|
editable=True
|
||||||
)
|
)
|
||||||
confirmed = models.BooleanField(_('Confirmed'),
|
confirmed = models.BooleanField(
|
||||||
|
_('Confirmed'),
|
||||||
default=False,
|
default=False,
|
||||||
help_text=_('This person has paid the membership fee.')
|
help_text=_('This person has paid the membership fee.')
|
||||||
)
|
)
|
||||||
@@ -258,7 +270,8 @@ class Membership(models.Model):
|
|||||||
self.email = self.user.email
|
self.email = self.user.email
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('membership-details',
|
return reverse(
|
||||||
|
'membership-details',
|
||||||
kwargs={'username': self.user.username}
|
kwargs={'username': self.user.username}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -7,15 +7,18 @@ class ResizeThumbnail(processors.Resize):
|
|||||||
height = 60
|
height = 60
|
||||||
crop = True
|
crop = True
|
||||||
|
|
||||||
|
|
||||||
class ResizeProfile(processors.Resize):
|
class ResizeProfile(processors.Resize):
|
||||||
width = 140
|
width = 140
|
||||||
height = 140
|
height = 140
|
||||||
crop = True
|
crop = True
|
||||||
|
|
||||||
|
|
||||||
class Thumbnail(ImageSpec):
|
class Thumbnail(ImageSpec):
|
||||||
pre_cache = True
|
pre_cache = True
|
||||||
processors = (ResizeThumbnail,)
|
processors = (ResizeThumbnail,)
|
||||||
|
|
||||||
|
|
||||||
class Profile(ImageSpec):
|
class Profile(ImageSpec):
|
||||||
pre_cache = False
|
pre_cache = False
|
||||||
processors = (ResizeProfile,)
|
processors = (ResizeProfile,)
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<table>
|
<table>
|
||||||
<thead><tr>
|
<thead><tr>
|
||||||
<th>{% trans 'Start' %}<//th>
|
<th>{% trans 'Start' %}</th>
|
||||||
<th>{% trans 'Event' %}</th>
|
<th>{% trans 'Event' %}</th>
|
||||||
<th colspan="4">{% trans 'Players' %}</th>
|
<th colspan="4">{% trans 'Players' %}</th>
|
||||||
<th>{% trans 'Kyu Points' %}</th>
|
<th>{% trans 'Kyu Points' %}</th>
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
'''
|
"""
|
||||||
Created on 03.10.2011
|
Created on 03.10.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from django.conf.urls import * # @UnusedWildImport
|
from django.conf.urls import * # @UnusedWildImport
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns(
|
||||||
|
'',
|
||||||
url('', include('social.apps.django_app.urls', namespace='social')),
|
url('', include('social.apps.django_app.urls', namespace='social')),
|
||||||
url('', include('django.contrib.auth.urls')),
|
url('', include('django.contrib.auth.urls')),
|
||||||
url(r'^register/$',
|
url(r'^register/$',
|
||||||
|
|||||||
@@ -4,16 +4,17 @@ from django.contrib import auth, messages
|
|||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
|
|
||||||
from mahjong_ranking.models import KyuDanRanking, LadderRanking, LadderSeason
|
from mahjong_ranking.models import KyuDanRanking, LadderRanking, LadderSeason
|
||||||
import forms
|
|
||||||
import models
|
|
||||||
from utils import mixins
|
from utils import mixins
|
||||||
|
|
||||||
|
from . import forms, models
|
||||||
|
|
||||||
|
|
||||||
class ActivateRegistration(generic.DetailView):
|
class ActivateRegistration(generic.DetailView):
|
||||||
'''
|
"""
|
||||||
Activates the Registration of an User and logs him in
|
Activates the Registration of an User and logs him in
|
||||||
'''
|
"""
|
||||||
template_name = 'membership/activation_error.html'
|
template_name = 'membership/activation_error.html'
|
||||||
|
|
||||||
def get(self, request, **kwargs):
|
def get(self, request, **kwargs):
|
||||||
@@ -79,7 +80,7 @@ class MembershipDetail(mixins.LoginRequiredMixin, generic.DetailView):
|
|||||||
|
|
||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
if self.kwargs.get('username'):
|
if self.kwargs.get('username'):
|
||||||
return models.Membership.objects.get(username=self.kwargs['username'])
|
return models.Membership.objects.get_or_create(username=self.kwargs['username'])[0]
|
||||||
elif self.request.user.is_authenticated():
|
elif self.request.user.is_authenticated():
|
||||||
return models.Membership.objects.get(user=self.request.user)
|
return models.Membership.objects.get(user=self.request.user)
|
||||||
|
|
||||||
@@ -88,13 +89,13 @@ class MembershipDetail(mixins.LoginRequiredMixin, generic.DetailView):
|
|||||||
try:
|
try:
|
||||||
context['kyu_dan_ranking'] = KyuDanRanking.objects.get(
|
context['kyu_dan_ranking'] = KyuDanRanking.objects.get(
|
||||||
user_id=self.object.user_id)
|
user_id=self.object.user_id)
|
||||||
except:
|
except KyuDanRanking.DoesNotExist:
|
||||||
context['kyu_dan_ranking'] = None
|
context['kyu_dan_ranking'] = None
|
||||||
try:
|
try:
|
||||||
context['ladder_ranking'] = LadderRanking.objects.get(
|
context['ladder_ranking'] = LadderRanking.objects.get(
|
||||||
user_id=self.object.user_id,
|
user_id=self.object.user_id,
|
||||||
season=LadderSeason.objects.current())
|
season=LadderSeason.objects.current())
|
||||||
except:
|
except LadderRanking.DoesNotExist:
|
||||||
context['ladder_ranking'] = LadderRanking(user=self.object.user)
|
context['ladder_ranking'] = LadderRanking(user=self.object.user)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,14 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<!DOCTYPE HTML>
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Kasu - {% block title %}{{ current_top_page.menu_name|default:"traditionelle asiatische Spielkultur"}}{% endblock %}</title>
|
<title>Kasu - {% block title %}{{ current_top_page.menu_name|default:"traditionelle asiatische Spielkultur"}}{% endblock %}</title>
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
</label>
|
</label>
|
||||||
{{form.comment}}
|
{{form.comment}}
|
||||||
<p class="buttonbar">
|
<p class="buttonbar">
|
||||||
<button type="submit" name="preview"><img src="{{ STATIC_URL }}icons/comment_edit.png" alt="{% trans "Preview" %}" /> {% trans "Preview" %}</button>
|
<button type="submit" name="preview"><img src="{{ STATIC_URL }}icons/comment_edit.png" alt="{% trans 'Preview' %}" /> {% trans "Preview" %}</button>
|
||||||
<button type="submit" name="submit"><img src="{{ STATIC_URL }}icons/comment_add.png" alt="{% trans "Post" %}" /> {% trans "Post" %}</button>
|
<button type="submit" name="submit"><img src="{{ STATIC_URL }}icons/comment_add.png" alt="{% trans 'Post' %}" /> {% trans "Post" %}</button>
|
||||||
</p>
|
</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
<label class="field_name" for="id_comment">
|
<label class="field_name" for="id_comment">
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ you can fill out our registration form.</p>
|
|||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
<p class="more_link">
|
<p class="more_link">
|
||||||
<a href="{% url 'membership-register' %}" class="button">
|
<a href="{% url 'membership-register' %}" class="button">
|
||||||
<img src="{{STATIC_URL}}icons/user_add.png" alt="{%trans "register"%}"/>
|
<img src="{{STATIC_URL}}icons/user_add.png" alt="{%trans 'register' %}"/>
|
||||||
{%trans "register"%}</a></p>
|
{%trans "register"%}</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ you can fill out our registration form.</p>
|
|||||||
<p><a href="{% url 'password_reset' %}">{% trans 'Forgot your Password?'%}</a></p>
|
<p><a href="{% url 'password_reset' %}">{% trans 'Forgot your Password?'%}</a></p>
|
||||||
<div class="buttonbar">
|
<div class="buttonbar">
|
||||||
<button type="submit">
|
<button type="submit">
|
||||||
<img src="{{STATIC_URL}}icons/lock_break.png" alt="{% trans "Login" %}" /> {% trans "Login" %}
|
<img src="{{STATIC_URL}}icons/lock_break.png" alt="{% trans 'Login' %}" /> {% trans 'Login' %}
|
||||||
</button></div>
|
</button></div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
{% include 'form.html' %}
|
{% include 'form.html' %}
|
||||||
<div class="buttonbar">
|
<div class="buttonbar">
|
||||||
<button type="submit">
|
<button type="submit">
|
||||||
<img src="{{STATIC_URL}}icons/lock_break.png" alt="{% trans "Login" %}" /> {% trans "Change Password" %}
|
<img src="{{STATIC_URL}}icons/lock_break.png" alt="{% trans 'Login' %}" /> {% trans "Change Password" %}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 28.09.2011
|
Created on 28.09.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from .countries import COUNTRIES
|
from .countries import COUNTRIES
|
||||||
from .html_cleaner import HtmlCleaner
|
from .html_cleaner import HtmlCleaner
|
||||||
from .massmailer import MassMailer
|
from .massmailer import MassMailer
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 24.11.2011
|
Created on 24.11.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from django import forms
|
from django import forms
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 08.05.2011
|
Created on 08.05.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@@ -17,10 +17,10 @@ from . import widgets
|
|||||||
|
|
||||||
class Html5Mixin(object):
|
class Html5Mixin(object):
|
||||||
def widget_attrs(self, widget):
|
def widget_attrs(self, widget):
|
||||||
'''
|
"""
|
||||||
Overwrites the standard Widget Attributes to add some HTML5 Stuff
|
Overwrites the standard Widget Attributes to add some HTML5 Stuff
|
||||||
:param widget: A Widget Object
|
:param widget: A Widget Object
|
||||||
'''
|
"""
|
||||||
attrs = super(Html5Mixin, self).widget_attrs(widget)
|
attrs = super(Html5Mixin, self).widget_attrs(widget)
|
||||||
if self.required and not isinstance(widget, widgets.CheckboxInput):
|
if self.required and not isinstance(widget, widgets.CheckboxInput):
|
||||||
attrs['required'] = 'required'
|
attrs['required'] = 'required'
|
||||||
@@ -199,9 +199,8 @@ class ReCaptchaField(django.forms.fields.CharField):
|
|||||||
self.required = True
|
self.required = True
|
||||||
super(ReCaptchaField, self).__init__(*args, **kwargs)
|
super(ReCaptchaField, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def _check_recaptcha(self, challenge_value, response_value, \
|
def _check_recaptcha(self, challenge_value, response_value, remote_ip):
|
||||||
remote_ip={}):
|
"""
|
||||||
'''
|
|
||||||
Submits a reCAPTCHA request for verification.
|
Submits a reCAPTCHA request for verification.
|
||||||
Returns RecaptchaResponse for the request
|
Returns RecaptchaResponse for the request
|
||||||
|
|
||||||
@@ -209,7 +208,7 @@ class ReCaptchaField(django.forms.fields.CharField):
|
|||||||
@param response_value: value of recaptcha_response_field
|
@param response_value: value of recaptcha_response_field
|
||||||
@param remoteip -- the user's ip address
|
@param remoteip -- the user's ip address
|
||||||
|
|
||||||
'''
|
"""
|
||||||
import urllib
|
import urllib
|
||||||
import urllib2
|
import urllib2
|
||||||
private_key = settings.RECAPTCHA_PRIVATE_KEY
|
private_key = settings.RECAPTCHA_PRIVATE_KEY
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 08.05.2011
|
Created on 08.05.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import ForeignKey, Model, SET_NULL # @UnusedImport
|
from django.db.models import ForeignKey, Model, SET_NULL # @UnusedImport
|
||||||
from django.db.models import SET_DEFAULT, ManyToManyField # @UnusedImport
|
from django.db.models import SET_DEFAULT, ManyToManyField # @UnusedImport
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 05.08.2011
|
Created on 05.08.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from . import registry
|
from . import registry
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 08.05.2011
|
Created on 08.05.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.forms import widgets
|
from django.forms import widgets
|
||||||
from django.forms.util import flatatt
|
from django.forms.util import flatatt
|
||||||
@@ -119,9 +119,9 @@ class RangeInput(widgets.TextInput):
|
|||||||
|
|
||||||
|
|
||||||
class ReCaptchaInput(widgets.Widget):
|
class ReCaptchaInput(widgets.Widget):
|
||||||
'''
|
"""
|
||||||
Der HTML Code von Googles ReCaptcha als Form Widget
|
Der HTML Code von Googles ReCaptcha als Form Widget
|
||||||
'''
|
"""
|
||||||
recaptcha_challenge_name = 'recaptcha_challenge_field'
|
recaptcha_challenge_name = 'recaptcha_challenge_field'
|
||||||
recaptcha_response_name = 'recaptcha_response_field'
|
recaptcha_response_name = 'recaptcha_response_field'
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 19.10.2011
|
Created on 19.10.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from BeautifulSoup import BeautifulSoup
|
from BeautifulSoup import BeautifulSoup
|
||||||
|
|
||||||
|
|
||||||
@@ -46,10 +46,10 @@ class HtmlCleaner(object):
|
|||||||
self.clean_attributes(tag)
|
self.clean_attributes(tag)
|
||||||
|
|
||||||
def clean_html(self, fragment=''):
|
def clean_html(self, fragment=''):
|
||||||
'''
|
"""
|
||||||
Reparses and cleans the html from XSS Attacks until it stops changing.
|
Reparses and cleans the html from XSS Attacks until it stops changing.
|
||||||
@param fragment:
|
@param fragment:
|
||||||
'''
|
"""
|
||||||
while True:
|
while True:
|
||||||
soup = BeautifulSoup(fragment)
|
soup = BeautifulSoup(fragment)
|
||||||
self.tag_removed = False
|
self.tag_removed = False
|
||||||
|
|||||||
@@ -653,17 +653,17 @@ class vDDDLists:
|
|||||||
self.dts = vDDD
|
self.dts = vDDD
|
||||||
|
|
||||||
def ical(self):
|
def ical(self):
|
||||||
'''
|
"""
|
||||||
Generates the text string in the iCalendar format.
|
Generates the text string in the iCalendar format.
|
||||||
'''
|
"""
|
||||||
dts_ical = [dt.ical() for dt in self.dts]
|
dts_ical = [dt.ical() for dt in self.dts]
|
||||||
return ",".join(dts_ical)
|
return ",".join(dts_ical)
|
||||||
|
|
||||||
def from_ical(ical):
|
def from_ical(ical):
|
||||||
'''
|
"""
|
||||||
Parses the list of data formats from ical text format.
|
Parses the list of data formats from ical text format.
|
||||||
@param ical: ical text format
|
@param ical: ical text format
|
||||||
'''
|
"""
|
||||||
out = []
|
out = []
|
||||||
ical_dates = ical.split(",")
|
ical_dates = ical.split(",")
|
||||||
for ical_dt in ical_dates:
|
for ical_dt in ical_dates:
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 06.06.2011
|
Created on 06.06.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
import fnmatch
|
import fnmatch
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
import os
|
import os
|
||||||
@@ -15,9 +15,9 @@ from django.utils.translation import ugettext as _
|
|||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
'''
|
"""
|
||||||
classdocs
|
classdocs
|
||||||
'''
|
"""
|
||||||
can_import_settings = True
|
can_import_settings = True
|
||||||
help = _("Reads raw CSS from stdin, and writes compressed CSS to stdout.")
|
help = _("Reads raw CSS from stdin, and writes compressed CSS to stdout.")
|
||||||
option_list = BaseCommand.option_list + (
|
option_list = BaseCommand.option_list + (
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 06.06.2011
|
Created on 06.06.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@@ -14,9 +14,9 @@ import jsmin
|
|||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
'''
|
"""
|
||||||
classdocs
|
classdocs
|
||||||
'''
|
"""
|
||||||
can_import_settings = True
|
can_import_settings = True
|
||||||
help = _("Reads raw CSS from stdin, and writes compressed CSS to stdout.")
|
help = _("Reads raw CSS from stdin, and writes compressed CSS to stdout.")
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
'''
|
"""
|
||||||
Created on 06.06.2011
|
Created on 06.06.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
@@ -13,9 +13,9 @@ from scss import parser
|
|||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
'''
|
"""
|
||||||
classdocs
|
classdocs
|
||||||
'''
|
"""
|
||||||
can_import_settings = True
|
can_import_settings = True
|
||||||
help = _("Compile SCSS rules.")
|
help = _("Compile SCSS rules.")
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ from django.template import loader, Context
|
|||||||
|
|
||||||
|
|
||||||
class MassMailer(object):
|
class MassMailer(object):
|
||||||
'''
|
"""
|
||||||
This Class will send E-Mails via an SMTP Connection to multiple recipients.
|
This Class will send E-Mails via an SMTP Connection to multiple recipients.
|
||||||
Each E-Mail will be send individually and can be personalized.
|
Each E-Mail will be send individually and can be personalized.
|
||||||
It will be send as HTML and Plain-Text Message.
|
It will be send as HTML and Plain-Text Message.
|
||||||
'''
|
"""
|
||||||
context = {}
|
context = {}
|
||||||
headers = {}
|
headers = {}
|
||||||
subject = None
|
subject = None
|
||||||
@@ -83,9 +83,9 @@ class MassMailer(object):
|
|||||||
self.headers[name] = value
|
self.headers[name] = value
|
||||||
|
|
||||||
def send(self):
|
def send(self):
|
||||||
'''
|
"""
|
||||||
Process the E-Mails and send them
|
Process the E-Mails and send them
|
||||||
'''
|
"""
|
||||||
self.process_mails()
|
self.process_mails()
|
||||||
if len(self.mail_queue) == 0:
|
if len(self.mail_queue) == 0:
|
||||||
self.log.info('No recipients for eMail "%s", bye!', self.subject)
|
self.log.info('No recipients for eMail "%s", bye!', self.subject)
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
'''
|
"""
|
||||||
Created on 23.05.2011
|
Created on 23.05.2011
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from django.utils.html import strip_spaces_between_tags
|
from django.utils.html import strip_spaces_between_tags
|
||||||
|
|
||||||
|
|
||||||
class CompressHtmlMiddleware(object):
|
class CompressHtmlMiddleware(object):
|
||||||
'''
|
"""
|
||||||
This Middleware compresses the HTML Output at the End. It strips the Spaces
|
This Middleware compresses the HTML Output at the End. It strips the Spaces
|
||||||
between Tags, an at the beginning and the end of the content.
|
between Tags, an at the beginning and the end of the content.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def process_response(self, request, response):
|
def process_response(self, request, response):
|
||||||
if 'text/html' in response['Content-Type']:
|
if 'text/html' in response['Content-Type']:
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class PermissionRequiredMixin(object):
|
|||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
# Verify class settings
|
# Verify class settings
|
||||||
if self.permission_required == None or len(self.permission_required.split(".")) != 2:
|
if self.permission_required is None or len(self.permission_required.split(".")) != 2:
|
||||||
raise ImproperlyConfigured("'PermissionRequiredMixin' requires 'permission_required' attribute to be set.")
|
raise ImproperlyConfigured("'PermissionRequiredMixin' requires 'permission_required' attribute to be set.")
|
||||||
has_permission = request.user.has_perm(self.permission_required)
|
has_permission = request.user.has_perm(self.permission_required)
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
'''
|
"""
|
||||||
Created on 25.11.2013
|
Created on 25.11.2013
|
||||||
|
|
||||||
@author: christian
|
@author: christian
|
||||||
'''
|
"""
|
||||||
from django import template
|
from django import template
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
|
|||||||
Reference in New Issue
Block a user