Commits

David Krauth  committed 3e91390

added game requests and game profile page

  • Participants
  • Parent commits 7f1d758

Comments (0)

Files changed (8)

 from django import forms
-from echess import models as echess
+from echess.models import GameRequest, ChessProfile
 
-COLOR_CHOICES = (
-    ('opp_choice', "Opponent's Choice"),
-    ('white', 'White'),
-    ('black', 'Black'),
-    ('next', 'Next in Series'),
-)
 
 #===============================================================================
 class NewGameForm(forms.Form):
 
     opponent = forms.ModelChoiceField(
-        echess.ChessProfile.objects.none(),
-        empty_label='First Available',
+        ChessProfile.objects.none(),
+        empty_label='-- First Available --',
         required=False
     )
-    color = forms.ChoiceField(choices=COLOR_CHOICES)
     
+    color = forms.ChoiceField(
+        choices=GameRequest.Color.CHOICES,
+        initial=GameRequest.Color.OPPONENT
+    )
+
     #---------------------------------------------------------------------------
     def __init__(self, user, *args, **kws):
         super(NewGameForm, self).__init__(*args, **kws)
-        self.fields['opponent'].queryset = echess.ChessProfile.objects.exclude(user=user)
+        self.fields['opponent'].queryset = ChessProfile.objects.exclude(user=user)
+        self.user = user
+        
+    #---------------------------------------------------------------------------
+    def save(self):
+        profile, created = ChessProfile.objects.get_or_create(user=self.user)
+        return GameRequest.objects.create(
+            requester=profile,
+            color=self.cleaned_data['color'],
+            opponent = self.cleaned_data['opponent']
+        )
 
 from django.db import models
 from django.contrib.auth.models import User
+from jargon.db.fields import ChoiceEnumeration
 
 
 #===============================================================================
         return self.user.username
     
 
+
+#===============================================================================
+class GameManager(models.Manager):
+    
+    #---------------------------------------------------------------------------
+    def for_user(self, user, **kws):
+        return self.filter(
+            models.Q(white__user=user) | models.Q(black__user=user),
+            **kws
+        )
+
+        
+
 #===============================================================================
 class Game(models.Model):
-
-    RESULT_OPTIONS = (
-        ('W', '1-0'),
-        ('B', '0-1'),
-        ('D', '1/2-1/2'),
-        ('U', '*'),
-    )
     
+    #===========================================================================
+    class Result(ChoiceEnumeration):
+        WHITE     = ChoiceEnumeration.Option('W', '1-0')
+        BLACK     = ChoiceEnumeration.Option('B', '0-1')
+        DRAW      = ChoiceEnumeration.Option('D', '1/2-1/2')
+        UNDECIDED = ChoiceEnumeration.Option('U', '*', default=True)
+        
     start_time = models.DateTimeField(default=datetime.now)
     end_time = models.DateTimeField(null=True, default=None)
-    result = models.CharField(max_length=1, choices=RESULT_OPTIONS, default='U')
+    result = models.CharField(
+        max_length=1, 
+        choices=Result.CHOICES, 
+        default=Result.DEFAULT,
+    )
     
     pgn = models.TextField(blank=True)
     white = models.ForeignKey(ChessProfile, related_name='game_white_set')
     black = models.ForeignKey(ChessProfile, related_name='game_black_set')
 
+    objects = GameManager()
+    
     #===========================================================================
     class Meta:
         ordering = ('-start_time',)
 
     #---------------------------------------------------------------------------
     def __unicode__(self):
-        return u'%s %s %s' % (self.eco, self.name, self.variation)
+        return u'%s %s %s' % (self.eco, self.name, self.variation)
+        
+
+
+#===============================================================================
+class GameRequest(models.Model):
+    
+    #===========================================================================
+    class Color(ChoiceEnumeration):
+        WHITE    = ChoiceEnumeration.Option('WHITE', 'White')
+        BLACK    = ChoiceEnumeration.Option('BLACK', 'Black')
+        OPPONENT = ChoiceEnumeration.Option('OPP', "Opponent's Choice")
+        NEXT     = ChoiceEnumeration.Option('NEXT', 'Next in Series')
+
+    #===========================================================================
+    class Status(ChoiceEnumeration):
+        INIT     = ChoiceEnumeration.Option('INIT', 'Initialized', default=True)
+        DECLINED = ChoiceEnumeration.Option('DECL', 'Declined')
+        ACCEPTED = ChoiceEnumeration.Option('ACPT', 'Accepted')
+        
+    
+    requester = models.ForeignKey(ChessProfile, related_name='requester_set')
+    opponent = models.ForeignKey(
+        ChessProfile,
+        null=True, 
+        blank=True, 
+        related_name='request_opppenent_set'
+    )
+    
+    created = models.DateTimeField(default=datetime.now)
+    color = models.CharField(max_length=5, choices=Color.CHOICES)
+    status = models.CharField(
+        max_length=4, 
+        choices=Status.CHOICES,
+        default=Status.DEFAULT
+    )
+    game = models.ForeignKey(Game, null=True, blank=True)
+    
+    

File templates/echess/about.html

+{% extends "echess/base.html" %}
+{% block main_content %}
+    <h3>Under Construction</h3>
+{% endblock main_content %}

File templates/echess/base.html

         h1 { margin-top: 1em; font-size: 2em; }
         h1 a img { vertical-align: middle; }
         table { border-collapse: collapse; border: 1px solid #c3d9ff; }
-        tr.odd td { background-color: #e5ecf9; }
         a { text-decoration: none; }
     </style> 
     {% block extra_head %}{% endblock extra_head %}
 </head>
 
 <body>
+    {% url chess-todo as todo_url %}
     <div class="container">
         <div id="header" class="span-24 last">
             <h1>
                         </li>
                         <li><a href="{% url chess-game-new %}">New Game</a></li>
                         {% endif %}
-                        <li><a href="#">Practice Game</a></li>
+                        <li><a href="{{ todo_url }}">Practice Game</a></li>
                         <li><a href="{% url chess-openings %}">Opening Library</a></li>
-                        <li><a href="#">About</a></li>
+                        <li><a href="{% url chess-about %}">About</a></li>
                         
                     </ul>
                 </div>
         <div id="footer">
             <div class="span-5 colborder">
                 <ul>
-                  <li><a class="quiet" href="#">Privacy Policy</a></li>
-                  <li><a class="quiet" href="#">Security Policy</a></li>
-                  <li><a class="quiet" href="#">Submit a Bug</a></li>
+                  <li><a class="quiet" href="{{ todo_url }}">Privacy Policy</a></li>
+                  <li><a class="quiet" href="{{ todo_url }}">Security Policy</a></li>
+                  <li><a class="quiet" href="{{ todo_url }}">Submit a Bug</a></li>
                 </ul>
             </div>
 

File templates/echess/profile_games.html

+{% extends "echess/base.html" %}
+{% block main_content %}
+    <h3>Pending Game Requests</h3>
+    <table>
+        <thead>
+            <tr>
+                <th>Created</th>
+                <th>Opponent</th>
+                <th>Color</th>
+            </tr>
+        </thead>
+        <tbody>
+            {% for r in pending %}
+            <tr class="{% cycle 'odd' 'even' %}">
+                <td>{{ r.created }}</td>
+                <td>{{ r.opponent|default:"First Responder" }}</td>
+                <td>{{ r.get_color_display }}</td>
+            </tr>
+            {% empty %}
+            <tr>
+                <td colsp="3"><em>No pending game requests</em></td>
+            </tr>
+            {% endfor %}
+        </tbody>
+    </table>
+{% endblock main_content %}

File templates/echess/todo.html

+{% extends "echess/base.html" %}
+{% block main_content %}
+    <h3>Under Construction</h3>
+{% endblock main_content %}
 from django.conf.urls.defaults import *
+from jargon.shortcuts import to_template
 from echess import views
 
 urlpatterns = patterns('',
     url(r'^$', views.index, name='chess-index'),
     url(r'^games/$', views.games, name='chess-games'),
     url(r'^games/new/$', views.new_game, name='chess-game-new'),
+    url(r'^games/profile/$', views.profile_games, name='chess-profile-games'),
     url(r'^games/(\d+)/$', views.game, name='chess-game'),
     url(r'^test/$', views.test, name='chess-test'),
     url(r'^play/$', views.play, name='chess-playback'),
+    url(r'^about/$', to_template('echess/about.html'), name='chess-about'),
+    url(r'^todo/$', to_template('echess/todo.html'), name='chess-todo'),
     
     url(r'^openings/$', views.openings, name='chess-openings'),
     url(r'^openings/eco/([^/]+)/$', views.eco_openings, name='chess-eco-openings'),
 from django import http
+from django.db import models
+from django.core.urlresolvers import reverse
 from django.contrib.auth.models import User
+from django.contrib.auth.decorators import login_required
 from django.shortcuts import render_to_response, get_object_or_404
 
 from jargon.shortcuts import request_to_response
 
 
 #-------------------------------------------------------------------------------
+@login_required
 def new_game(request):
     if request.method == 'POST':
         form = forms.NewGameForm(request.user, request.POST)
         if form.is_valid():
-            return http.HttpResponseRedirect(request.path)
+            form.save()
+            return http.HttpResponseRedirect(reverse('chess-profile-games'))
     else:
         form = forms.NewGameForm(request.user)
         
     return request_to_response(request, 'echess/new_game.html', dict(form=form))
+
+
+#-------------------------------------------------------------------------------
+@login_required
+def profile_games(request):
+    data = dict(
+        pending=GameRequest.objects.filter(
+            requester__user=request.user,
+            status=GameRequest.Status.INIT
+        ),
+        ongoing=Game.objects.for_user(
+            request.user,
+            result=Game.Result.UNDECIDED
+        ),
+        completed=Game.objects.for_user(request.user).exclude(
+            result=Game.Result.UNDECIDED
+        ),
+    )
+    return request_to_response(request, 'echess/profile_games.html', data)
+