Permalink
Browse files

added ip based view counting

  • Loading branch information...
ialbert committed Aug 7, 2012
1 parent 861393b commit 8fc31c9436581b6619c099efaa11a6c91a6a2e63
Showing with 239 additions and 11 deletions.
  1. +224 −0 main/server/migrations/0002_auto__add_postview.py
  2. +14 −10 main/server/models.py
  3. +1 −1 main/server/views.py
@@ -0,0 +1,224 @@
+# -*- coding: 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):
+ # Deleting model 'Visit'
+ db.delete_table('server_visit')
+
+ # Deleting model 'Related'
+ db.delete_table('server_related')
+
+ # Deleting model 'PostBody'
+ db.delete_table('server_postbody')
+
+ # Deleting model 'View'
+ db.delete_table('server_view')
+
+ # Adding model 'PostView'
+ db.create_table('server_postview', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('ip', self.gf('django.db.models.fields.GenericIPAddressField')(default='', max_length=39, null=True, blank=True)),
+ ('post', self.gf('django.db.models.fields.related.ForeignKey')(related_name='post_views', to=orm['server.Post'])),
+ ('date', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
+ ))
+ db.send_create_signal('server', ['PostView'])
+
+
+ def backwards(self, orm):
+ # Adding model 'Visit'
+ db.create_table('server_visit', (
+ ('date', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
+ ('ip', self.gf('django.db.models.fields.GenericIPAddressField')(default='', max_length=39, null=True, blank=True)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
+ ))
+ db.send_create_signal('server', ['Visit'])
+
+ # Adding model 'Related'
+ db.create_table('server_related', (
+ ('source', self.gf('django.db.models.fields.related.ForeignKey')(related_name='source', to=orm['server.Post'])),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('target', self.gf('django.db.models.fields.related.ForeignKey')(related_name='target', to=orm['server.Post'])),
+ ))
+ db.send_create_signal('server', ['Related'])
+
+ # Adding model 'PostBody'
+ db.create_table('server_postbody', (
+ ('content', self.gf('django.db.models.fields.TextField')(max_length=10000)),
+ ('post', self.gf('django.db.models.fields.related.ForeignKey')(related_name='bodies', to=orm['server.Post'])),
+ ('html', self.gf('django.db.models.fields.TextField')(blank=True)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ))
+ db.send_create_signal('server', ['PostBody'])
+
+ # Adding model 'View'
+ db.create_table('server_view', (
+ ('date', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
+ ('post', self.gf('django.db.models.fields.related.ForeignKey')(related_name='post_views', to=orm['server.Post'])),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='user_views', to=orm['auth.User'])),
+ ))
+ db.send_create_signal('server', ['View'])
+
+ # Deleting model 'PostView'
+ db.delete_table('server_postview')
+
+
+ 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'})
+ },
+ 'server.award': {
+ 'Meta': {'object_name': 'Award'},
+ 'badge': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['server.Badge']"}),
+ 'date': ('django.db.models.fields.DateTimeField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'server.badge': {
+ 'Meta': {'object_name': 'Badge'},
+ 'count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'description': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+ 'secret': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'type': ('django.db.models.fields.IntegerField', [], {}),
+ 'unique': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'server.blog': {
+ 'Meta': {'object_name': 'Blog'},
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '500'})
+ },
+ 'server.note': {
+ 'Meta': {'object_name': 'Note'},
+ 'content': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '5000'}),
+ 'date': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
+ 'html': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '5000'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'sender': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'note_sender'", 'to': "orm['auth.User']"}),
+ 'target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'note_target'", 'to': "orm['auth.User']"}),
+ 'type': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'unread': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}),
+ 'url': ('django.db.models.fields.URLField', [], {'default': "''", 'max_length': '200', 'blank': 'True'})
+ },
+ 'server.post': {
+ 'Meta': {'object_name': 'Post'},
+ 'accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'answer_count': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+ 'changed': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}),
+ 'content': ('django.db.models.fields.TextField', [], {'max_length': '10000'}),
+ 'creation_date': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
+ 'full_score': ('django.db.models.fields.IntegerField', [], {'default': '0', 'db_index': 'True', 'blank': 'True'}),
+ 'html': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'lastedit_date': ('django.db.models.fields.DateTimeField', [], {}),
+ 'lastedit_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'editor'", 'to': "orm['auth.User']"}),
+ 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['server.Post']"}),
+ 'rank': ('django.db.models.fields.FloatField', [], {'default': '0', 'blank': 'True'}),
+ 'root': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'descendants'", 'null': 'True', 'to': "orm['server.Post']"}),
+ 'score': ('django.db.models.fields.IntegerField', [], {'default': '0', 'db_index': 'True', 'blank': 'True'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '200', 'blank': 'True'}),
+ 'status': ('django.db.models.fields.IntegerField', [], {'default': '100'}),
+ 'tag_set': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['server.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'tag_val': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
+ 'title': ('django.db.models.fields.TextField', [], {'max_length': '200'}),
+ 'type': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+ 'url': ('django.db.models.fields.URLField', [], {'default': "''", 'max_length': '200', 'blank': 'True'}),
+ 'views': ('django.db.models.fields.IntegerField', [], {'default': '0', 'db_index': 'True', 'blank': 'True'})
+ },
+ 'server.postrevision': {
+ 'Meta': {'object_name': 'PostRevision'},
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+ 'content': ('django.db.models.fields.TextField', [], {}),
+ 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'diff': ('django.db.models.fields.TextField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'post': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'revisions'", 'to': "orm['server.Post']"})
+ },
+ 'server.postview': {
+ 'Meta': {'object_name': 'PostView'},
+ 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'ip': ('django.db.models.fields.GenericIPAddressField', [], {'default': "''", 'max_length': '39', 'null': 'True', 'blank': 'True'}),
+ 'post': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'post_views'", 'to': "orm['server.Post']"})
+ },
+ 'server.tag': {
+ 'Meta': {'object_name': 'Tag'},
+ 'count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.TextField', [], {'max_length': '50', 'db_index': 'True'})
+ },
+ 'server.userprofile': {
+ 'Meta': {'object_name': 'UserProfile'},
+ 'about_me': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}),
+ 'about_me_html': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}),
+ 'bronze_badges': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'display_name': ('django.db.models.fields.CharField', [], {'default': "'User'", 'max_length': '250', 'db_index': 'True'}),
+ 'gold_badges': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_visited': ('django.db.models.fields.DateTimeField', [], {}),
+ 'location': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}),
+ 'my_tags': ('django.db.models.fields.TextField', [], {'default': "''", 'max_length': '250', 'null': 'True', 'blank': 'True'}),
+ 'new_messages': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'scholar': ('django.db.models.fields.TextField', [], {'default': "''", 'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'score': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'}),
+ 'silver_badges': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'type': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'profile'", 'unique': 'True', 'to': "orm['auth.User']"}),
+ 'uuid': ('django.db.models.fields.TextField', [], {'unique': 'True', 'db_index': 'True'}),
+ 'website': ('django.db.models.fields.URLField', [], {'default': "''", 'max_length': '250', 'null': 'True', 'blank': 'True'})
+ },
+ 'server.vote': {
+ 'Meta': {'object_name': 'Vote'},
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+ 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'post': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['server.Post']"}),
+ 'type': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'})
+ }
+ }
+
+ complete_apps = ['server']
View
@@ -277,17 +277,21 @@ def combine(self):
def update_post_views(post, request, hours=1):
"Views are updated per user session"
- amount = hours * 3600
- if request.user.is_anonymous():
- return
- viewed = request.session.get(SESSION_VIEW_COUNT, set())
- if post.id not in viewed:
- # direct updates bypass signals
+
+ amount = 1
+
+ ip = html.get_ip(request)
+
+ now = datetime.now()
+ since = now - timedelta(hours=hours)
+
+ # one view per hour will be counted per each IP address
+ if not PostView.objects.filter(ip=ip, post=post, date__gt=since):
+ #messages.info(request, "created view for %s" % post.title)
+ PostView.objects.create(ip=ip, post=post, date=now)
Post.objects.filter(id=post.id).update(views = F('views') + 1, rank=F('rank') + amount )
post.views += 1
- viewed.add(post.id)
- request.session[SESSION_VIEW_COUNT] = viewed
- View.objects.create(user=request.user, post=post)
+
return post
def get_post_manager(user):
@@ -344,7 +348,7 @@ def username(self, obj):
admin.site.register(Blog, BlogAdmin)
-class ViewCounter(models.Model):
+class PostView(models.Model):
"""
Keeps track of post views based on IP base.
"""
View
@@ -314,7 +314,7 @@ def post_show(request, pid):
try:
root = query.get(id=pid)
# update the views for the question
- models.update_post_views(post=root, request=request, hours=settings.POST_VIEW_RANK_GAIN)
+ models.update_post_views(post=root, request=request, hours=1)
counts = sess.get_counts()
except models.Post.DoesNotExist, exc:

0 comments on commit 8fc31c9

Please sign in to comment.