-
-
Save tdfischer/0cc0fb0f986b0a81becd0ba526c9203b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/assets/js/components/OrganizerDashboard.js b/assets/js/components/OrganizerDashboard.js | |
index 6b018aa..f3caca0 100644 | |
--- a/assets/js/components/OrganizerDashboard.js | |
+++ b/assets/js/components/OrganizerDashboard.js | |
@@ -8,10 +8,13 @@ import Divider from '@material-ui/core/Divider' | |
import { getCurrentUser } from '../selectors/auth' | |
const People = new Model('people') | |
+const TurfMembership = new Model('turf_memberships') | |
class OrganizerDashboardBase extends React.Component { | |
componentDidMount() { | |
- this.props.people.fetchIfNeeded(this.props.currentUser.email) | |
+ this.props.people.fetchIfNeeded(this.props.currentUser.email).then(() => { | |
+ return this.props.turfMemberships.fetchAll({turf__id: _.get(this.props.currentPerson, 'turf_memberships.0.turf_id', 2)}) | |
+ }) | |
} | |
render() { | |
@@ -21,10 +24,17 @@ class OrganizerDashboardBase extends React.Component { | |
}) | |
console.log(this.props.currentPerson, metadata) | |
const name = _.get(this.props.currentPerson, 'name', '') | |
+ const neighbors = ( | |
+ <ul> | |
+ {_.map(this.props.neighbors, n => <li>{n.person.name}</li>)} | |
+ </ul> | |
+ ) | |
return ( | |
<div> | |
<Typography variant="title">{name}</Typography> | |
<Typography variant="subheading">{this.props.currentUser.email}</Typography> | |
+ <Typography variant="title">Your Neighbors in {_.get(this.props.currentPerson, 'turf_memberships.0.name'}</Typography> | |
+ {neighbors} | |
<Divider /> | |
<Typography variant="title">Raw data</Typography> | |
{metadata} | |
@@ -36,15 +46,18 @@ class OrganizerDashboardBase extends React.Component { | |
const mapStateToProps = state => { | |
const currentUser = getCurrentUser(state) | |
const currentPerson = People.select(state).filterBy('email', currentUser.email).first() | |
+ const neighbors = TurfMembership.select(state).filterBy('turf_id', 2).slice | |
return { | |
currentUser, | |
- currentPerson | |
+ currentPerson, | |
+ neighbors | |
} | |
} | |
const mapDispatchToProps = dispatch => { | |
return { | |
- people: People.bindActionCreators(dispatch) | |
+ people: People.bindActionCreators(dispatch), | |
+ turfMemberships: TurfMembership.bindActionCreators(dispatch) | |
} | |
} | |
diff --git a/crm/api_views.py b/crm/api_views.py | |
index 3ff656c..98affc5 100644 | |
--- a/crm/api_views.py | |
+++ b/crm/api_views.py | |
@@ -167,8 +167,19 @@ class CityViewSet(IntrospectiveViewSet): | |
serializer = self.get_serializer(results, many=True) | |
return Response(serializer.data) | |
+class TurfViewSet(IntrospectiveViewSet): | |
+ permission_classes = (IsAuthenticated,) | |
+ queryset = models.Turf.objects.all() | |
+ serializer_class = serializers.TurfSerializer | |
+ | |
+class TurfMembershipViewSet(IntrospectiveViewSet): | |
+ permission_classes = (IsAuthenticated,) | |
+ queryset = models.TurfMembership.objects.all() | |
+ serializer_class = serializers.TurfMembershipSerializer | |
views = { | |
+ 'turfs': TurfViewSet, | |
+ 'turf_memberships': TurfMembershipViewSet, | |
'users': UserViewSet, | |
'people': PersonViewSet, | |
'cities': CityViewSet, | |
diff --git a/crm/management/commands/update_geocache.py b/crm/management/commands/update_geocache.py | |
index 5bd602b..7c3918e 100644 | |
--- a/crm/management/commands/update_geocache.py | |
+++ b/crm/management/commands/update_geocache.py | |
@@ -1,9 +1,10 @@ | |
from django.core.management.base import BaseCommand, CommandError | |
from geopy.geocoders import GoogleV3, Nominatim | |
-from geopy.exc import GeocoderQueryError | |
+from geopy.exc import GeocoderQueryError, GeocoderTimedOut | |
from django.core.cache import caches | |
-from crm.models import Person | |
+from crm.models import Person, Turf, TurfMembership | |
from django.conf import settings | |
+from address.models import Country, State, Locality | |
geocache = caches['default'] | |
@@ -22,6 +23,8 @@ class Command(BaseCommand): | |
geocoded = None | |
try: | |
geocoded = geolocator.geocode(currentAddr, exactly_one=True) | |
+ except GeocoderTimedOut: | |
+ pass | |
except GeocoderQueryError: | |
pass | |
if geocoded is not None: | |
@@ -40,7 +43,26 @@ class Command(BaseCommand): | |
'administrative_area_level_1': values.get('administrative_area_level_1', None), | |
'country': values.get('country', None), | |
} | |
- person.neighborhood = values.get('neighborhood', None) | |
+ if values.get('neighborhood') is not None: | |
+ country, newCountry = Country.objects.get_or_create(name=values.get('country')) | |
+ state, newState = State.objects.get_or_create(name=values.get('administrative_area_level_1'), | |
+ country=country) | |
+ city, newCity = Locality.objects.get_or_create(name=values.get('locality'), | |
+ state=state) | |
+ neighborhoodTurf, newNeighborhood = Turf.objects.get_or_create(name=values.get('neighborhood'), | |
+ locality=city) | |
+ neighborhoodMembership, joinedNeighborhood = TurfMembership.objects.get_or_create(turf=neighborhoodTurf, | |
+ person=person) | |
+ if newCountry: | |
+ print "New country:", country.name | |
+ if newState: | |
+ print "New state:", state.name | |
+ if newCity: | |
+ print "New city:", city.name | |
+ if newNeighborhood: | |
+ print "New neighborhood:", neighborhoodTurf.name | |
+ if joinedNeighborhood: | |
+ print person, "joined neighborhood:", neighborhoodTurf.name | |
geocache.set('geocache:' + currentAddr, {'longitude': longitude, | |
'latitude': latitude}) | |
else: | |
diff --git a/crm/models.py b/crm/models.py | |
index 8b219a8..cc4a1e3 100644 | |
--- a/crm/models.py | |
+++ b/crm/models.py | |
@@ -2,9 +2,9 @@ | |
from __future__ import unicode_literals | |
from django.db import models | |
-from django.db.models import Count, Subquery, OuterRef | |
+from django.utils import timezone | |
from django.urls import reverse | |
-from address.models import AddressField, Address | |
+from address.models import AddressField, Address, Locality | |
from enumfields import EnumIntegerField, Enum | |
from taggit.managers import TaggableManager | |
import inspect | |
@@ -13,7 +13,6 @@ class Person(models.Model): | |
name = models.CharField(max_length=200) | |
email = models.CharField(max_length=200) | |
address = AddressField(blank=True) | |
- neighborhood = models.CharField(max_length=200, null=True, blank=False) | |
created = models.DateTimeField(auto_now_add=True) | |
lat = models.FloatField() | |
lng = models.FloatField() | |
@@ -30,3 +29,21 @@ class Person(models.Model): | |
if len(ret) == 0: | |
return self.email | |
return ret | |
+ | |
+class Turf(models.Model): | |
+ name = models.CharField(max_length=200) | |
+ locality = models.ForeignKey(Locality) | |
+ | |
+ def __unicode__(self): | |
+ return "%s, %s"%(self.name, self.locality) | |
+ | |
+class TurfMembership(models.Model): | |
+ person = models.ForeignKey(Person, related_name='turf_memberships') | |
+ turf = models.ForeignKey(Turf, related_name='members') | |
+ joined_on = models.DateField() | |
+ is_captain = models.BooleanField(default=False) | |
+ | |
+ def save(self, *args, **kwargs): | |
+ if not self.id: | |
+ self.joined_on = timezone.now() | |
+ return super(TurfMembership, self).save(*args, **kwargs) | |
diff --git a/crm/serializers.py b/crm/serializers.py | |
index 1627562..fba6dfc 100644 | |
--- a/crm/serializers.py | |
+++ b/crm/serializers.py | |
@@ -28,23 +28,48 @@ class AddressSerializer(serializers.ModelSerializer): | |
class GeoField(serializers.Field): | |
def to_representation(self, obj): | |
- return {'lat': obj.lat, 'lng': obj.lng, | |
- 'neighborhood': obj.neighborhood} | |
+ return {'lat': obj.lat, 'lng': obj.lng} | |
def get_attribute(self, obj): | |
return obj | |
+class NonRecursiveTurfMembershipSerializer(serializers.HyperlinkedModelSerializer): | |
+ name = serializers.CharField(source='turf.name', read_only=True) | |
+ turf_id = serializers.IntegerField(source='turf.id', read_only=True) | |
+ turf = serializers.HyperlinkedRelatedField(read_only=True, | |
+ view_name='turf-detail') | |
+ | |
+ class Meta: | |
+ model = models.TurfMembership | |
+ fields = ('is_captain', 'joined_on', 'name', 'turf', 'turf_id') | |
+ | |
class PersonSerializer(TaggitSerializer, serializers.HyperlinkedModelSerializer): | |
tags = TagListSerializerField() | |
geo = GeoField() | |
+ turf_memberships = NonRecursiveTurfMembershipSerializer(many=True) | |
class Meta: | |
model = models.Person | |
fields = ('name', 'id', 'email', 'created', 'url', 'tags', | |
- 'geo') | |
+ 'geo', 'turf_memberships') | |
lookup_field = 'email' | |
extra_kwargs = { | |
'url': {'lookup_field': 'email'}, | |
'id': {'source': 'email'} | |
} | |
+ | |
+class TurfMembershipSerializer(serializers.HyperlinkedModelSerializer): | |
+ person = PersonSerializer() | |
+ turf_id = serializers.IntegerField(source='turf.id', read_only=True) | |
+ | |
+ class Meta: | |
+ model = models.TurfMembership | |
+ fields = ('is_captain', 'joined_on', 'person', 'turf_id') | |
+ | |
+class TurfSerializer(serializers.HyperlinkedModelSerializer): | |
+ members = TurfMembershipSerializer(many=True) | |
+ | |
+ class Meta: | |
+ model = models.Turf | |
+ fields = ('name', 'members', 'id', 'url') | |
diff --git a/organizer/settings.py b/organizer/settings.py | |
index 4276612..c010928 100644 | |
--- a/organizer/settings.py | |
+++ b/organizer/settings.py | |
@@ -54,6 +54,7 @@ INSTALLED_APPS = [ | |
'taggit', | |
'taggit_serializer', | |
'crm', | |
+ 'onboarding' | |
] | |
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment