From 55eab2f1cdaf7b043fe47392f8228031fedf792e Mon Sep 17 00:00:00 2001 From: Sergio Oliveira Date: Thu, 24 Oct 2013 10:17:53 -0200 Subject: [PATCH] Adding missing directory. Updates #21 --- src/hitcount/__init__.py | 0 src/hitcount/admin.py | 3 +++ src/hitcount/migrations/0001_initial.py | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/hitcount/migrations/__init__.py | 0 src/hitcount/models.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/hitcount/tests.py | 3 +++ src/hitcount/views.py | 13 +++++++++++++ 7 files changed, 123 insertions(+), 0 deletions(-) create mode 100644 src/hitcount/__init__.py create mode 100644 src/hitcount/admin.py create mode 100644 src/hitcount/migrations/0001_initial.py create mode 100644 src/hitcount/migrations/__init__.py create mode 100644 src/hitcount/models.py create mode 100644 src/hitcount/tests.py create mode 100644 src/hitcount/views.py diff --git a/src/hitcount/__init__.py b/src/hitcount/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/hitcount/__init__.py diff --git a/src/hitcount/admin.py b/src/hitcount/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/src/hitcount/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/src/hitcount/migrations/0001_initial.py b/src/hitcount/migrations/0001_initial.py new file mode 100644 index 0000000..1236631 --- /dev/null +++ b/src/hitcount/migrations/0001_initial.py @@ -0,0 +1,53 @@ +# -*- 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): + # Adding model 'Hit' + db.create_table(u'hitcount_hit', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('created', self.gf('django.db.models.fields.DateField')(auto_now_add=True, db_index=True, blank=True)), + ('updated', self.gf('django.db.models.fields.DateField')(auto_now=True, db_index=True, blank=True)), + ('hits', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)), + ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])), + ('object_pk', self.gf('django.db.models.fields.CharField')(max_length=256)), + )) + db.send_create_signal(u'hitcount', ['Hit']) + + # Adding unique constraint on 'Hit', fields ['content_type', 'object_pk'] + db.create_unique(u'hitcount_hit', ['content_type_id', 'object_pk']) + + + def backwards(self, orm): + # Removing unique constraint on 'Hit', fields ['content_type', 'object_pk'] + db.delete_unique(u'hitcount_hit', ['content_type_id', 'object_pk']) + + # Deleting model 'Hit' + db.delete_table(u'hitcount_hit') + + + models = { + u'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'}), + u'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'}) + }, + u'hitcount.hit': { + 'Meta': {'unique_together': "(('content_type', 'object_pk'),)", 'object_name': 'Hit'}, + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + 'created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), + 'hits': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'object_pk': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'updated': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}) + } + } + + complete_apps = ['hitcount'] \ No newline at end of file diff --git a/src/hitcount/migrations/__init__.py b/src/hitcount/migrations/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/hitcount/migrations/__init__.py diff --git a/src/hitcount/models.py b/src/hitcount/models.py new file mode 100644 index 0000000..5e52457 --- /dev/null +++ b/src/hitcount/models.py @@ -0,0 +1,51 @@ + +from django.db import models +from django.core.cache import cache +from django.contrib.contenttypes import generic +from django.contrib.contenttypes.models import ContentType + + +class Hit(models.Model): + created = models.DateField(auto_now_add=True, db_index=True) + updated = models.DateField(auto_now=True, db_index=True) + hits = models.PositiveIntegerField(default=0) + content_type = models.ForeignKey(ContentType) + object_pk = models.CharField(max_length=256) + + class Meta: + unique_together = ('content_type', 'object_pk') + + +class HitCountModelMixin(object): + + @property + def hits(self): + content_type = ContentType.objects.get_for_model(self.__class__, + for_concrete_model=False) + try: + hit = Hit.objects.get(content_type=content_type, + object_pk=self.pk) + except Hit.DoesNotExist: + return 0 + + return hit.hits + + def hit(self, request=None): + content_type = ContentType.objects.get_for_model(self.__class__) + + # Here we cache the user's IP to ensure that the same + # IP won't hit the same page again for while + if request: + ip_addr = request.META.get('REMOTE_ADDR') + cache_key = u'page_hits-{}-{}-{}'.format(ip_addr, + content_type, self.pk) + duplicate = cache.get(cache_key) + if duplicate: + return + cache.set(cache_key, True) + + # Everything ok, so just increment the page count + hit_ = Hit.objects.get_or_create(content_type=content_type, + object_pk=self.pk)[0] + hit_.hits += 1 + hit_.save() diff --git a/src/hitcount/tests.py b/src/hitcount/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/src/hitcount/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/src/hitcount/views.py b/src/hitcount/views.py new file mode 100644 index 0000000..c6fefaa --- /dev/null +++ b/src/hitcount/views.py @@ -0,0 +1,13 @@ +from django.shortcuts import render + +class HitCountViewMixin(object): + def get_object(self): + raise NotImplementedError + + def dispatch(self, request, *args, **kwargs): + response = super(HitCountViewMixin, self).dispatch(request, + *args, **kwargs) + if 200 <= response.status_code < 300: + obj = self.get_object() + if obj: obj.hit(request) + return response -- libgit2 0.21.2