Permalink
Browse files

Merge branch 'master' of https://github.com/elegion/setwith.me

Conflicts:
	setwithme/settings.py
	setwithme/static/css/base.css
  • Loading branch information...
2 parents 0654d7f + 6c68142 commit 73795f751eaebfcbeeccd4d82e8d0c8437ffd2fd @alarin alarin committed Jul 31, 2011
View
@@ -1 +1,45 @@
-Django Dash 2011 repository for e-Legion team
+---
+SET online game
+---
+
+Brief description:
+
+Rules
+The object of the game is to identify a 'set' of three cards from 12 cards laid out on the table.
+Each card has a variation of the following four features:
+(A) Color:
+Each card is red, green, or purple.
+
+(B) Symbol:
+Each card contains ovals, squiggles, or diamonds.
+
+(C) Number:
+Each card has one, two, or three symbols.
+
+(D) Shading: Each card is solid, open, or striped.
+
+A 'Set' consists of three cards in which each feature is EITHER the same on each card OR is different on each card.
+That is to say, any feature in the 'Set' of three cards is either common to all three cards or is different on each card.
+
+----
+Key features:
+
+1. Cool design!
+2. Login with Facebook or anonymous login with auto-created user.
+3. Highly interactive game process.
+4. Game available for any reasonable number of users (they just need to click 'Play' in one minute)
+5. Simple chat in game
+
+----
+Installation:
+No additional services/modules required except listed in requirements.txt
+You will need only driver for database,
+it is not listed in requirements since you can choose any SQL-database you like.
+python manage.py syncdb --noinput
+python manage.py migrate
+python manage.py createcachetable cache_table
+That's all!
+
+Note, that Facebook login would work only if proper application for your domain is specified in settings.
+That's due to Oauth restrictions.
+
@@ -10,16 +10,18 @@
from django.views.decorators.http import require_POST
from game.models import Game, GameSession, ClientConnectionState, Facts
-from users.models import WaitingUser
+from users.models import UserProfile, WaitingUser
@render_to('core/index.html')
def home(request):
ONLINE_TIMEOUT = datetime.timedelta(minutes=30)
now = datetime.datetime.now()
guard = now - ONLINE_TIMEOUT
+ top_users = UserProfile.objects.order_by('-games_win', 'games_total')[:3]
return {'players': User.objects.filter(last_login__gt=guard).count(),
- 'games_online': Game.objects.filter(finished=False).count()}
+ 'games_online': Game.objects.filter(finished=False).count(),
+ 'top_users': top_users}
@login_required
@@ -5,13 +5,11 @@
from game.models import Game, ClientConnectionState
-LAST_SESSION_UPDATE_TIMEOUT = datetime.timedelta(minutes=2)
+LAST_SESSION_UPDATE_TIMEOUT = datetime.timedelta(minutes=5)
class Command(BaseCommand):
- help = """ Obtains twitter_id by screen_name for users from old DB
- and updates twitter_id field """
- args = 'old_db_name'
+ help = """ Cleans zombie games """
def handle(self, *args, **options):
cleaned_cnt = 0
@@ -26,8 +24,7 @@ def handle(self, *args, **options):
for gs in game.gamesession_set.all():
gs.client_state = ClientConnectionState.LOST
gs.save()
- game.finished = True
- game.save()
+ game.finish()
cleaned_cnt += 1
if cleaned_cnt:
print "Cleaned %s zombie games" % cleaned_cnt
@@ -154,10 +154,22 @@ def is_finished(self):
.exclude(state=GameSessionState.LEFT).count()
is_finished = (active_players < 2) or (not has_cards and not has_sets)
if is_finished:
- self.finished = True
- self.save()
+ self.finish()
return is_finished
+ def finish(self):
+ if self.finished:
+ return
+ for gs in self.gamesession_set.all():
+ if gs.user.pk == self.leader:
+ gs.user.userprofile.games_win += 1
+ else:
+ gs.user.userprofile.games_loss += 1
+ gs.user.userprofile.games_total += 1
+ gs.user.userprofile.save()
+ self.finished = True
+ self.save()
+
@property
def leader(self):
"""Determines leading user,
@@ -262,6 +262,5 @@ def leave_game(request, game_id):
gs.state = GameSessionState.LEFT
gs.left = True
gs.save()
- gs.game.finished = True
- gs.game.save()
+ gs.game.finish()
return redirect('/')
@@ -0,0 +1,87 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding field 'UserProfile.games_total'
+ db.add_column('users_userprofile', 'games_total', self.gf('django.db.models.fields.PositiveIntegerField')(default=0), keep_default=False)
+
+ # Adding field 'UserProfile.games_win'
+ db.add_column('users_userprofile', 'games_win', self.gf('django.db.models.fields.PositiveIntegerField')(default=0), keep_default=False)
+
+ # Adding field 'UserProfile.games_loss'
+ db.add_column('users_userprofile', 'games_loss', self.gf('django.db.models.fields.PositiveIntegerField')(default=0), keep_default=False)
+
+
+ def backwards(self, orm):
+
+ # Deleting field 'UserProfile.games_total'
+ db.delete_column('users_userprofile', 'games_total')
+
+ # Deleting field 'UserProfile.games_win'
+ db.delete_column('users_userprofile', 'games_win')
+
+ # Deleting field 'UserProfile.games_loss'
+ db.delete_column('users_userprofile', 'games_loss')
+
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'users.userprofile': {
+ 'Meta': {'object_name': 'UserProfile'},
+ 'games_loss': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'games_total': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'games_win': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'}),
+ 'user_pic': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '300'})
+ },
+ 'users.waitinguser': {
+ 'Meta': {'object_name': 'WaitingUser'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_poll': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ }
+ }
+
+ complete_apps = ['users']
@@ -25,6 +25,9 @@ def __unicode__(self):
class UserProfile(models.Model):
user = models.OneToOneField(User)
user_pic = models.CharField(max_length=300, default='')
+ games_total = models.PositiveIntegerField(default=0)
+ games_win = models.PositiveIntegerField(default=0)
+ games_loss = models.PositiveIntegerField(default=0)
def get_user_json(user):
View
@@ -57,4 +57,4 @@ base = .
DJANGO_SETTINGS_MODULE = production_settings
[cron]
-setwithme/manage.py clean_dead_games = */5 * * * *
+manage.py clean_dead_games = */5 * * * *
View
@@ -205,15 +205,14 @@
DEFAULT_PROFILE_PIC = os.path.join(STATIC_URL, '/static/images/nophoto.png')
-try:
- from settings_local import *
-except ImportError:
- pass
-
-
CACHES = {
'default': {
- 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
- 'LOCATION': '/var/tmp/django_cache',
+ 'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
+ 'LOCATION': 'cache_table',
}
}
+
+try:
+ from settings_local import *
+except ImportError:
+ pass
@@ -161,6 +161,59 @@ a.pseudo:hover {
margin: 0.5em 0 0 0;
}
+.main .top_users_container {
+ position: absolute;
+ top: 0;
+ right: 0;
+ background: #81868a;
+ border-radius: 5px;
+ -moz-border-radius: 5px;
+ padding: 15px 25px 28px;;
+ margin-top: 35px;
+}
+ .main .top_users_container .header {
+ background: #81868a;
+ font-family: 'Lobster', cursive;
+ font-size: 1.35em;
+ color: #42494f;
+ text-shadow: #9fa4a8 0 1px 0;
+ }
+ .main .top_users_container .top_users {
+ margin-top: 20px;
+ width: 14em;
+ }
+ .main .top_users_container .top_users .separator {
+ display: block;
+ height: 2px;
+ margin: 18px 0 15px;
+ background: url(../images/bg_separator_top_users.png);
+ }
+ .main .top_users_container .top_user .info {
+ margin-top: -62px;
+ margin-left: 80px;
+ }
+ .main .top_users_container .top_user .photo {
+ border: #fff 6px solid;
+ border-radius: 3px;
+ -moz-border-radius: 3px;
+ margin-right: 10px;
+ }
+ .main .top_users_container .top_user .name {
+ font-family: 'Lobster', cursive;
+ font-size: 1em;
+ color: #f9f9f9;
+ text-shadow: #a5a7a8 0 -1px 1px;
+ }
+ .main .top_users_container .top_user .stats {
+ margin: 1em 0 0;
+ width: auto;
+ color: #d2d2d2;
+ font-size: 0.8em;
+ font-style: italic;
+ font-weight: bold;
+ text-shadow: #6a6e71 0 -1px 0;
+ }
+
.big_button {
display: block;
width: 15em;
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -58,4 +58,21 @@
</div>
{% endif %}
</div>
+{% if top_users %}
+<div class="top_users_container">
+ <span class="header">Top users</span>
+ <ul class="top_users">
+ {% for user in top_users %}
+ <li class="top_user">
+ <img class="photo" src="{{ user_profile.user_pic }}">
+ <div class="info">
+ <div class="name">{{ user.user.first_name }} {{ user.user.last_name }}</div>
+ <div class="stats">win {{ user.games_win }}, loss {{ user.games_loss }}</div>
+ </div>
+ </li>
+ {% if not forloop.last %}<li class="separator"></li>{% endif %}
+ {% endfor %}
+ </ul>
+</div>
+{% endif %}
{% endblock %}
@@ -51,7 +51,7 @@
<div id="js_users"></div>
</div>
- <div class="hideall"></div>
+ <div class="hideall" style="display:none"></div>
<div class="center">
<div class="winner_plate">
<h1>Game over. And winner is...</h1>
@@ -11,7 +11,7 @@
<img class="photo" src="{{ user_profile.user_pic }}">
<div class="info">
<div class="name">{{ request.user.first_name }} {{ request.user.last_name }}</div>
- <div class="stat">win 0 | lose 0</div>
+ <div class="stat">win {{ request.user.userprofile.games_win }} | lose {{ request.user.userprofile.games_loss }}</div>
</div>
<form class="logout" action="{% url core.views.logout %}" method="POST">
{% csrf_token %}

0 comments on commit 73795f7

Please sign in to comment.