diff --git a/readthedocs/core/static-src/core/js/readthedocs-doc-embed.js b/readthedocs/core/static-src/core/js/readthedocs-doc-embed.js index 5e8bad04293..f7fcbc21dcd 100644 --- a/readthedocs/core/static-src/core/js/readthedocs-doc-embed.js +++ b/readthedocs/core/static-src/core/js/readthedocs-doc-embed.js @@ -59,15 +59,12 @@ $(document).ready(function () { // Show promo selectively if (data.promo && build.show_promo()) { - // TODO don't hardcode this promo - var promo = sponsorship.Promo.from_variants([ - { - id: 'wtd-eu', - text: 'Write the Docs Europe, in Prague Aug 31 - Sep 1. Buy your ticket now!', - link: 'http://www.writethedocs.org/conf/eu/2015/', - image: 'https://70247537a87b983da006-a47a8cc3edeb6b00d7ff1d6a25af0fda.ssl.cf5.rackcdn.com/wtd-promo.png' - } - ]); + var promo = sponsorship.Promo.from_variant([ + id=data.promo_data.id, + text=data.promo_data.text, + image=data.promo_data.image, + link=data.promo_data.link + ]) if (promo) { promo.display(); } diff --git a/readthedocs/core/static/core/js/readthedocs-doc-embed.js b/readthedocs/core/static/core/js/readthedocs-doc-embed.js index 8713997d3d2..5a6fd96b002 100644 --- a/readthedocs/core/static/core/js/readthedocs-doc-embed.js +++ b/readthedocs/core/static/core/js/readthedocs-doc-embed.js @@ -98,15 +98,12 @@ $(document).ready(function () { // Show promo selectively if (data.promo && build.show_promo()) { - // TODO don't hardcode this promo - var promo = sponsorship.Promo.from_variants([ - { - id: 'wtd-eu', - text: 'Write the Docs Europe, in Prague Aug 31 - Sep 1. Buy your ticket now!', - link: 'http://www.writethedocs.org/conf/eu/2015/', - image: 'https://70247537a87b983da006-a47a8cc3edeb6b00d7ff1d6a25af0fda.ssl.cf5.rackcdn.com/wtd-promo.png' - } - ]); + var promo = sponsorship.Promo.from_variant([ + id=data.promo_data.id, + text=data.promo_data.text, + image=data.promo_data.image, + link=data.promo_data.link + ]) if (promo) { promo.display(); } diff --git a/readthedocs/donate/admin.py b/readthedocs/donate/admin.py index d186132f10e..dcb60641a9f 100644 --- a/readthedocs/donate/admin.py +++ b/readthedocs/donate/admin.py @@ -1,5 +1,6 @@ from django.contrib import admin -from .models import Supporter +from .models import Supporter, SupporterPromo + class SupporterAdmin(admin.ModelAdmin): model = Supporter @@ -7,5 +8,12 @@ class SupporterAdmin(admin.ModelAdmin): list_display = ('name', 'email', 'dollars', 'public') list_filter = ('name', 'email', 'dollars', 'public') -admin.site.register(Supporter, SupporterAdmin) +class SupporterPromoAdmin(admin.ModelAdmin): + model = SupporterPromo + list_display = ('name', 'display_type', 'text', 'live') + list_filter = ('live', 'display_type') + + +admin.site.register(Supporter, SupporterAdmin) +admin.site.register(SupporterPromo, SupporterPromoAdmin) diff --git a/readthedocs/donate/migrations/0003_add_promo.py b/readthedocs/donate/migrations/0003_add_promo.py new file mode 100644 index 00000000000..65ecdf1187b --- /dev/null +++ b/readthedocs/donate/migrations/0003_add_promo.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as 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 'SupporterPromo' + db.create_table(u'donate_supporterpromo', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('pub_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('modified_date', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)), + ('name', self.gf('django.db.models.fields.CharField')(max_length=200)), + ('analytics_id', self.gf('django.db.models.fields.CharField')(max_length=200)), + ('text', self.gf('django.db.models.fields.TextField')(blank=True)), + ('link', self.gf('django.db.models.fields.URLField')(max_length=255, null=True, blank=True)), + ('image', self.gf('django.db.models.fields.URLField')(max_length=255, null=True, blank=True)), + ('live', self.gf('django.db.models.fields.BooleanField')(default=False)), + )) + db.send_create_signal(u'donate', ['SupporterPromo']) + + + def backwards(self, orm): + # Deleting model 'SupporterPromo' + db.delete_table(u'donate_supporterpromo') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 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'donate.supporter': { + 'Meta': {'object_name': 'Supporter'}, + 'dollars': ('django.db.models.fields.IntegerField', [], {'default': '50', 'max_length': '30'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '200', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_4_digits': ('django.db.models.fields.CharField', [], {'max_length': '4'}), + 'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'modified_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'site_url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'stripe_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'subscribed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'goldonce'", 'null': 'True', 'to': u"orm['auth.User']"}) + }, + u'donate.supporterpromo': { + 'Meta': {'object_name': 'SupporterPromo'}, + 'analytics_id': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'link': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'live': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'modified_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'text': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + } + } + + complete_apps = ['donate'] \ No newline at end of file diff --git a/readthedocs/donate/migrations/0004_add_type.py b/readthedocs/donate/migrations/0004_add_type.py new file mode 100644 index 00000000000..6ab3a747197 --- /dev/null +++ b/readthedocs/donate/migrations/0004_add_type.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as 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 'SupporterPromo.display_type' + db.add_column(u'donate_supporterpromo', 'display_type', + self.gf('django.db.models.fields.CharField')(default='doc', max_length=200), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'SupporterPromo.display_type' + db.delete_column(u'donate_supporterpromo', 'display_type') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'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': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'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', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 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'donate.supporter': { + 'Meta': {'object_name': 'Supporter'}, + 'dollars': ('django.db.models.fields.IntegerField', [], {'default': '50', 'max_length': '30'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '200', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_4_digits': ('django.db.models.fields.CharField', [], {'max_length': '4'}), + 'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'modified_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'site_url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'stripe_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'subscribed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'goldonce'", 'null': 'True', 'to': u"orm['auth.User']"}) + }, + u'donate.supporterpromo': { + 'Meta': {'object_name': 'SupporterPromo'}, + 'analytics_id': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'display_type': ('django.db.models.fields.CharField', [], {'default': "'doc'", 'max_length': '200'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'link': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'live': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'modified_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'text': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + } + } + + complete_apps = ['donate'] \ No newline at end of file diff --git a/readthedocs/donate/models.py b/readthedocs/donate/models.py index 1136f78212c..e17d678cf85 100644 --- a/readthedocs/donate/models.py +++ b/readthedocs/donate/models.py @@ -18,6 +18,12 @@ (8000, '4 Weeks ($8000)'), ) +DISPLAY_CHOICES = ( + ('doc', 'Documentation Pages'), + ('site-footer', 'Site Footer'), + ('search', 'Search Pages'), +) + class Supporter(models.Model): pub_date = models.DateTimeField(_('Publication date'), auto_now_add=True) @@ -41,3 +47,30 @@ class Supporter(models.Model): def __str__(self): return self.name + + +class SupporterPromo(models.Model): + pub_date = models.DateTimeField(_('Publication date'), auto_now_add=True) + modified_date = models.DateTimeField(_('Modified date'), auto_now=True) + + name = models.CharField(_('Name'), max_length=200) + analytics_id = models.CharField(_('Analytics ID'), max_length=200) + text = models.TextField(_('Text'), blank=True) + link = models.URLField(_('Link URL'), max_length=255, blank=True, null=True) + image = models.URLField(_('Image URL'), max_length=255, blank=True, null=True) + display_type = models.CharField(_('Display Type'), max_length=200, + choices=DISPLAY_CHOICES, default='doc') + + live = models.BooleanField(_('Live'), default=False) + + def __str__(self): + return self.name + + def as_dict(self): + "A dict respresentation of this for JSON encoding" + return { + 'id': self.analytics_id, + 'text': self.text, + 'link': self.link, + 'image': self.image, + } diff --git a/readthedocs/restapi/views/footer_views.py b/readthedocs/restapi/views/footer_views.py index f09eff06d31..c720433fc17 100644 --- a/readthedocs/restapi/views/footer_views.py +++ b/readthedocs/restapi/views/footer_views.py @@ -9,6 +9,7 @@ from builds.models import Version from projects.models import Project +from donate.models import SupporterPromo @decorators.api_view(['GET']) @@ -59,6 +60,8 @@ def footer_html(request): if project.gold_owners.count(): show_promo = False + promo_obj = SupporterPromo.objects.filter(live=True, display_type='doc').order_by('?').first() + context = Context({ 'project': project, 'path': path, @@ -80,9 +83,12 @@ def footer_html(request): context.update(csrf(request)) html = template_loader.get_template('restapi/footer.html').render(context) - return Response({ + resp_data = { 'html': html, 'version_active': version.active, 'version_supported': version.supported, 'promo': show_promo, - }) + } + if show_promo and promo_obj: + resp_data['promo_data'] = promo_obj.as_dict() + return Response(resp_data)