Skip to content

Commit

Permalink
(no ticket) Balloons
Browse files Browse the repository at this point in the history
Change-Id: Ie0f90a3f74a4d72cb73334a9a945f680b805dc7d
  • Loading branch information
accek authored and maciej-kisiel committed Oct 12, 2013
1 parent dcf3be5 commit ce7da7c
Show file tree
Hide file tree
Showing 20 changed files with 1,460 additions and 1 deletion.
Empty file added oioioi/balloons/__init__.py
Empty file.
98 changes: 98 additions & 0 deletions oioioi/balloons/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from oioioi.base import admin
from oioioi.balloons.models import ProblemBalloonsConfig, \
BalloonsDisplay
from oioioi.base.admin import system_admin_menu_registry
from oioioi.contests.models import ProblemInstance, Contest
from oioioi.contests.menu import contest_admin_menu_registry
from oioioi.contests.utils import is_contest_admin


class ProblemBalloonsConfigAdmin(admin.ModelAdmin):
list_display = ['problem_instance', 'color_display']
list_display_links = ['problem_instance']

def has_add_permission(self, request):
return is_contest_admin(request)

def has_change_permission(self, request, obj=None):
return is_contest_admin(request)

def has_delete_permission(self, request, obj=None):
return self.has_change_permission(request, obj)

def get_readonly_fields(self, request, obj=None):
if obj:
return self.readonly_fields + ('problem_instance',)
return self.readonly_fields

def color_display(self, instance):
return '<span class="balloons_admin" style="background: %s">%s</span>' \
% (instance.color, instance.color)
color_display.allow_tags = True
color_display.short_description = _("Color")

def queryset(self, request):
qs = super(ProblemBalloonsConfigAdmin, self).queryset(request)
return qs.filter(problem_instance__contest=request.contest)

def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'problem_instance':
qs = ProblemInstance.objects
if request.contest:
qs = qs.filter(contest=request.contest)
kwargs['queryset'] = qs
return super(ProblemBalloonsConfigAdmin, self) \
.formfield_for_foreignkey(db_field, request, **kwargs)

admin.site.register(ProblemBalloonsConfig, ProblemBalloonsConfigAdmin)
contest_admin_menu_registry.register('problemballoonsconfig_admin',
_("Balloons colors"), lambda request:
reverse('oioioiadmin:balloons_problemballoonsconfig_changelist'),
order=60)


class BalloonsDisplayAdmin(admin.ModelAdmin):
list_display = ['ip_addr', 'user']

def has_add_permission(self, request):
return is_contest_admin(request)

def has_change_permission(self, request, obj=None):
return is_contest_admin(request)

def has_delete_permission(self, request, obj=None):
return self.has_change_permission(request, obj)

def get_readonly_fields(self, request, obj=None):
if obj:
return self.readonly_fields + ('contest',)
return self.readonly_fields

def queryset(self, request):
qs = super(BalloonsDisplayAdmin, self).queryset(request)
if request.contest is None:
return qs
return qs.filter(contest=request.contest)

def formfield_for_foreignkey(self, db_field, request, **kwargs):
if request.contest is not None:
if db_field.name == 'contest':
qs = Contest.objects.filter(id=request.contest.id)
kwargs['initial'] = request.contest
kwargs['queryset'] = qs
elif db_field.name == 'user':
qs = User.objects.filter(participant__contest=request.contest)
if qs or not request.user.is_superuser:
kwargs['queryset'] = qs

return super(BalloonsDisplayAdmin, self) \
.formfield_for_foreignkey(db_field, request, **kwargs)

admin.site.register(BalloonsDisplay, BalloonsDisplayAdmin)
system_admin_menu_registry.register('balloonsdisplay_admin',
_("Balloons displays"), lambda request:
reverse('oioioiadmin:balloons_balloonsdisplay_changelist'),
order=60)
Empty file.
Empty file.
98 changes: 98 additions & 0 deletions oioioi/balloons/management/commands/import_balloons_displays.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand, CommandError
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _
from django.db import transaction, DatabaseError
from oioioi.contests.models import Contest
from oioioi.balloons.models import BalloonsDisplay
import os
import csv
import urllib2


class Command(BaseCommand):
COLUMNS = ['username', 'ip_addr']
columns_str = ', '.join(COLUMNS)

args = _("<contest_id> <filename_or_url>")
help = _("Updates the list of balloons displays of <contest_id> from the "
"given CSV file <filename or url>, with the following columns: "
"%(columns)s.\n\n"
"Given csv file should contain a header row with columns' names "
"(respectively %(columns)s) separeted by commas."
) % {'columns': columns_str}

requires_model_validation = True

def handle(self, *args, **options):
if len(args) != 2:
raise CommandError(_("Expected two arguments"))

try:
contest = Contest.objects.get(id=args[0])
except Contest.DoesNotExist:
raise CommandError(_("Contest %s does not exist") % args[0])

arg = args[1]

if arg.startswith('http://') or arg.startswith('https://'):
self.stdout.write(_("Fetching %s...\n") % (arg,))
stream = urllib2.urlopen(arg)
else:
if not os.path.exists(arg):
raise CommandError(_("File not found: ") + arg)
stream = open(arg, 'r')

reader = csv.reader(stream)
header = reader.next()
if header != self.COLUMNS:
raise CommandError(_("Missing header or invalid columns: "
"%(header)s\nExpected: %(expected)s") % {
'header': ', '.join(header),
'expected': ', '.join(self.COLUMNS)})

with transaction.commit_on_success():
BalloonsDisplay.objects.filter(contest=contest).delete()

ok = True
all_count = 0
for row in reader:
all_count += 1

for i, column in enumerate(self.COLUMNS):
row[i] = row[i].decode('utf8')

try:
user = User.objects.get(username=row[0])
display = BalloonsDisplay(ip_addr=row[1], user=user,
contest=contest)
display.save()
except User.DoesNotExist:
self.stdout.write(_("Error for user=%(user)s: user does"
" not exist\n") % {'user': row[1]})
ok = False
except DatabaseError, e:
self.stdout.write(_(
"DB Error for user=%(user)s: %(message)s\n")
% {'user': row[1], 'message': e.message})
ok = False
except ValidationError, e:
for k, v in e.message_dict.iteritems():
for message in v:
if k == '__all__':
self.stdout.write(_(
"Error for user=%(user)s: %s\n")
% (row[1], message))
else:
self.stdout.write(
_("Error for user=%(user)s, "
"field %(field)s: %(message)s\n")
% {'user': row[1], 'field': k,
'message': message})
ok = False

if ok:
self.stdout.write(_("Processed %d entries") % (all_count))
else:
raise CommandError(_("There were some errors. Database not "
"changed.\n"))
72 changes: 72 additions & 0 deletions oioioi/balloons/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):

depends_on = (
("contests", "0013_auto__add_field_contestattachment_round"),
)

def forwards(self, orm):
# Adding model 'ProblemBalloonsConfig'
db.create_table(u'balloons_problemballoonsconfig', (
('problem_instance', self.gf('django.db.models.fields.related.OneToOneField')(related_name='balloons_config', unique=True, primary_key=True, to=orm['contests.ProblemInstance'])),
('color', self.gf('oioioi.base.utils.color.ColorField')(max_length=7)),
))
db.send_create_signal(u'balloons', ['ProblemBalloonsConfig'])


def backwards(self, orm):
# Deleting model 'ProblemBalloonsConfig'
db.delete_table(u'balloons_problemballoonsconfig')


models = {
u'balloons.problemballoonsconfig': {
'Meta': {'object_name': 'ProblemBalloonsConfig'},
'color': ('oioioi.base.utils.color.ColorField', [], {'max_length': '7'}),
'problem_instance': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'balloons_config'", 'unique': 'True', 'primary_key': 'True', 'to': u"orm['contests.ProblemInstance']"})
},
u'contests.contest': {
'Meta': {'object_name': 'Contest'},
'controller_name': ('oioioi.base.fields.DottedNameField', [], {'max_length': '255', 'superclass': "'oioioi.contests.controllers.ContestController'"}),
'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'default_submissions_limit': ('django.db.models.fields.IntegerField', [], {'default': '10', 'blank': 'True'}),
'id': ('django.db.models.fields.CharField', [], {'max_length': '32', 'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'})
},
u'contests.probleminstance': {
'Meta': {'ordering': "('round', 'short_name')", 'unique_together': "(('contest', 'short_name'),)", 'object_name': 'ProblemInstance'},
'contest': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contests.Contest']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'problem': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['problems.Problem']"}),
'round': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contests.Round']", 'null': 'True', 'blank': 'True'}),
'short_name': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
'submissions_limit': ('django.db.models.fields.IntegerField', [], {'default': '10', 'blank': 'True'})
},
u'contests.round': {
'Meta': {'ordering': "('contest', 'start_date')", 'unique_together': "(('contest', 'name'),)", 'object_name': 'Round'},
'contest': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contests.Contest']"}),
'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_trial': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'results_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'start_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'})
},
u'problems.problem': {
'Meta': {'object_name': 'Problem'},
'contest': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contests.Contest']", 'null': 'True', 'blank': 'True'}),
'controller_name': ('oioioi.base.fields.DottedNameField', [], {'max_length': '255', 'superclass': "'oioioi.problems.controllers.ProblemController'"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'package_backend_name': ('oioioi.base.fields.DottedNameField', [], {'max_length': '255', 'null': 'True', 'superclass': "'oioioi.problems.package.ProblemPackageBackend'", 'blank': 'True'}),
'short_name': ('django.db.models.fields.CharField', [], {'max_length': '30'})
}
}

complete_apps = ['balloons']
Loading

0 comments on commit ce7da7c

Please sign in to comment.