[extensions-web] Add and from now on populate 'popularity': (enables - disables)



commit 447fd5f6971db7256a1a8c9e359457752807214b
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Fri Dec 16 02:58:45 2011 -0500

    Add and from now on populate 'popularity': (enables - disables)
    
    An extension's popularity is the number of enables minus the number of
    disables. Because Django's ORM isn't quite up to the task of doing this
    math in the sorting of the query quite yet, we track this as three
    separate fields in the database: enables, disables and popularity.
    
    From now on, the JavaScript associated with enabling/disabling an
    extension will also ping back to the server to keep track of this
    anonymous data, used entirely for statistics.

 ...enables__add_field_extension_disables__add_f.py |  106 ++++++++++++++++++++
 sweettooth/extensions/models.py                    |    4 +
 sweettooth/extensions/urls.py                      |    1 +
 sweettooth/extensions/views.py                     |   22 ++++-
 sweettooth/static/js/extensions.js                 |   11 ++-
 5 files changed, 142 insertions(+), 2 deletions(-)
---
diff --git a/sweettooth/extensions/migrations/0011_auto__add_field_extension_enables__add_field_extension_disables__add_f.py b/sweettooth/extensions/migrations/0011_auto__add_field_extension_enables__add_field_extension_disables__add_f.py
new file mode 100644
index 0000000..486d0fb
--- /dev/null
+++ b/sweettooth/extensions/migrations/0011_auto__add_field_extension_enables__add_field_extension_disables__add_f.py
@@ -0,0 +1,106 @@
+# 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 'Extension.enables'
+        db.add_column('extensions_extension', 'enables', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
+
+        # Adding field 'Extension.disables'
+        db.add_column('extensions_extension', 'disables', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
+
+        # Adding field 'Extension.popularity'
+        db.add_column('extensions_extension', 'popularity', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
+
+
+    def backwards(self, orm):
+        
+        # Deleting field 'Extension.enables'
+        db.delete_column('extensions_extension', 'enables')
+
+        # Deleting field 'Extension.disables'
+        db.delete_column('extensions_extension', 'disables')
+
+        # Deleting field 'Extension.popularity'
+        db.delete_column('extensions_extension', 'popularity')
+
+
+    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'})
+        },
+        'extensions.extension': {
+            'Meta': {'object_name': 'Extension'},
+            'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'creator': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'disables': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'downloads': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+            'enables': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'icon': ('django.db.models.fields.files.ImageField', [], {'default': "'/static/images/plugin.png'", 'max_length': '100', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+            'popularity': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'screenshot': ('sorl.thumbnail.fields.ImageField', [], {'max_length': '100', 'blank': 'True'}),
+            'slug': ('autoslug.fields.AutoSlugField', [], {'unique_with': '()', 'max_length': '50', 'populate_from': 'None', 'db_index': 'True'}),
+            'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
+            'uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200', 'db_index': 'True'})
+        },
+        'extensions.extensionversion': {
+            'Meta': {'unique_together': "(('extension', 'version'),)", 'object_name': 'ExtensionVersion'},
+            'extension': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'versions'", 'to': "orm['extensions.Extension']"}),
+            'extra_json_fields': ('django.db.models.fields.TextField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'shell_versions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['extensions.ShellVersion']", 'symmetrical': 'False'}),
+            'source': ('django.db.models.fields.files.FileField', [], {'max_length': '223'}),
+            'status': ('django.db.models.fields.PositiveIntegerField', [], {}),
+            'version': ('django.db.models.fields.IntegerField', [], {'default': '0'})
+        },
+        'extensions.shellversion': {
+            'Meta': {'object_name': 'ShellVersion'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'major': ('django.db.models.fields.PositiveIntegerField', [], {}),
+            'minor': ('django.db.models.fields.PositiveIntegerField', [], {}),
+            'point': ('django.db.models.fields.IntegerField', [], {})
+        }
+    }
+
+    complete_apps = ['extensions']
diff --git a/sweettooth/extensions/models.py b/sweettooth/extensions/models.py
index 6931fc8..f7d807a 100644
--- a/sweettooth/extensions/models.py
+++ b/sweettooth/extensions/models.py
@@ -73,6 +73,10 @@ class Extension(models.Model):
     created = models.DateTimeField(auto_now_add=True)
     downloads = models.PositiveIntegerField(default=0)
 
+    enables = models.IntegerField(default=0)
+    disables = models.IntegerField(default=0)
+    popularity = models.IntegerField(default=0)
+
     class Meta:
         permissions = (
             ("can-modify-data", "Can modify extension data"),
diff --git a/sweettooth/extensions/urls.py b/sweettooth/extensions/urls.py
index bc9a154..6dc7214 100644
--- a/sweettooth/extensions/urls.py
+++ b/sweettooth/extensions/urls.py
@@ -21,6 +21,7 @@ ajax_patterns = patterns('',
     url(r'^set-status/inactive/', views.ajax_set_status_view,
         dict(newstatus=models.STATUS_INACTIVE), name='extensions-ajax-set-status-inactive'),
     url(r'^extensions-list/', views.ajax_extensions_list),
+    url(r'^adjust-popularity/', views.ajax_adjust_popularity_view),
 )
 
 shell_patterns = patterns('',
diff --git a/sweettooth/extensions/views.py b/sweettooth/extensions/views.py
index 7dee4ef..935fe5a 100644
--- a/sweettooth/extensions/views.py
+++ b/sweettooth/extensions/views.py
@@ -4,7 +4,7 @@ from django.core.paginator import Paginator, InvalidPage
 from django.core.urlresolvers import reverse
 from django.contrib.auth.decorators import login_required
 from django.contrib import messages
-from django.http import HttpResponseForbidden, Http404
+from django.http import HttpResponseForbidden, HttpResponseServerError, Http404
 from django.shortcuts import get_object_or_404, redirect
 from django.template.loader import render_to_string
 from django.utils.safestring import mark_safe
@@ -60,6 +60,8 @@ def ajax_query_params_query(request):
         queryset = queryset.order_by('-pk')
     elif sort == 'downloads':
         queryset = queryset.order_by('-downloads')
+    elif sort == 'popularity':
+        queryset = queryset.order_by('-popularity')
     else:
         queryset = queryset.order_by('name')
 
@@ -212,6 +214,24 @@ def extension_version_view(request, obj, **kwargs):
     return render(request, template_name, context)
 
 @ajax_view
+def ajax_adjust_popularity_view(request):
+    uuid = request.GET['uuid']
+    action = request.GET['action']
+
+    extension = models.Extension.objects.get(uuid=uuid)
+
+    if action == 'enable':
+        extension.enables += 1
+        extension.popularity += 1
+    elif action == 'disable':
+        extension.disables += 1
+        extension.popularity -= 1
+    else:
+        return HttpResponseServerError()
+
+    extension.save()
+
+ ajax_view
 @require_POST
 @model_view(models.ExtensionVersion)
 def ajax_submit_and_lock_view(request, obj):
diff --git a/sweettooth/static/js/extensions.js b/sweettooth/static/js/extensions.js
index 9e475f9..a23a692 100644
--- a/sweettooth/static/js/extensions.js
+++ b/sweettooth/static/js/extensions.js
@@ -100,6 +100,12 @@ function($, messages, dbusProxy, extensionUtils) {
         if ($switch.hasClass('insensitive'))
             return;
 
+        function sendPopularity(action) {
+            $.ajax({ url: '/ajax/adjust-popularity/',
+                     data: { uuid: uuid,
+                             action: action } });
+        }
+
         $switch.bind('changed', function(e, newValue) {
             var oldState = $elem.data('state');
             if (newValue) {
@@ -110,10 +116,13 @@ function($, messages, dbusProxy, extensionUtils) {
                 } else if (oldState == ExtensionState.DISABLED ||
                            oldState == ExtensionState.INITIALIZED) {
                     dbusProxy.EnableExtension(uuid);
+                    sendPopularity('enable');
                 }
             } else {
-                if (oldState == ExtensionState.ENABLED)
+                if (oldState == ExtensionState.ENABLED) {
                     dbusProxy.DisableExtension(uuid);
+                    sendPopularity('disable');
+                }
             }
         });
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]