Merge lp:~developer-ubuntu-com-dev/developer-ubuntu-com/show-gadgetsnap-images into lp:developer-ubuntu-com

Proposed by Daniel Holbach on 2015-11-10
Status: Merged
Merged at revision: 167
Proposed branch: lp:~developer-ubuntu-com-dev/developer-ubuntu-com/show-gadgetsnap-images
Merge into: lp:developer-ubuntu-com
Diff against target: 321 lines (+208/-18)
8 files modified
developer_portal/templatetags/text_extras.py (+8/-0)
store_data/cms_plugins.py (+20/-3)
store_data/management/commands/update-gadget-snaps.py (+5/-1)
store_data/migrations/0002_add_title_field.py (+58/-0)
store_data/migrations/0003_add_website_field.py (+59/-0)
store_data/models.py (+2/-0)
templates/gadget_snap_list.html (+24/-14)
templates/gadget_snap_shortlist.html (+32/-0)
To merge this branch: bzr merge lp:~developer-ubuntu-com-dev/developer-ubuntu-com/show-gadgetsnap-images
Reviewer Review Type Date Requested Status
Daniel Holbach (community) Approve on 2015-11-10
Review via email: mp+277089@code.launchpad.net

Commit Message

Show gadget snap images (icon_url instead of screenshot_url) and display a more readable name.

To post a comment you must log in.
169. By Daniel Holbach on 2015-11-10

remove unnecessary blank line

170. By David Callé on 2015-11-10

Add shortlist CMS plugin for gadget snaps, layout fixes

Daniel Holbach (dholbach) wrote :

Good to go!

review: Approve
171. By Daniel Holbach on 2015-11-10

simplify code and style generic-* snap names as well

172. By Daniel Holbach on 2015-11-10

use title field instead

173. By Daniel Holbach on 2015-11-10

fix -community name

174. By Daniel Holbach on 2015-11-10

add website field for store api

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'developer_portal/templatetags/text_extras.py'
2--- developer_portal/templatetags/text_extras.py 2015-07-02 19:51:07 +0000
3+++ developer_portal/templatetags/text_extras.py 2015-11-10 14:53:00 +0000
4@@ -24,3 +24,11 @@
5 @register.filter
6 def string(integer):
7 return str(integer)
8+
9+@register.filter
10+def style_snap_name(snap_name):
11+ if snap_name.startswith('generic-'):
12+ return 'Generic {}'.format(snap_name.split('-')[1])
13+ if snap_name.endswith('-community'):
14+ return snap_name.replace('-community', '').title()
15+ return snap_name.split('.')[0].title()
16
17=== modified file 'store_data/cms_plugins.py'
18--- store_data/cms_plugins.py 2015-07-02 15:43:26 +0000
19+++ store_data/cms_plugins.py 2015-11-10 14:53:00 +0000
20@@ -5,8 +5,10 @@
21 from .models import GadgetSnap
22
23
24-class GadgetSnapListPlugin(CMSPluginBase):
25- name = _("Gadget Snap List Plugin")
26+class GadgetSnapListPluginLarge(CMSPluginBase):
27+ # Keeping the name short to be able to differentiate them
28+ # in the editor dropdown
29+ name = _("Snap list - Gadget")
30 render_template = "gadget_snap_list.html"
31 text_enabled = True
32
33@@ -16,4 +18,19 @@
34 })
35 return context
36
37-plugin_pool.register_plugin(GadgetSnapListPlugin)
38+plugin_pool.register_plugin(GadgetSnapListPluginLarge)
39+
40+class GadgetSnapListPluginSmall(CMSPluginBase):
41+ # Keeping the name short to be able to differentiate them
42+ # in the editor dropdown
43+ name = _("Snap shortlist - Gadget")
44+ render_template = "gadget_snap_shortlist.html"
45+ text_enabled = True
46+
47+ def render(self, context, instance, placeholder):
48+ context.update({
49+ 'gadget_snap_list': GadgetSnap.objects.all(),
50+ })
51+ return context
52+
53+plugin_pool.register_plugin(GadgetSnapListPluginSmall)
54
55=== modified file 'store_data/management/commands/update-gadget-snaps.py'
56--- store_data/management/commands/update-gadget-snaps.py 2015-07-02 12:42:22 +0000
57+++ store_data/management/commands/update-gadget-snaps.py 2015-11-10 14:53:00 +0000
58@@ -20,7 +20,9 @@
59 'ratings_average': entry['ratings_average'],
60 'alias': entry['alias'], 'price': entry['price'],
61 'publisher': entry['publisher'], 'version': entry['version'],
62- 'last_updated': now, 'description': entry['description']})
63+ 'last_updated': now, 'description': entry['description'],
64+ 'title': entry['title'], 'website': entry.get('website', ''),
65+ })
66 if not created:
67 gadget_snap.last_updated = now
68 gadget_snap.icon_url = entry['icon_url']
69@@ -30,6 +32,8 @@
70 gadget_snap.publisher = entry['publisher']
71 gadget_snap.version = entry['version']
72 gadget_snap.description = entry['description']
73+ gadget_snap.title = entry['title']
74+ gadget_snap.website = entry.get('website', '')
75 gadget_snap.save()
76 for arch in entry['architecture']:
77 arch_ob, created = Architecture.objects.get_or_create(name=arch)
78
79=== added file 'store_data/migrations/0002_add_title_field.py'
80--- store_data/migrations/0002_add_title_field.py 1970-01-01 00:00:00 +0000
81+++ store_data/migrations/0002_add_title_field.py 2015-11-10 14:53:00 +0000
82@@ -0,0 +1,58 @@
83+# -*- coding: utf-8 -*-
84+from south.utils import datetime_utils as datetime
85+from south.db import db
86+from south.v2 import SchemaMigration
87+from django.db import models
88+
89+
90+class Migration(SchemaMigration):
91+
92+ def forwards(self, orm):
93+ # Adding field 'GadgetSnap.title'
94+ db.add_column(u'store_data_gadgetsnap', 'title',
95+ self.gf('django.db.models.fields.CharField')(max_length=250, null=True, blank=True),
96+ keep_default=False)
97+
98+
99+ def backwards(self, orm):
100+ # Deleting field 'GadgetSnap.title'
101+ db.delete_column(u'store_data_gadgetsnap', 'title')
102+
103+
104+ models = {
105+ u'store_data.architecture': {
106+ 'Meta': {'object_name': 'Architecture'},
107+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
108+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '10'})
109+ },
110+ u'store_data.gadgetsnap': {
111+ 'Meta': {'object_name': 'GadgetSnap'},
112+ 'alias': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
113+ 'architecture': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['store_data.Architecture']", 'symmetrical': 'False'}),
114+ 'description': ('django.db.models.fields.TextField', [], {'max_length': '5000'}),
115+ 'icon_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
116+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
117+ 'last_updated': ('django.db.models.fields.DateTimeField', [], {}),
118+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
119+ 'price': ('django.db.models.fields.DecimalField', [], {'max_digits': '5', 'decimal_places': '2'}),
120+ 'publisher': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
121+ 'ratings_average': ('django.db.models.fields.DecimalField', [], {'max_digits': '2', 'decimal_places': '1'}),
122+ 'release': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['store_data.Release']", 'symmetrical': 'False'}),
123+ 'screenshot_url': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['store_data.ScreenshotURL']", 'symmetrical': 'False'}),
124+ 'store_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
125+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
126+ 'version': ('django.db.models.fields.CharField', [], {'max_length': '25'})
127+ },
128+ u'store_data.release': {
129+ 'Meta': {'object_name': 'Release'},
130+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
131+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '25'})
132+ },
133+ u'store_data.screenshoturl': {
134+ 'Meta': {'object_name': 'ScreenshotURL'},
135+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
136+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
137+ }
138+ }
139+
140+ complete_apps = ['store_data']
141\ No newline at end of file
142
143=== added file 'store_data/migrations/0003_add_website_field.py'
144--- store_data/migrations/0003_add_website_field.py 1970-01-01 00:00:00 +0000
145+++ store_data/migrations/0003_add_website_field.py 2015-11-10 14:53:00 +0000
146@@ -0,0 +1,59 @@
147+# -*- coding: utf-8 -*-
148+from south.utils import datetime_utils as datetime
149+from south.db import db
150+from south.v2 import SchemaMigration
151+from django.db import models
152+
153+
154+class Migration(SchemaMigration):
155+
156+ def forwards(self, orm):
157+ # Adding field 'GadgetSnap.website'
158+ db.add_column(u'store_data_gadgetsnap', 'website',
159+ self.gf('django.db.models.fields.URLField')(default='', max_length=200, blank=True),
160+ keep_default=False)
161+
162+
163+ def backwards(self, orm):
164+ # Deleting field 'GadgetSnap.website'
165+ db.delete_column(u'store_data_gadgetsnap', 'website')
166+
167+
168+ models = {
169+ u'store_data.architecture': {
170+ 'Meta': {'object_name': 'Architecture'},
171+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
172+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '10'})
173+ },
174+ u'store_data.gadgetsnap': {
175+ 'Meta': {'object_name': 'GadgetSnap'},
176+ 'alias': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
177+ 'architecture': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['store_data.Architecture']", 'symmetrical': 'False'}),
178+ 'description': ('django.db.models.fields.TextField', [], {'max_length': '5000'}),
179+ 'icon_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
180+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
181+ 'last_updated': ('django.db.models.fields.DateTimeField', [], {}),
182+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
183+ 'price': ('django.db.models.fields.DecimalField', [], {'max_digits': '5', 'decimal_places': '2'}),
184+ 'publisher': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
185+ 'ratings_average': ('django.db.models.fields.DecimalField', [], {'max_digits': '2', 'decimal_places': '1'}),
186+ 'release': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['store_data.Release']", 'symmetrical': 'False'}),
187+ 'screenshot_url': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['store_data.ScreenshotURL']", 'symmetrical': 'False'}),
188+ 'store_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
189+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}),
190+ 'version': ('django.db.models.fields.CharField', [], {'max_length': '25'}),
191+ 'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
192+ },
193+ u'store_data.release': {
194+ 'Meta': {'object_name': 'Release'},
195+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
196+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '25'})
197+ },
198+ u'store_data.screenshoturl': {
199+ 'Meta': {'object_name': 'ScreenshotURL'},
200+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
201+ 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
202+ }
203+ }
204+
205+ complete_apps = ['store_data']
206\ No newline at end of file
207
208=== modified file 'store_data/models.py'
209--- store_data/models.py 2015-07-02 08:49:35 +0000
210+++ store_data/models.py 2015-11-10 14:53:00 +0000
211@@ -17,6 +17,7 @@
212 icon_url = models.URLField(blank=True)
213 release = models.ManyToManyField(Release)
214 name = models.CharField(max_length=100)
215+ title = models.CharField(max_length=250, blank=True, null=True)
216 ratings_average = models.DecimalField(max_digits=2, decimal_places=1)
217 alias = models.CharField(max_length=100, blank=True, null=True)
218 price = models.DecimalField(max_digits=5, decimal_places=2)
219@@ -27,3 +28,4 @@
220 last_updated = models.DateTimeField()
221 description = models.TextField(max_length=5000)
222 screenshot_url = models.ManyToManyField(ScreenshotURL)
223+ website = models.URLField(blank=True)
224
225=== modified file 'templates/gadget_snap_list.html'
226--- templates/gadget_snap_list.html 2015-07-03 08:00:09 +0000
227+++ templates/gadget_snap_list.html 2015-11-10 14:53:00 +0000
228@@ -1,32 +1,42 @@
229 {% load i18n static text_extras %}
230
231-<div class="row equal-height no-border">
232- {% for snap in gadget_snap_list %}
233- {% if gadget_snap_list|index:snap|divisibleby:3 %}
234- <div class="left four-col last-col box">
235+<div class="no-border">
236+ {% for snap in gadget_snap_list %}
237+ {% if gadget_snap_list|index:snap|divisibleby:1 %}
238+ <div class="left twelve-col last-col box">
239 {% else %}
240- <div class="left four-col box">
241+ <div class="left twelve-col box">
242 {% endif %}
243- {% if snap.screenshot_url.0.url %}
244- <p><img src="{{ snap.screenshot_url.0.url }}"/></p>
245+ {% if snap.icon_url %}
246+ <div class="two-col no-margin-bottom">
247+ <img src="{{ snap.icon_url }}"/>
248+ </div>
249 {% else %}
250 {% with 0|randint:10|string as rand %}
251 {% with "img/boards/noboard-"|add:rand|add:".png" as noboard %}
252- <p><img src="{% static noboard %}"/></p>
253+ <div class="two-col no-margin-bottom">
254+ <img src="{% static noboard %}"/>
255+ </div>
256 {% endwith %}
257 {% endwith %}
258 {% endif %}
259- <h3>{{ snap.alias|default_if_none:snap.name }}</h3>
260+ <div class="ten-col last-col no-margin-bottom">
261+ <h3>
262+ {% with snap_name=snap.title|default_if_none:snap.name %}
263+ {{ snap_name|style_snap_name }}
264+ {% endwith %}
265+ </h3>
266 {% if snap.description|length > 180 %}
267 <p>{{ snap.description|truncatechars:180 }}</p>
268 {% else %}
269 <p>{% autoescape off %}{{ snap.description|html_links }}{% endautoescape %}</p>
270 {% endif %}
271- <ul class="list-ubuntu">
272- <li>
273- <a href="https://developer.ubuntu.com/en/snappy/start/">{% trans "Install Snappy on this device" %}</a>
274- </li>
275- </ul>
276+ <ul class="list-ubuntu">
277+ <li>
278+ <a href="https://developer.ubuntu.com/en/snappy/start/">{% trans "Install Snappy on this device" %}</a>
279+ </li>
280+ </ul>
281+ </div>
282 </div>
283 {% endfor %}
284 </div>
285
286=== added file 'templates/gadget_snap_shortlist.html'
287--- templates/gadget_snap_shortlist.html 1970-01-01 00:00:00 +0000
288+++ templates/gadget_snap_shortlist.html 2015-11-10 14:53:00 +0000
289@@ -0,0 +1,32 @@
290+{% load i18n static text_extras %}
291+
292+<div class="equal-height no-border">
293+ {% for snap in gadget_snap_list|slice:"6" %}
294+ {% if gadget_snap_list|index:snap|divisibleby:6 %}
295+ <div class="two-col last-col box">
296+ {% else %}
297+ <div class="two-col box">
298+ {% endif %}
299+ {% if snap.icon_url %}
300+ <div class="two-col">
301+ <img src="{{ snap.icon_url }}"/>
302+ </div>
303+ {% else %}
304+ {% with 0|randint:10|string as rand %}
305+ {% with "img/boards/noboard-"|add:rand|add:".png" as noboard %}
306+ <div class="two-col">
307+ <img src="{% static noboard %}"/>
308+ </div>
309+ {% endwith %}
310+ {% endwith %}
311+ {% endif %}
312+ <div class="two-col no-margin-bottom">
313+ <h4>
314+ {% with snap_name=snap.title|default_if_none:snap.name %}
315+ {{ snap_name|style_snap_name }}
316+ {% endwith %}
317+ </h4>
318+ </div>
319+ </div>
320+ {% endfor %}
321+</div>

Subscribers

People subscribed via source and target branches