Commit 9c9a2e7737d14e583db322267a6cd9e4ec813510
Exists in
master
and in
39 other branches
Merge branch 'master' of github.com:TracyWebTech/colab
Showing
12 changed files
with
11 additions
and
140 deletions
Show diff stats
requirements.txt
src/colab/custom_settings.py
@@ -107,6 +107,7 @@ INSTALLED_APPS = INSTALLED_APPS + ( | @@ -107,6 +107,7 @@ INSTALLED_APPS = INSTALLED_APPS + ( | ||
107 | 'django_browserid', | 107 | 'django_browserid', |
108 | 'conversejs', | 108 | 'conversejs', |
109 | 'haystack', | 109 | 'haystack', |
110 | + 'hitcounter', | ||
110 | 111 | ||
111 | # Own apps | 112 | # Own apps |
112 | 'super_archives', | 113 | 'super_archives', |
@@ -116,7 +117,6 @@ INSTALLED_APPS = INSTALLED_APPS + ( | @@ -116,7 +117,6 @@ INSTALLED_APPS = INSTALLED_APPS + ( | ||
116 | 'accounts', | 117 | 'accounts', |
117 | 'proxy', | 118 | 'proxy', |
118 | 'search', | 119 | 'search', |
119 | - 'hitcount', | ||
120 | 120 | ||
121 | # Feedzilla and deps | 121 | # Feedzilla and deps |
122 | 'feedzilla', | 122 | 'feedzilla', |
src/hitcount/__init__.py
src/hitcount/admin.py
src/hitcount/migrations/0001_initial.py
@@ -1,53 +0,0 @@ | @@ -1,53 +0,0 @@ | ||
1 | -# -*- coding: utf-8 -*- | ||
2 | -import datetime | ||
3 | -from south.db import db | ||
4 | -from south.v2 import SchemaMigration | ||
5 | -from django.db import models | ||
6 | - | ||
7 | - | ||
8 | -class Migration(SchemaMigration): | ||
9 | - | ||
10 | - def forwards(self, orm): | ||
11 | - # Adding model 'Hit' | ||
12 | - db.create_table(u'hitcount_hit', ( | ||
13 | - (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), | ||
14 | - ('created', self.gf('django.db.models.fields.DateField')(auto_now_add=True, db_index=True, blank=True)), | ||
15 | - ('updated', self.gf('django.db.models.fields.DateField')(auto_now=True, db_index=True, blank=True)), | ||
16 | - ('hits', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)), | ||
17 | - ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])), | ||
18 | - ('object_pk', self.gf('django.db.models.fields.CharField')(max_length=256)), | ||
19 | - )) | ||
20 | - db.send_create_signal(u'hitcount', ['Hit']) | ||
21 | - | ||
22 | - # Adding unique constraint on 'Hit', fields ['content_type', 'object_pk'] | ||
23 | - db.create_unique(u'hitcount_hit', ['content_type_id', 'object_pk']) | ||
24 | - | ||
25 | - | ||
26 | - def backwards(self, orm): | ||
27 | - # Removing unique constraint on 'Hit', fields ['content_type', 'object_pk'] | ||
28 | - db.delete_unique(u'hitcount_hit', ['content_type_id', 'object_pk']) | ||
29 | - | ||
30 | - # Deleting model 'Hit' | ||
31 | - db.delete_table(u'hitcount_hit') | ||
32 | - | ||
33 | - | ||
34 | - models = { | ||
35 | - u'contenttypes.contenttype': { | ||
36 | - 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, | ||
37 | - 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
38 | - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
39 | - 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | ||
40 | - 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | ||
41 | - }, | ||
42 | - u'hitcount.hit': { | ||
43 | - 'Meta': {'unique_together': "(('content_type', 'object_pk'),)", 'object_name': 'Hit'}, | ||
44 | - 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), | ||
45 | - 'created': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), | ||
46 | - 'hits': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), | ||
47 | - u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||
48 | - 'object_pk': ('django.db.models.fields.CharField', [], {'max_length': '256'}), | ||
49 | - 'updated': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}) | ||
50 | - } | ||
51 | - } | ||
52 | - | ||
53 | - complete_apps = ['hitcount'] | ||
54 | \ No newline at end of file | 0 | \ No newline at end of file |
src/hitcount/migrations/__init__.py
src/hitcount/models.py
@@ -1,55 +0,0 @@ | @@ -1,55 +0,0 @@ | ||
1 | - | ||
2 | -from django.db import models | ||
3 | -from django.core.cache import cache | ||
4 | -from django.contrib.contenttypes import generic | ||
5 | -from django.contrib.contenttypes.models import ContentType | ||
6 | - | ||
7 | - | ||
8 | -class Hit(models.Model): | ||
9 | - created = models.DateField(auto_now_add=True, db_index=True) | ||
10 | - updated = models.DateField(auto_now=True, db_index=True) | ||
11 | - hits = models.PositiveIntegerField(default=0) | ||
12 | - content_type = models.ForeignKey(ContentType) | ||
13 | - object_pk = models.CharField(max_length=256) | ||
14 | - | ||
15 | - class Meta: | ||
16 | - unique_together = ('content_type', 'object_pk') | ||
17 | - | ||
18 | - | ||
19 | -class HitCountModelMixin(object): | ||
20 | - | ||
21 | - @property | ||
22 | - def hits(self): | ||
23 | - content_type = ContentType.objects.get_for_model(self.__class__, | ||
24 | - for_concrete_model=False) | ||
25 | - try: | ||
26 | - hit = Hit.objects.get(content_type=content_type, | ||
27 | - object_pk=self.pk) | ||
28 | - except Hit.DoesNotExist: | ||
29 | - return 0 | ||
30 | - | ||
31 | - return hit.hits | ||
32 | - | ||
33 | - def hit(self, request=None): | ||
34 | - content_type = ContentType.objects.get_for_model(self.__class__) | ||
35 | - | ||
36 | - # Here we cache the user's IP to ensure that the same | ||
37 | - # IP won't hit the same page again for while | ||
38 | - if request: | ||
39 | - ip_addr = request.META.get('REMOTE_ADDR') | ||
40 | - cache_key = u'page_hits-{}-{}-{}'.format(ip_addr, | ||
41 | - content_type, self.pk) | ||
42 | - duplicate = cache.get(cache_key) | ||
43 | - if duplicate: | ||
44 | - return | ||
45 | - cache.set(cache_key, True) | ||
46 | - | ||
47 | - # Everything ok, so just increment the page count | ||
48 | - hit_pk = Hit.objects.get_or_create(content_type=content_type, | ||
49 | - object_pk=self.pk)[0].pk | ||
50 | - | ||
51 | - # Using this way instead of hits += 1 forces django to | ||
52 | - # call the UPDATE directly in the database avoiding | ||
53 | - # cuncurrency problems | ||
54 | - Hit.objects.filter(pk=hit_pk).update(hits=models.F("hits") + 1) | ||
55 | - |
src/hitcount/tests.py
src/hitcount/views.py
@@ -1,16 +0,0 @@ | @@ -1,16 +0,0 @@ | ||
1 | -from django.shortcuts import render | ||
2 | - | ||
3 | -class HitCountViewMixin(object): | ||
4 | - def get_object(self, *args, **kwargs): | ||
5 | - try: | ||
6 | - super(HitCountViewMixin, self).get_object(*args, **kwargs) | ||
7 | - except AttributeError: | ||
8 | - raise NotImplementedError | ||
9 | - | ||
10 | - def dispatch(self, request, *args, **kwargs): | ||
11 | - response = super(HitCountViewMixin, self).dispatch(request, | ||
12 | - *args, **kwargs) | ||
13 | - if 200 <= response.status_code < 300: | ||
14 | - obj = self.get_object() | ||
15 | - if obj: obj.hit(request) | ||
16 | - return response |
src/proxy/models.py
@@ -7,10 +7,10 @@ from django.conf import settings | @@ -7,10 +7,10 @@ from django.conf import settings | ||
7 | from django.db import models | 7 | from django.db import models |
8 | 8 | ||
9 | from accounts.models import User | 9 | from accounts.models import User |
10 | -from hitcount.models import HitCountModelMixin | 10 | +from hitcounter.models import HitCounterModelMixin |
11 | 11 | ||
12 | 12 | ||
13 | -class Attachment(models.Model, HitCountModelMixin): | 13 | +class Attachment(models.Model, HitCounterModelMixin): |
14 | url = models.TextField(primary_key=True) | 14 | url = models.TextField(primary_key=True) |
15 | attach_id = models.TextField() | 15 | attach_id = models.TextField() |
16 | used_by = models.TextField() | 16 | used_by = models.TextField() |
@@ -44,7 +44,7 @@ class Attachment(models.Model, HitCountModelMixin): | @@ -44,7 +44,7 @@ class Attachment(models.Model, HitCountModelMixin): | ||
44 | return None | 44 | return None |
45 | 45 | ||
46 | 46 | ||
47 | -class Revision(models.Model, HitCountModelMixin): | 47 | +class Revision(models.Model, HitCounterModelMixin): |
48 | key = models.TextField(blank=True, primary_key=True) | 48 | key = models.TextField(blank=True, primary_key=True) |
49 | rev = models.TextField(blank=True) | 49 | rev = models.TextField(blank=True) |
50 | author = models.TextField(blank=True) | 50 | author = models.TextField(blank=True) |
@@ -65,7 +65,7 @@ class Revision(models.Model, HitCountModelMixin): | @@ -65,7 +65,7 @@ class Revision(models.Model, HitCountModelMixin): | ||
65 | except User.DoesNotExist: | 65 | except User.DoesNotExist: |
66 | return None | 66 | return None |
67 | 67 | ||
68 | -class Ticket(models.Model, HitCountModelMixin): | 68 | +class Ticket(models.Model, HitCounterModelMixin): |
69 | id = models.IntegerField(primary_key=True) | 69 | id = models.IntegerField(primary_key=True) |
70 | summary = models.TextField(blank=True) | 70 | summary = models.TextField(blank=True) |
71 | description = models.TextField(blank=True) | 71 | description = models.TextField(blank=True) |
@@ -96,7 +96,7 @@ class Ticket(models.Model, HitCountModelMixin): | @@ -96,7 +96,7 @@ class Ticket(models.Model, HitCountModelMixin): | ||
96 | return None | 96 | return None |
97 | 97 | ||
98 | 98 | ||
99 | -class Wiki(models.Model, HitCountModelMixin): | 99 | +class Wiki(models.Model, HitCounterModelMixin): |
100 | name = models.TextField(primary_key=True) | 100 | name = models.TextField(primary_key=True) |
101 | wiki_text = models.TextField(blank=True) | 101 | wiki_text = models.TextField(blank=True) |
102 | author = models.TextField(blank=True) | 102 | author = models.TextField(blank=True) |
src/proxy/views.py
@@ -5,13 +5,13 @@ from django.conf import settings | @@ -5,13 +5,13 @@ from django.conf import settings | ||
5 | 5 | ||
6 | from revproxy.views import ProxyView | 6 | from revproxy.views import ProxyView |
7 | from .models import Wiki, Ticket, Revision | 7 | from .models import Wiki, Ticket, Revision |
8 | -from hitcount.views import HitCountViewMixin | 8 | +from hitcounter.views import HitCounterViewMixin |
9 | 9 | ||
10 | 10 | ||
11 | CWD = os.path.abspath(os.path.dirname(__file__)) | 11 | CWD = os.path.abspath(os.path.dirname(__file__)) |
12 | DIAZO_RULES_DIR = os.path.join(CWD, 'diazo') | 12 | DIAZO_RULES_DIR = os.path.join(CWD, 'diazo') |
13 | 13 | ||
14 | -class TracProxyView(HitCountViewMixin, ProxyView): | 14 | +class TracProxyView(HitCounterViewMixin, ProxyView): |
15 | base_url = settings.COLAB_TRAC_URL | 15 | base_url = settings.COLAB_TRAC_URL |
16 | add_remote_user = settings.REVPROXY_ADD_REMOTE_USER | 16 | add_remote_user = settings.REVPROXY_ADD_REMOTE_USER |
17 | diazo_theme_template = 'proxy/trac.html' | 17 | diazo_theme_template = 'proxy/trac.html' |
src/super_archives/models.py
@@ -14,7 +14,7 @@ from django.utils.translation import ugettext_lazy as _ | @@ -14,7 +14,7 @@ from django.utils.translation import ugettext_lazy as _ | ||
14 | from html2text import html2text | 14 | from html2text import html2text |
15 | from haystack.query import SearchQuerySet | 15 | from haystack.query import SearchQuerySet |
16 | from taggit.managers import TaggableManager | 16 | from taggit.managers import TaggableManager |
17 | -from hitcount.models import HitCountModelMixin | 17 | +from hitcounter.models import HitCounterModelMixin |
18 | 18 | ||
19 | from .utils import blocks | 19 | from .utils import blocks |
20 | from .utils.etiquetador import etiquetador | 20 | from .utils.etiquetador import etiquetador |
@@ -108,7 +108,7 @@ class Keyword(models.Model): | @@ -108,7 +108,7 @@ class Keyword(models.Model): | ||
108 | return self.keyword | 108 | return self.keyword |
109 | 109 | ||
110 | 110 | ||
111 | -class Thread(models.Model, HitCountModelMixin): | 111 | +class Thread(models.Model, HitCounterModelMixin): |
112 | 112 | ||
113 | subject_token = models.CharField(max_length=512) | 113 | subject_token = models.CharField(max_length=512) |
114 | mailinglist = models.ForeignKey(MailingList, | 114 | mailinglist = models.ForeignKey(MailingList, |