wouso/interface/apps/magic/views.py
from datetime import datetime, timedelta
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.core.urlresolvers import reverse
from django.db.models import Count, Q
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import render_to_response, get_object_or_404, redirect
from django.template import RequestContext
from django.utils.translation import ugettext as _, ugettext_noop
from django.views.generic import ListView
from exceptions import ValueError
from wouso.core.config.models import BoolSetting
from wouso.core.scoring.sm import InvalidFormula
from wouso.core.user.models import Player
from wouso.core.magic.models import Spell, SpellHistory, PlayerSpellDue, Artifact, Bazaar
from wouso.core import scoring, signals
from wouso.interface.activity.models import Activity
class BazaarView(ListView):
template_name = 'magic/bazaar.html'
context_object_name = 'activity'
paginate_by = 40
def get_queryset(self):
activity_list = Activity.objects.filter(Q(action='spell-buy') | Q(action='earned-ach') |
Q(action__contains='gold') | Q(action='cast')).order_by('-timestamp')
return activity_list
def get_context_data(self, **kwargs):
context = super(BazaarView, self).get_context_data(**kwargs)
player = self.request.user.get_profile() if self.request.user.is_authenticated() else None
spells = Spell.objects.all().order_by('-available', 'level_required')
# Disable exchange for real
exchange_disabled = BoolSetting.get('setting-bazaar-exchange').get_value() is False
try:
rate = scoring.calculate('gold-points-rate', gold=1)['points']
rate2 = round(1/scoring.calculate('points-gold-rate', points=1)['gold'])
except InvalidFormula:
rate, rate2 = 1, 1
rate_text = _('Rate: 1 gold = {rate} points, {rate2} points = 1 gold').format(rate=rate,
rate2=rate2)
cast_spells = PlayerSpellDue.objects.filter(source=player).all()
unseen_count = cast_spells.filter(seen=False).count()
# TODO: think of smth better
cast_spells.update(seen=True)
context.update({'spells': spells,
'rate': rate, 'rate_text': rate_text,
'cast': cast_spells,
'unseen_count': unseen_count,
'theowner': player,
'exchange_disabled': exchange_disabled})
return context
bazaar = BazaarView.as_view()
@login_required
def bazaar_exchange(request):
gold_rate = scoring.calculate('gold-points-rate', gold=1)['points']
points_rate = scoring.calculate('points-gold-rate', points=1)['gold']
player = request.user.get_profile()
message, error = '', ''
if BoolSetting.get('setting-bazaar-exchange').get_value() is False:
error = _("Exchange is disabled")
elif request.method == 'POST':
try:
points = float(request.POST.get('points', 0))
gold = round(float(request.POST.get('gold', 0)))
except:
error = _('Invalid amounts')
else:
if points != 0:
gold = points_rate * points
if gold > 0:
if player.points < points:
error = _('Insufficient points')
else:
points = round(gold) / points_rate
scoring.score(player, None, 'points-gold-rate', points=points)
message = _('Converted successfully')
else:
error = _('Insufficient points')
# other way around
elif gold != 0:
points = gold_rate * gold
if player.coins['gold'] < gold:
error = _('Insufficient gold')
else:
scoring.score(player, None, 'gold-points-rate', gold=gold)
message = _('Converted successfully')
else:
error = _('Unknown action')
else:
error = _('Expected post')
if error:
messages.error(request, error)
if message:
messages.success(request, message)
return render_to_response('magic/bazaar_buy.html',
{'tab': 'exchange'},
context_instance=RequestContext(request))
@login_required
def bazaar_buy(request, spell):
spell = get_object_or_404(Spell, pk=spell)
player = request.user.get_profile()
error, message = '',''
if Bazaar.disabled():
error = _("Magic is disabled")
elif spell.price > player.coins.get('gold', 0):
error = _("Insufficient gold amount")
elif spell.available == False:
error = _("Spell is not available")
elif spell.level_required > player.level_no:
error = _("Level {level} is required to buy this spell").format(level=spell.level_required)
else:
player.magic.add_spell(spell)
scoring.score(player, None, 'buy-spell', external_id=spell.id,
price=spell.price)
signal_msg = ugettext_noop('bought a spell')
action_msg = 'spell-buy'
signals.addActivity.send(sender=None, user_from=player,
user_to=player,
message=signal_msg,
game=None,
action=action_msg,
public=False)
SpellHistory.bought(player, spell)
message = _("Successfully acquired")
if error:
messages.error(request, error)
if message:
messages.success(request, message)
return redirect('bazaar_home')
@login_required
def magic_cast(request, destination=None, spell=None):
player = request.user.get_profile()
destination = get_object_or_404(Player, pk=destination)
error = ''
if Bazaar.disabled() or BoolSetting.get('setting-magic').get_value() is False:
error = _("Magic is disabled")
elif request.method == 'POST':
spell = get_object_or_404(Spell, pk=request.POST.get('spell', 0))
try:
days = int(request.POST.get('days', 0))
except ValueError:
pass
else:
if (days > spell.due_days) or ((spell.due_days > 0) and (days < 1)):
error = _('Invalid number of days')
else:
due = datetime.now() + timedelta(days=days)
if not spell.mass:
error = destination.magic.cast_spell(spell=spell, source=player, due=due)
else:
players = destination.get_neighbours_from_top(2, player.race, spell.type)
players = player.magic.filter_players_by_spell(players, spell)
error = player.magic.mass_cast(spell=spell, destination=players, due=due)
if not error:
return HttpResponseRedirect(reverse('wouso.interface.profile.views.user_profile', args=(destination.id,)))
error = _('Cast failed:') + ' ' + error
if error:
messages.error(request, error)
return render_to_response('profile/cast.html',
{'destination': destination},
context_instance=RequestContext(request))
@login_required
def affected_players(request):
try:
spell_id = int(request.GET.get('spell_id', None))
user_id = int(request.GET.get('user', None))
except:
raise Http404
spell = get_object_or_404(Spell, pk=spell_id)
if spell.mass:
user = request.user.get_profile()
destination = get_object_or_404(Player, pk=user_id)
players = destination.get_neighbours_from_top(2, user.race, spell.type)
players = user.magic.filter_players_by_spell(players, spell)
else :
user = get_object_or_404(Player, pk=user_id)
players = [user]
return render_to_response('profile/mass_cast_players_list.html', { 'players':players }, context_instance=RequestContext(request))
@login_required
def artifact_hof(request, artifact=None):
"""
Hall of Fame for Artifacts (generaly achievements)
"""
artifact = get_object_or_404(Artifact, pk=artifact) if artifact else None
artifacts = Artifact.objects.all().annotate(used=Count('playerartifactamount')).filter(group__name='Default').order_by('-used')
players = Player.objects.all().annotate(owned=Count('playerartifactamount')).exclude(owned=0).order_by('-owned')[:10]
return render_to_response('magic/artifact_hof.html', {'artifacts': artifacts, 'players': players, 'artifact': artifact},
context_instance=RequestContext(request))