Merge lp:~dholbach/loco-team-portal/geo-grouping into lp:loco-team-portal

Proposed by Daniel Holbach
Status: Merged
Merged at revision: 213
Proposed branch: lp:~dholbach/loco-team-portal/geo-grouping
Merge into: lp:loco-team-portal
Diff against target: 357 lines (+172/-28)
10 files modified
loco_directory/common/context_processors.py (+1/-2)
loco_directory/common/utils.py (+36/-0)
loco_directory/events/forms.py (+0/-2)
loco_directory/teams/management/commands/init-ld.py (+0/-1)
loco_directory/teams/models.py (+35/-1)
loco_directory/teams/views.py (+7/-3)
loco_directory/templates/teams/team_list.html (+37/-7)
loco_directory/templates/venues/venue_list.html (+45/-10)
loco_directory/venues/models.py (+2/-0)
loco_directory/venues/views.py (+9/-2)
To merge this branch: bzr merge lp:~dholbach/loco-team-portal/geo-grouping
Reviewer Review Type Date Requested Status
Michael Hall Pending
Review via email: mp+31534@code.launchpad.net

This proposal supersedes a proposal from 2010-07-29.

To post a comment you must log in.
Revision history for this message
Michael Hall (mhall119) wrote : Posted in a previous version of this proposal

The {% cycle 'col_left' 'col_right' %} doesn't work quite right with nested loops, as it doesn't get reset each time the inner loop is restarted. Thus if one list ends on 'col_left', the next list will start on 'col_right', which isn't correct.

Also, with probably 90% or more of loco teams being the only team in their country, does it make sense to break apart the team list by country?

Revision history for this message
Michael Hall (mhall119) wrote : Posted in a previous version of this proposal

I proposed a merge your branch with fixes/changes

review: Needs Fixing
Revision history for this message
Daniel Holbach (dholbach) wrote :

<mhall119> dholbach: geo-grouping looks good to me

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'loco_directory/common/context_processors.py'
2--- loco_directory/common/context_processors.py 2010-06-17 19:11:30 +0000
3+++ loco_directory/common/context_processors.py 2010-08-02 12:47:40 +0000
4@@ -31,5 +31,4 @@
5
6 def url_base(request):
7 url = request.get_full_path().split('/')
8- return {'url_base': url[1]}
9-
10\ No newline at end of file
11+ return {'url_base': url[1]}
12
13=== modified file 'loco_directory/common/utils.py'
14--- loco_directory/common/utils.py 2010-06-17 01:38:28 +0000
15+++ loco_directory/common/utils.py 2010-08-02 12:47:40 +0000
16@@ -1,5 +1,14 @@
17 import email
18 import os
19+from copy import deepcopy
20+
21+def flat_list(some_list):
22+ """
23+ >>> reduce(lambda a,b: a.extend(b) or a, [[2,3],[6],[66,34]])
24+ [2, 3, 6, 66, 34]
25+ """
26+ return reduce(lambda a,b: a.extend(b) or a, some_list)
27+
28
29 def redirect(to, *args, **kwargs):
30 from distutils.version import LooseVersion as V
31@@ -33,3 +42,30 @@
32 pass
33
34 return "version %s (rev %s)" % (version, bzr_revno)
35+
36+class simple_iterator(object):
37+
38+ def __init__(self, *args):
39+ self.values = []
40+ self.index = -1
41+ if len(args) == 1 and isinstance(args[0], (list, tuple, set)):
42+ self.values.extend(deepcopy(args[0]))
43+ else:
44+ self.values.extend(deepcopy(args))
45+
46+ def get_next_index(self):
47+ if self.index + 1 >= len(self.values):
48+ self.index = 0
49+ else:
50+ self.index = self.index + 1
51+ return self.index
52+ next_index = property(get_next_index)
53+
54+ def get_next(self):
55+ return self.values[self.next_index]
56+ next = property(get_next)
57+
58+ def reset(self):
59+ self.index = -1
60+ return ''
61+
62
63=== modified file 'loco_directory/events/forms.py'
64--- loco_directory/events/forms.py 2010-06-19 21:35:39 +0000
65+++ loco_directory/events/forms.py 2010-08-02 12:47:40 +0000
66@@ -6,8 +6,6 @@
67 from models import BaseEvent, GlobalEvent, TeamEvent, Attendee, TeamEventComment
68 from venues.models import Venue
69
70-import re
71-
72 def validate_tag(tag):
73 if tag.startswith('#'):
74 tag = tag[1:]
75
76=== modified file 'loco_directory/teams/management/commands/init-ld.py'
77--- loco_directory/teams/management/commands/init-ld.py 2010-07-01 06:27:09 +0000
78+++ loco_directory/teams/management/commands/init-ld.py 2010-08-02 12:47:40 +0000
79@@ -3,7 +3,6 @@
80 from django.core.management.base import NoArgsCommand
81 from django.contrib.auth.models import Group
82
83-from teams import models
84 import settings
85
86 import subprocess
87
88=== modified file 'loco_directory/teams/models.py'
89--- loco_directory/teams/models.py 2010-07-15 14:28:03 +0000
90+++ loco_directory/teams/models.py 2010-08-02 12:47:40 +0000
91@@ -1,6 +1,8 @@
92 from django.db import models
93 from django.utils.translation import ugettext_lazy as _
94
95+from common.utils import flat_list
96+
97 class Language(models.Model):
98 class Meta:
99 ordering = ('name',)
100@@ -24,6 +26,18 @@
101 def __unicode__(self):
102 return u'%s' % (self.name)
103
104+ @property
105+ def related_countries(self):
106+ return self.country_set.all()
107+
108+ @property
109+ def related_venues(self):
110+ return flat_list([list(a.related_venues) for a in self.related_countries])
111+
112+ @property
113+ def related_teams(self):
114+ return flat_list([list(a.related_teams) for a in self.related_countries])
115+
116 class Country(models.Model):
117 name = models.TextField(_("Name"), max_length=100)
118 continents = models.ManyToManyField(Continent)
119@@ -31,6 +45,25 @@
120 def __unicode__(self):
121 return u'%s' % (self.name)
122
123+ @property
124+ def related_teams(self):
125+ return self.team_set.all()
126+
127+ @property
128+ def related_venues(self):
129+ return self.venue_set.all()
130+
131+def countries_without_continent():
132+ return Country.objects.filter(continents__isnull=True)
133+
134+def countries_without_continent_have_venues():
135+ list_of_venues = [list(a.related_venues) for a in countries_without_continent()]
136+ return len(flat_list(list_of_venues))>0
137+
138+def countries_without_continent_have_teams():
139+ list_of_teams = [list(a.related_teams) for a in countries_without_continent()]
140+ return len(flat_list(list_of_teams))>0
141+
142 class Team(models.Model):
143 lp_name = models.SlugField(_("Launchpad Team ID"), max_length=40, null=True)
144 name = models.CharField(_("Team Name"), max_length=80, null=True)
145@@ -69,4 +102,5 @@
146 def get_absolute_url(self):
147 return ('team-detail', [str(self.lp_name)])
148
149-
150+def teams_without_country():
151+ return Team.objects.filter(countries__isnull=True)
152
153=== modified file 'loco_directory/teams/views.py'
154--- loco_directory/teams/views.py 2010-07-29 15:41:01 +0000
155+++ loco_directory/teams/views.py 2010-08-02 12:47:40 +0000
156@@ -1,7 +1,6 @@
157 # -*- coding: utf-8 -*-
158
159 from django.template import RequestContext
160-from django.utils.translation import ugettext_lazy as _
161 from django.utils.translation import ugettext
162 from django.core import serializers
163
164@@ -13,10 +12,10 @@
165
166 from django import http
167
168-from common.utils import redirect
169+from common.utils import redirect, simple_iterator
170 from common import launchpad
171
172-from models import Team
173+from teams.models import Continent, Team, countries_without_continent, countries_without_continent_have_teams, teams_without_country
174
175 import forms
176
177@@ -54,6 +53,11 @@
178 context = {
179 'team_list': team_list,
180 'form': form,
181+ 'continents': Continent.objects.all().order_by('name'),
182+ 'countries_without_continent': countries_without_continent().order_by('name'),
183+ 'countries_without_continent_have_teams': countries_without_continent_have_teams(),
184+ 'teams_without_country': teams_without_country().order_by('name'),
185+ 'colcycle' : simple_iterator('col_left', 'col_right'),
186 }
187 return render_to_response('teams/team_list.html', context,
188 RequestContext(request))
189
190=== modified file 'loco_directory/templates/teams/team_list.html'
191--- loco_directory/templates/teams/team_list.html 2010-07-15 07:56:44 +0000
192+++ loco_directory/templates/teams/team_list.html 2010-08-02 12:47:40 +0000
193@@ -20,13 +20,43 @@
194 {% block content %}
195 <article id="main-content" class="main-content">
196 {% if team_list %}
197-<ul>
198-{% for team in team_list %}
199-<li title="{% if team.approved %}{% blocktrans with team.name as teamname %}{{ teamname }} approved{% endblocktrans %}{% else %}{% blocktrans with team.name as teamname %}{{ teamname }} not approved{% endblocktrans %}{% endif %}" class="{% if team.approved %}approved{% else %}unapproved{% endif %} {% cycle 'col_left' 'col_right' %}"><a href="{{ team.get_absolute_url }}">{{ team.name }}</a></li>
200-{% endfor %}
201-</ul>
202-<br class="clear" />
203+ {% for continent in continents %}{% if continent.related_teams %}
204+ <h2>{{continent.name}}</h2>
205+ <ul>
206+ {{colcycle.reset}}
207+ {% for team in continent.related_teams %}
208+ <li title="{% if team.approved %}{% blocktrans with team.name as teamname %}{{ teamname }} approved{% endblocktrans %}{% else %}{% blocktrans with team.name as teamname %}{{ teamname }} not approved{% endblocktrans %}{% endif %}" class="{% if team.approved %}approved{% else %}unapproved{% endif %} {{colcycle.next}}"><a href="{{ team.get_absolute_url }}">{{ team.name }}</a></li>
209+ {% endfor %}
210+ </ul>
211+ <br class="clear" />
212+ {% endif %}{% endfor %}
213+
214+ {% if countries_without_continent_have_teams %}
215+ <h2>{% trans "Countries without continent" %}</h2>
216+ {% for country in countries_without_continent %}{% if country.related_teams %}
217+ <h3>{{country.name}}</h3>
218+ <ul>
219+ {{colcycle.reset}}
220+ {% for team in country.related_teams %}
221+ <li title="{% if team.approved %}{% blocktrans with team.name as teamname %}{{ teamname }} approved{% endblocktrans %}{% else %}{% blocktrans with team.name as teamname %}{{ teamname }} not approved{% endblocktrans %}{% endif %}" class="{% if team.approved %}approved{% else %}unapproved{% endif %} {{colcycle.next}}"><a href="{{ team.get_absolute_url }}">{{ team.name }}</a></li>
222+ {% endfor %}
223+ </ul>
224+ <br class="clear" />
225+ {% endif %}{% endfor %}
226+ {% endif %}
227+
228+ {% if teams_without_country %}
229+ <h2>{% trans "Teams without country" %}</h2>
230+ <ul>
231+ {{colcycle.reset}}
232+ {% for team in teams_without_country %}
233+ <li title="{% if team.approved %}{% blocktrans with team.name as teamname %}{{ teamname }} approved{% endblocktrans %}{% else %}{% blocktrans with team.name as teamname %}{{ teamname }} not approved{% endblocktrans %}{% endif %}" class="{% if team.approved %}approved{% else %}unapproved{% endif %} {{colcycle.next}}"><a href="{{ team.get_absolute_url }}">{{ team.name }}</a></li>
234+ {% endfor %}
235+ </ul>
236+ <br class="clear" />
237+ {% endif %}
238+
239+{% endif %}
240 </article>
241-{% endif %}
242
243 {% endblock %}
244
245=== modified file 'loco_directory/templates/venues/venue_list.html'
246--- loco_directory/templates/venues/venue_list.html 2010-07-30 23:08:36 +0000
247+++ loco_directory/templates/venues/venue_list.html 2010-08-02 12:47:40 +0000
248@@ -17,23 +17,58 @@
249 {% endblock %}
250
251 {% block content %}
252-<article class="main-content">
253+<article id="main-content" class="main-content">
254
255 <h2>{% trans "Ubuntu LoCo Event Venues" %}</h2>
256
257 {% if venue_list %}
258-<p>{% trans "Select a Venue below to see more information about it:" %}</p>
259-
260-{% regroup venue_list by country as venue_country_list %}
261-{% for country in venue_country_list %}
262- <h3>{{ country.grouper }}</h3>
263+ <p>{% trans "Select a Venue below to see more information about it:" %}</p>
264+
265+ {% for continent in continents %}
266+ {% if continent.related_venues %}
267+ <h2>{{continent.name}}</h2>
268+ {% for country in continent.related_countries %}
269+ {% if country.related_venues %}
270+ <h3>{{country.name}}</h3>
271+ <ul>
272+ {{colcycle.reset}}
273+ {% for venue in country.related_venues %}
274+ <li class="{{colcycle.next}}"><a title="{% trans "show venue details" %}" href="{{ venue.get_absolute_url }}">{{ venue.name }}{% if venue.city %}, {{ venue.city }}{% endif %}</a></li>
275+ {% endfor %}
276+ </ul>
277+ <br style="clear:left;">
278+ {% endif %}
279+ {% endfor %}
280+ {% endif %}
281+ {% endfor %}
282+
283+ {% if countries_without_continent_have_venues %}
284+ <h2>{% trans "Countries without Continent" %}</h3>
285+ {% for country in countries_without_continent %}
286+ {% if country.related_venues %}
287+ <h3>{{country.name}}</h3>
288+ <ul>
289+ {{colcycle.reset}}
290+ {% for venue in country.related_venues %}
291+ <li class="{{colcycle.next}}"><a title="{% trans "show venue details" %}" href="{{ venue.get_absolute_url }}">{{ venue.name }}{% if venue.city %}, {{ venue.city }}{% endif %}</a></li>
292+ {% endfor %}
293+ </ul>
294+ <br style="clear:left;">
295+ {% endif %}
296+ {% endfor %}
297+ {% endif %}
298+
299+ {% if venues_without_country %}
300+ <h2>{% trans "Venues without Country" %}</h2>
301 <ul>
302- {% for venue in country.list %}
303- <li class="{% if forloop.counter|divisibleby:2 %}col_right{% else %}col_left{% endif %}"><a title="{% trans "show venue details" %}" href="{{ venue.get_absolute_url }}">{{ venue.name }}{% if venue.city %}, {{ venue.city }}{% endif %}</a></li>
304- {% endfor %}
305+ {{colcycle.reset}}
306+ {% for venue in venues_without_country %}
307+ <li class="{{colcycle.next}}"><a title="{% trans "show venue details" %}" href="{{ venue.get_absolute_url }}">{{ venue.name }}{% if venue.city %}, {{ venue.city }}{% endif %}</a></li>
308+ {% endfor %}
309 </ul>
310 <br style="clear:left;">
311-{% endfor %}
312+ {% endif %}
313+
314
315 {% else %}
316 <p>{% trans "There are currently no LoCo Venues :(" %}</p>
317
318=== modified file 'loco_directory/venues/models.py'
319--- loco_directory/venues/models.py 2010-06-09 01:36:18 +0000
320+++ loco_directory/venues/models.py 2010-08-02 12:47:40 +0000
321@@ -40,3 +40,5 @@
322 """ get the absolute url for the venue """
323 return ('venue-detail', [self.id])
324
325+def venues_without_country():
326+ return Venue.objects.filter(country__isnull=True)
327
328=== modified file 'loco_directory/venues/views.py'
329--- loco_directory/venues/views.py 2010-06-19 20:20:12 +0000
330+++ loco_directory/venues/views.py 2010-08-02 12:47:40 +0000
331@@ -7,10 +7,11 @@
332 from django.utils.translation import ugettext as _
333 from django.db.models import Q
334
335-from models import Venue
336+from teams.models import Continent, countries_without_continent, countries_without_continent_have_venues
337+from models import Venue, venues_without_country
338 from forms import VenueForm, VenueSearchForm
339
340-
341+from common.utils import simple_iterator
342
343 def venue_list(request):
344 """
345@@ -27,6 +28,12 @@
346 context = {
347 'form': form,
348 'venue_list': venue_list,
349+ 'continents': Continent.objects.all().order_by('name'),
350+ 'countries_without_continent': countries_without_continent().order_by('name'),
351+ 'countries_without_continent_have_venues': countries_without_continent_have_venues(),
352+ 'venues_without_country': venues_without_country().order_by('name'),
353+ 'colcycle' : simple_iterator('col_left', 'col_right'),
354+
355 }
356 return render_to_response('venues/venue_list.html', context,
357 RequestContext(request))

Subscribers

People subscribed via source and target branches