Skip to content

Commit 0a82c33

Browse files
committed
Merge pull request #1413 from rtfd/db-promo
Add a small SupporterPromo model for showing promos
2 parents 9f0f253 + fa635d3 commit 0a82c33

File tree

7 files changed

+251
-22
lines changed

7 files changed

+251
-22
lines changed

readthedocs/core/static-src/core/js/readthedocs-doc-embed.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,12 @@ $(document).ready(function () {
5959

6060
// Show promo selectively
6161
if (data.promo && build.show_promo()) {
62-
// TODO don't hardcode this promo
63-
var promo = sponsorship.Promo.from_variants([
64-
{
65-
id: 'wtd-eu',
66-
text: 'Write the Docs Europe, in Prague Aug 31 - Sep 1. <a>Buy your ticket now!</a>',
67-
link: 'http://www.writethedocs.org/conf/eu/2015/',
68-
image: 'https://70247537a87b983da006-a47a8cc3edeb6b00d7ff1d6a25af0fda.ssl.cf5.rackcdn.com/wtd-promo.png'
69-
}
70-
]);
62+
var promo = sponsorship.Promo.from_variant([
63+
id=data.promo_data.id,
64+
text=data.promo_data.text,
65+
image=data.promo_data.image,
66+
link=data.promo_data.link
67+
])
7168
if (promo) {
7269
promo.display();
7370
}

readthedocs/core/static/core/js/readthedocs-doc-embed.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,12 @@ $(document).ready(function () {
9898

9999
// Show promo selectively
100100
if (data.promo && build.show_promo()) {
101-
// TODO don't hardcode this promo
102-
var promo = sponsorship.Promo.from_variants([
103-
{
104-
id: 'wtd-eu',
105-
text: 'Write the Docs Europe, in Prague Aug 31 - Sep 1. <a>Buy your ticket now!</a>',
106-
link: 'http://www.writethedocs.org/conf/eu/2015/',
107-
image: 'https://70247537a87b983da006-a47a8cc3edeb6b00d7ff1d6a25af0fda.ssl.cf5.rackcdn.com/wtd-promo.png'
108-
}
109-
]);
101+
var promo = sponsorship.Promo.from_variant([
102+
id=data.promo_data.id,
103+
text=data.promo_data.text,
104+
image=data.promo_data.image,
105+
link=data.promo_data.link
106+
])
110107
if (promo) {
111108
promo.display();
112109
}

readthedocs/donate/admin.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
from django.contrib import admin
2-
from .models import Supporter
2+
from .models import Supporter, SupporterPromo
3+
34

45
class SupporterAdmin(admin.ModelAdmin):
56
model = Supporter
67
raw_id_fields = ('user',)
78
list_display = ('name', 'email', 'dollars', 'public')
89
list_filter = ('name', 'email', 'dollars', 'public')
910

10-
admin.site.register(Supporter, SupporterAdmin)
1111

12+
class SupporterPromoAdmin(admin.ModelAdmin):
13+
model = SupporterPromo
14+
list_display = ('name', 'display_type', 'text', 'live')
15+
list_filter = ('live', 'display_type')
16+
17+
18+
admin.site.register(Supporter, SupporterAdmin)
19+
admin.site.register(SupporterPromo, SupporterPromoAdmin)
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# -*- coding: utf-8 -*-
2+
from south.utils import datetime_utils as 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 'SupporterPromo'
12+
db.create_table(u'donate_supporterpromo', (
13+
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
14+
('pub_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
15+
('modified_date', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, blank=True)),
16+
('name', self.gf('django.db.models.fields.CharField')(max_length=200)),
17+
('analytics_id', self.gf('django.db.models.fields.CharField')(max_length=200)),
18+
('text', self.gf('django.db.models.fields.TextField')(blank=True)),
19+
('link', self.gf('django.db.models.fields.URLField')(max_length=255, null=True, blank=True)),
20+
('image', self.gf('django.db.models.fields.URLField')(max_length=255, null=True, blank=True)),
21+
('live', self.gf('django.db.models.fields.BooleanField')(default=False)),
22+
))
23+
db.send_create_signal(u'donate', ['SupporterPromo'])
24+
25+
26+
def backwards(self, orm):
27+
# Deleting model 'SupporterPromo'
28+
db.delete_table(u'donate_supporterpromo')
29+
30+
31+
models = {
32+
u'auth.group': {
33+
'Meta': {'object_name': 'Group'},
34+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
35+
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
36+
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
37+
},
38+
u'auth.permission': {
39+
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
40+
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
41+
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
42+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
43+
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
44+
},
45+
u'auth.user': {
46+
'Meta': {'object_name': 'User'},
47+
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
48+
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
49+
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
50+
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
51+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
52+
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
53+
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
54+
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
55+
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
56+
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
57+
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
58+
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
59+
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
60+
},
61+
u'contenttypes.contenttype': {
62+
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
63+
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
64+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
65+
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
66+
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
67+
},
68+
u'donate.supporter': {
69+
'Meta': {'object_name': 'Supporter'},
70+
'dollars': ('django.db.models.fields.IntegerField', [], {'default': '50', 'max_length': '30'}),
71+
'email': ('django.db.models.fields.EmailField', [], {'max_length': '200', 'blank': 'True'}),
72+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
73+
'last_4_digits': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
74+
'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
75+
'modified_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
76+
'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
77+
'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
78+
'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
79+
'site_url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
80+
'stripe_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
81+
'subscribed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
82+
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'goldonce'", 'null': 'True', 'to': u"orm['auth.User']"})
83+
},
84+
u'donate.supporterpromo': {
85+
'Meta': {'object_name': 'SupporterPromo'},
86+
'analytics_id': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
87+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
88+
'image': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
89+
'link': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
90+
'live': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
91+
'modified_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
92+
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
93+
'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
94+
'text': ('django.db.models.fields.TextField', [], {'blank': 'True'})
95+
}
96+
}
97+
98+
complete_apps = ['donate']
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# -*- coding: utf-8 -*-
2+
from south.utils import datetime_utils as 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 field 'SupporterPromo.display_type'
12+
db.add_column(u'donate_supporterpromo', 'display_type',
13+
self.gf('django.db.models.fields.CharField')(default='doc', max_length=200),
14+
keep_default=False)
15+
16+
17+
def backwards(self, orm):
18+
# Deleting field 'SupporterPromo.display_type'
19+
db.delete_column(u'donate_supporterpromo', 'display_type')
20+
21+
22+
models = {
23+
u'auth.group': {
24+
'Meta': {'object_name': 'Group'},
25+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
26+
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
27+
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
28+
},
29+
u'auth.permission': {
30+
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
31+
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
32+
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
33+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
34+
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
35+
},
36+
u'auth.user': {
37+
'Meta': {'object_name': 'User'},
38+
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
39+
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
40+
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
41+
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
42+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
43+
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
44+
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
45+
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
46+
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
47+
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
48+
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
49+
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
50+
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
51+
},
52+
u'contenttypes.contenttype': {
53+
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
54+
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
55+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
56+
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
57+
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
58+
},
59+
u'donate.supporter': {
60+
'Meta': {'object_name': 'Supporter'},
61+
'dollars': ('django.db.models.fields.IntegerField', [], {'default': '50', 'max_length': '30'}),
62+
'email': ('django.db.models.fields.EmailField', [], {'max_length': '200', 'blank': 'True'}),
63+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
64+
'last_4_digits': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
65+
'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
66+
'modified_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
67+
'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
68+
'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
69+
'public': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
70+
'site_url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
71+
'stripe_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
72+
'subscribed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
73+
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'goldonce'", 'null': 'True', 'to': u"orm['auth.User']"})
74+
},
75+
u'donate.supporterpromo': {
76+
'Meta': {'object_name': 'SupporterPromo'},
77+
'analytics_id': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
78+
'display_type': ('django.db.models.fields.CharField', [], {'default': "'doc'", 'max_length': '200'}),
79+
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
80+
'image': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
81+
'link': ('django.db.models.fields.URLField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
82+
'live': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
83+
'modified_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
84+
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
85+
'pub_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
86+
'text': ('django.db.models.fields.TextField', [], {'blank': 'True'})
87+
}
88+
}
89+
90+
complete_apps = ['donate']

readthedocs/donate/models.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
(8000, '4 Weeks ($8000)'),
1919
)
2020

21+
DISPLAY_CHOICES = (
22+
('doc', 'Documentation Pages'),
23+
('site-footer', 'Site Footer'),
24+
('search', 'Search Pages'),
25+
)
26+
2127

2228
class Supporter(models.Model):
2329
pub_date = models.DateTimeField(_('Publication date'), auto_now_add=True)
@@ -41,3 +47,30 @@ class Supporter(models.Model):
4147

4248
def __str__(self):
4349
return self.name
50+
51+
52+
class SupporterPromo(models.Model):
53+
pub_date = models.DateTimeField(_('Publication date'), auto_now_add=True)
54+
modified_date = models.DateTimeField(_('Modified date'), auto_now=True)
55+
56+
name = models.CharField(_('Name'), max_length=200)
57+
analytics_id = models.CharField(_('Analytics ID'), max_length=200)
58+
text = models.TextField(_('Text'), blank=True)
59+
link = models.URLField(_('Link URL'), max_length=255, blank=True, null=True)
60+
image = models.URLField(_('Image URL'), max_length=255, blank=True, null=True)
61+
display_type = models.CharField(_('Display Type'), max_length=200,
62+
choices=DISPLAY_CHOICES, default='doc')
63+
64+
live = models.BooleanField(_('Live'), default=False)
65+
66+
def __str__(self):
67+
return self.name
68+
69+
def as_dict(self):
70+
"A dict respresentation of this for JSON encoding"
71+
return {
72+
'id': self.analytics_id,
73+
'text': self.text,
74+
'link': self.link,
75+
'image': self.image,
76+
}

readthedocs/restapi/views/footer_views.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from builds.models import Version
1111
from projects.models import Project
12+
from donate.models import SupporterPromo
1213

1314

1415
@decorators.api_view(['GET'])
@@ -59,6 +60,8 @@ def footer_html(request):
5960
if project.gold_owners.count():
6061
show_promo = False
6162

63+
promo_obj = SupporterPromo.objects.filter(live=True, display_type='doc').order_by('?').first()
64+
6265
context = Context({
6366
'project': project,
6467
'path': path,
@@ -80,9 +83,12 @@ def footer_html(request):
8083

8184
context.update(csrf(request))
8285
html = template_loader.get_template('restapi/footer.html').render(context)
83-
return Response({
86+
resp_data = {
8487
'html': html,
8588
'version_active': version.active,
8689
'version_supported': version.supported,
8790
'promo': show_promo,
88-
})
91+
}
92+
if show_promo and promo_obj:
93+
resp_data['promo_data'] = promo_obj.as_dict()
94+
return Response(resp_data)

0 commit comments

Comments
 (0)