def main(): opts, args = parse_args() if len(args) != 1: optparser.error('must give path to shapefile') shapefile = args[0] if not os.path.exists(shapefile): optparser.error('file does not exist') ds = DataSource(shapefile) layer = ds[opts.layer_id] metro = get_metro() metro_name = metro['metro_name'].upper() location_type, _ = LocationType.objects.get_or_create( name='neighborhood', plural_name='neighborhoods', scope=metro_name, slug='neighborhoods', is_browsable=True, is_significant=True, ) importer = LocationImporter(layer, location_type) num_created = importer.save(name_field=opts.name_field, source=opts.source, verbose=opts.verbose) if opts.verbose: print >> sys.stderr, 'Created %s neighborhoods.' % num_created
class ImportBlocksForm(forms.Form): edges = forms.FileField(label='All Lines (tl...edges.zip)', required=True) featnames = forms.FileField(label='Feature Names Relationship (tl...featnames.zip)', required=True) faces = forms.FileField(label='Topological Faces (tl...faces.zip)', required=True) place = forms.FileField(label='Place (Current) (tl..._place.zip)', required=True) city = forms.CharField(max_length=30, help_text="Optional: skip features that don't include this city name", required=False) fix_cities = forms.BooleanField( help_text="Optional: try to override each block's city by finding an overlapping Location that represents a city. Only useful if you've set up multiple_cities=True and set city_location_type in your settings.METRO_LIST *and* have some appropriate Locations of that type already created.", required=False, initial=bool(get_metro().get('multiple_cities', False))) regenerate_intersections = forms.BooleanField( help_text="Regenerate all Intersections and BlockIntersections after loading Blocks. Say No only if you are sure you have more blocks to load from another set of shapefiles; it will run a lot faster. It's always safe to say Yes.", required=False, initial=True) def save(self): if not self.is_valid(): return False import_blocks_from_shapefiles( save_file(self.cleaned_data['edges'], suffix='.zip'), save_file(self.cleaned_data['featnames'], suffix='.zip'), save_file(self.cleaned_data['faces'], suffix='.zip'), save_file(self.cleaned_data['place'], suffix='.zip'), city=self.cleaned_data['city'], fix_cities=self.cleaned_data['fix_cities'], regenerate_intersections=self.cleaned_data['regenerate_intersections'], ) return True
def __init__(self, layer): self.layer = layer metro = get_metro() self.metro_name = metro['metro_name'].upper() self.now = datetime.datetime.now() self.location_type, _ = LocationType.objects.get_or_create( name='neighborhood', plural_name='neighborhoods', scope=self.metro_name, slug='neighborhoods', is_browsable=True, is_significant=True, ) unknown, created = Location.objects.get_or_create( name='Unknown neighborhood', normalized_name='UNKNOWN', slug='unknown', location_type=self.location_type, location=None, centroid=None, display_order=0, city=self.metro_name, source='', area=None, is_public=False) if not created: unknown.creation_date = self.now unknown.last_mod_date = self.now
def __init__(self, layer): self.layer = layer metro = get_metro() self.metro_name = metro['metro_name'].upper() self.now = datetime.datetime.now() self.location_type, _ = LocationType.objects.get_or_create( name = 'neighborhood', plural_name = 'neighborhoods', scope = self.metro_name, slug = 'neighborhoods', is_browsable = True, is_significant = True, ) unknown, created = Location.objects.get_or_create( name = 'Unknown neighborhood', normalized_name = 'UNKNOWN', slug = 'unknown', location_type = self.location_type, location = None, centroid = None, display_order = 0, city = self.metro_name, source = '', area = None, is_public = False ) if not created: unknown.creation_date = self.now unknown.last_mod_date = self.now
def main(): opts, args = parse_args() if len(args) != 2: optparser.error('must supply type slug and path to shapefile') type_slug = args[0] shapefile = args[1] if not os.path.exists(shapefile): optparser.error('file does not exist') ds = DataSource(shapefile) layer = ds[opts.layer_id] metro = get_metro() metro_name = metro['metro_name'].upper() location_type, _ = LocationType.objects.get_or_create( name = opts.type_name, plural_name = opts.type_name_plural, scope = metro_name, slug = type_slug, is_browsable = True, is_significant = True, ) importer = LocationImporter(layer, location_type) num_created = importer.save(name_field=opts.name_field, source=opts.source, verbose=opts.verbose) if opts.verbose: print >> sys.stderr, 'Created %s %s.' % (num_created, location_type.plural_name)
def send_verification_email(email, task): domain = get_metro()['short_name'] + '.' + settings.EB_DOMAIN url = 'http://%s%s' % (domain, verification_url(email, task)) template_name = { CREATE_TASK: 'register', RESET_TASK: 'password_reset' }[task] text_content = render_to_string('accounts/%s_email.txt' % template_name, { 'url': url, 'email': email }) html_content = render_to_string('accounts/%s_email.html' % template_name, { 'url': url, 'email': email }) if settings.DEBUG: print text_content print html_content else: subject = { CREATE_TASK: 'Please confirm account', RESET_TASK: 'Password reset request' }[task] conn = SMTPConnection() # Use default settings. message = EmailMultiAlternatives(subject, text_content, settings.GENERIC_EMAIL_SENDER, [email], connection=conn) message.attach_alternative(html_content, 'text/html') message.send()
class PetitionForm(forms.Form): name = forms.CharField(max_length=100, widget=forms.TextInput(attrs={'size': 30})) location = LocationField(max_length=100, widget=forms.TextInput(attrs={'size': 30})) city = forms.CharField(max_length=30, widget=forms.TextInput(attrs={'size': 30}), initial=get_metro()['city_name']) state = forms.CharField(max_length=2, widget=forms.TextInput(attrs={'size': 2}), initial=get_metro()['state']) email = forms.EmailField(widget=forms.TextInput(attrs={'size': 30})) notes = forms.CharField(required=False, widget=forms.Textarea(attrs={ 'cols': 35, 'rows': 4 }))
def populate_intersections(*args, **kwargs): # On average, there are 2.3 blocks per intersection. So for # example in the case of Chicago, where there are 788,496 blocks, # we'd expect to see approximately 340,000 intersections logging.info("Starting to populate intersections") metro = get_metro() zipcodes = Location.objects.filter(location_type__name__istartswith="zip").exclude(name__startswith='Unknown') def lookup_zipcode(pt): for zipcode in zipcodes: if zipcode.location.contains(pt): return zipcode intersections_seen = {} for i in Intersection.objects.all(): intersections_seen[i.pretty_name] = i.id intersections_seen[i.reverse_pretty_name()] = i.id for bi in BlockIntersection.objects.iterator(): street_name = make_dir_street_name(bi.block) i_street_name = make_dir_street_name(bi.intersecting_block) # This tuple enables us to skip over intersections # we've already seen. Since intersections are # symmetrical---eg., "N. Kimball Ave. & W. Diversey # Ave." == "W. Diversey Ave. & N. Kimball Ave."---we # use both orderings. seen_intersection = (u"%s & %s" % (street_name, i_street_name), u"%s & %s" % (i_street_name, street_name)) if seen_intersection[0] not in intersections_seen and \ seen_intersection[1] not in intersections_seen: if bi.block.left_city != bi.block.right_city: city = metro['city_name'].upper() else: city = bi.block.left_city if bi.block.left_state != bi.block.right_state: state = metro['state'].upper() else: state = bi.block.left_state if (bi.block.left_zip != bi.block.right_zip or \ bi.intersecting_block.left_zip != bi.intersecting_block.right_zip) or \ (bi.block.left_zip != bi.intersecting_block.left_zip): zipcode_obj = lookup_zipcode(bi.location) if zipcode_obj: zipcode = zipcode_obj.name else: zipcode = bi.block.left_zip else: zipcode = bi.block.left_zip intersection = intersection_from_blocks(bi.block, bi.intersecting_block, bi.location, city, state, zipcode) intersection.save() logging.debug("Created intersection %s" % intersection) bi.intersection = intersection bi.save() intersections_seen[seen_intersection[0]] = intersection.id intersections_seen[seen_intersection[1]] = intersection.id else: if not bi.intersection: bi.intersection_id = intersections_seen[seen_intersection[0]] bi.save() logging.debug("Already seen intersection %s" % " / ".join(seen_intersection)) logging.info("Finished populating intersections")
def populate_intersections(*args, **kwargs): # On average, there are 2.3 blocks per intersection. So for # example in the case of Chicago, where there are 788,496 blocks, # we'd expect to see approximately 340,000 intersections logger.info("Starting to populate intersections") metro = get_metro() zipcodes = Location.objects.filter(location_type__name__istartswith="zip").exclude(name__startswith='Unknown') def lookup_zipcode(pt): for zipcode in zipcodes: if zipcode.location.contains(pt): return zipcode intersections_seen = {} for i in Intersection.objects.all(): intersections_seen[i.pretty_name] = i.id intersections_seen[i.reverse_pretty_name()] = i.id for bi in BlockIntersection.objects.iterator(): street_name = make_dir_street_name(bi.block) i_street_name = make_dir_street_name(bi.intersecting_block) # This tuple enables us to skip over intersections # we've already seen. Since intersections are # symmetrical---eg., "N. Kimball Ave. & W. Diversey # Ave." == "W. Diversey Ave. & N. Kimball Ave."---we # use both orderings. seen_intersection = (u"%s & %s" % (street_name, i_street_name), u"%s & %s" % (i_street_name, street_name)) if seen_intersection[0] not in intersections_seen and \ seen_intersection[1] not in intersections_seen: if bi.block.left_city != bi.block.right_city: city = metro['city_name'].upper() else: city = bi.block.left_city if bi.block.left_state != bi.block.right_state: state = metro['state'].upper() else: state = bi.block.left_state if (bi.block.left_zip != bi.block.right_zip or \ bi.intersecting_block.left_zip != bi.intersecting_block.right_zip) or \ (bi.block.left_zip != bi.intersecting_block.left_zip): zipcode_obj = lookup_zipcode(bi.location) if zipcode_obj: zipcode = zipcode_obj.name else: zipcode = bi.block.left_zip else: zipcode = bi.block.left_zip intersection = intersection_from_blocks(bi.block, bi.intersecting_block, bi.location, city, state, zipcode) intersection.save() logging.debug("Created intersection %s" % intersection) bi.intersection = intersection bi.save() intersections_seen[seen_intersection[0]] = intersection.id intersections_seen[seen_intersection[1]] = intersection.id else: if not bi.intersection: bi.intersection_id = intersections_seen[seen_intersection[0]] bi.save() logger.debug("Already seen intersection %s" % " / ".join(seen_intersection)) logger.info("Finished populating intersections")
def tearDown(self): # Restore old log level. from ebpub.metros.allmetros import get_metro metro = get_metro() metro['multiple_cities'] = self.old_multiple metro['city_name'] = self.old_city logger = logging.getLogger('django.request') logger.setLevel(self._previous_level)
def get_place_info_for_request(request, *args, **kwargs): """ A utility function that abstracts getting some commonly used location-related information: a place (Location or Block), its type, a bbox, a list of nearby locations, etc. """ info = dict( bbox=None, nearby_locations=[], location=None, place_type=None, is_block=False, block_radius=None, is_saved=False, pid='', cookies_to_set={}, ) if 'place' in kwargs: info['place'] = place = kwargs['place'] else: info['place'] = place = url_to_place(*args, **kwargs) if isinstance(place, Block): info['is_block'] = True xy_radius, block_radius, cookies_to_set = block_radius_value(request) block_radius = kwargs.get('block_radius') or block_radius nearby, search_buf = get_locations_near_place(place, block_radius) info['nearby_locations'] = nearby info['bbox'] = search_buf.extent saved_place_lookup = {'block_center': place.geom.centroid} info['block_radius'] = block_radius info['cookies_to_set'] = cookies_to_set info['pid'] = make_pid(place, block_radius) info['place_type'] = 'block' else: info['location'] = place info['place_type'] = place.location_type.slug saved_place_lookup = {'location__id': place.id} info['pid'] = make_pid(place) if place.location is None: # No geometry. info['bbox'] = get_metro()['extent'] else: nearby, search_buf = get_locations_near_place(place) info['bbox'] = search_buf.extent info['nearby_locations'] = nearby # Determine whether this is a saved place. if not request.user.is_anonymous(): saved_place_lookup[ 'user_id'] = request.user.id # TODO: request.user.id should not do a DB lookup info['is_saved'] = SavedPlace.objects.filter( **saved_place_lookup).count() return info
def __init__(self, request, context, queryset, *args, **kwargs): NewsitemFilter.__init__(self, request, context, queryset, *args, **kwargs) self.location_object = None args = list(args) if 'block' not in kwargs: # We do this first so we consume the right number of args # before getting to block_radius. try: if get_metro()['multiple_cities']: self.city_slug = args.pop(0) else: self.city_slug = '' self.street_slug = args.pop(0) self.block_range = args.pop(0) except IndexError: raise FilterError( "not enough args, need a street and a block range") try: block_radius = args.pop(0) self.block_radius = radius_from_slug(block_radius) except (TypeError, ValueError): raise FilterError('bad radius %r' % block_radius) except IndexError: self.block_radius = context.get('block_radius') if self.block_radius is None: # Redirect to a URL that includes some radius, either # from a cookie, or the default radius. # TODO: Filters are used in various contexts, but the # redirect URL is tailored only for the schema_filter # view. xy_radius, block_radius, cookies_to_set = block_radius_value( request) radius_param = urllib.quote(',' + radius_slug(block_radius)) radius_url = request.get_full_path() + radius_param raise FilterError('missing radius', url=radius_url) if 'block' in kwargs: # needs block_radius to already be there. self._update_block(kwargs['block']) if self.location_object is not None: block = self.location_object else: m = re.search('^%s$' % constants.BLOCK_URL_REGEX, self.block_range) if not m: raise FilterError('Invalid block URL: %r' % self.block_range) url_to_block_args = m.groups() block = url_to_block(self.city_slug, self.street_slug, *url_to_block_args) self._update_block(block) self._got_args = True
def get_place_info_for_request(request, *args, **kwargs): """ A utility function that abstracts getting some commonly used location-related information: a place (Location or Block), its type, a bbox, a list of nearby locations, etc. """ info = dict(bbox=None, nearby_locations=[], location=None, place_type=None, is_block=False, block_radius=None, is_saved=False, pid='', cookies_to_set={}, ) if 'place' in kwargs: info['place'] = place = kwargs['place'] else: info['place'] = place = url_to_place(*args, **kwargs) if isinstance(place, Block): info['is_block'] = True xy_radius, block_radius, cookies_to_set = block_radius_value(request) block_radius = kwargs.get('block_radius') or block_radius nearby, search_buf = get_locations_near_place(place, block_radius) info['nearby_locations'] = nearby info['bbox'] = search_buf.extent saved_place_lookup = {'block__id': place.id} info['block_radius'] = block_radius info['cookies_to_set'] = cookies_to_set info['pid'] = make_pid(place, block_radius) info['place_type'] = 'block' else: info['location'] = place info['place_type'] = place.location_type.slug saved_place_lookup = {'location__id': place.id} info['pid'] = make_pid(place) if place.location is None: # No geometry. info['bbox'] = get_metro()['extent'] else: nearby, search_buf = get_locations_near_place(place) info['bbox'] = search_buf.extent info['nearby_locations'] = nearby # Determine whether this is a saved place. if not request.user.is_anonymous(): saved_place_lookup['user_id'] = request.user.id # TODO: request.user.id should not do a DB lookup info['is_saved'] = SavedPlace.objects.filter(**saved_place_lookup).count() return info
def location_type(): metro = get_metro() metro_name = metro['metro_name'].upper() location_type, _ = LocationType.objects.get_or_create( name='Neighborhood', plural_name='Neighborhoods', scope=metro_name, slug='neighborhoods', is_browsable=True, is_significant=True, ) return location_type
def __init__(self, layer, location_type, source='UNKNOWN', filter_bounds=False, verbose=False): self.layer = layer metro = get_metro() self.metro_name = metro['metro_name'].upper() self.now = datetime.datetime.now() self.location_type = location_type self.source = source self.filter_bounds = filter_bounds self.verbose = verbose if self.filter_bounds: from ebpub.utils.geodjango import get_default_bounds self.bounds = get_default_bounds()
def location_type(): metro = get_metro() metro_name = metro['metro_name'].upper() location_type, _ = LocationType.objects.get_or_create( name = 'Neighborhood', plural_name = 'Neighborhoods', scope = metro_name, slug = 'neighborhoods', is_browsable = True, is_significant = True, ) return location_type
def street_list(context): crumbs = home(context) crumbs.append((u'Streets', '/streets/')) if get_metro()['multiple_cities']: # XXX UNTESTED city = context.get('city') if city is None: if context.get('place_type') == 'block': city = context['place'].city_object() else: assert False, "context has neither city nor a place from which to get it" crumbs.append((city.name, "/streets/%s/" % city.slug)) return crumbs
def __init__(self, request, context, queryset, *args, **kwargs): NewsitemFilter.__init__(self, request, context, queryset, *args, **kwargs) self.location_object = None args = list(args) if 'block' not in kwargs: # We do this first so we consume the right number of args # before getting to block_radius. try: if get_metro()['multiple_cities']: self.city_slug = args.pop(0) else: self.city_slug = '' self.street_slug = args.pop(0) self.block_range = args.pop(0) except IndexError: raise FilterError("not enough args") try: block_radius = args.pop(0) self.block_radius = radius_from_slug(block_radius) except (TypeError, ValueError): raise FilterError('bad radius %r' % block_radius) except IndexError: self.block_radius = context.get('block_radius') if self.block_radius is None: # Redirect to a URL that includes some radius, either # from a cookie, or the default radius. # TODO: Filters are used in various contexts, but the # redirect URL is tailored only for the schema_filter # view. xy_radius, block_radius, cookies_to_set = block_radius_value(request) radius_url = u'%s,%s/' % (request.path.rstrip('/'), radius_slug(block_radius)) raise FilterError('missing radius', url=radius_url) if 'block' in kwargs: # needs block_radius to already be there. self._update_block(kwargs['block']) m = re.search('^%s$' % constants.BLOCK_URL_REGEX, self.block_range) if not m: raise FilterError('Invalid block URL: %r' % self.block_range) self.url_to_block_args = m.groups() self._got_args = True if self.location_object is not None: block = self.location_object else: block = url_to_block(self.city_slug, self.street_slug, *self.url_to_block_args) self._update_block(block)
def get_object(self, bits): # TODO: This duplicates the logic in the URLconf. Fix Django to allow # for RSS feed URL parsing in the URLconf. # See http://code.djangoproject.com/ticket/4720 if get_metro()['multiple_cities']: street_re = re.compile(r'^([-a-z]{3,40})/([-a-z0-9]{1,64})/%s$' % BLOCK_URL_REGEX) else: street_re = re.compile(r'^()([-a-z0-9]{1,64})/%s$' % BLOCK_URL_REGEX) m = street_re.search('/'.join(bits)) if not m: raise Block.DoesNotExist city_slug, street_slug, from_num, to_num, predir, postdir = m.groups() return url_to_block(city_slug, street_slug, from_num, to_num, predir, postdir)
def get_default_bounds(): """Returns the bounding box of the metro, as a Polygon. >>> import mock >>> metrodict = {'extent': (-10.0, 15.0, -5.0, 20.0)} >>> with mock.patch('ebpub.utils.geodjango.get_metro', lambda: metrodict) as get_metro: ... bounds = get_default_bounds() >>> bounds #doctest: +ELLIPSIS <Polygon object at ...> >>> bounds.extent (-10.0, 15.0, -5.0, 20.0) """ return Polygon.from_bbox(get_metro()['extent'])
def __init__(self, shapefile, layer_id=0): ds = DataSource(shapefile) self.layer = ds[layer_id] metro = get_metro() self.metro_name = metro['metro_name'].upper() self.location_type, _ = LocationType.objects.get_or_create( name = 'ZIP Code', plural_name = 'ZIP Codes', scope = 'U.S.A.', slug = 'zipcodes', is_browsable = True, is_significant = True, )
def setUp(self): # Don't log 404 warnings, we expect a lot of them during these # tests. logger = logging.getLogger('django.request') self._previous_level = logger.getEffectiveLevel() logger.setLevel(logging.ERROR) from ebpub.metros.allmetros import get_metro metro = get_metro() self.old_multiple = metro['multiple_cities'] self.old_city = metro['city_name'] metro['multiple_cities'] = False metro['city_name'] = 'Boston'
def __init__(self, shapefile, layer_id=0): ds = DataSource(shapefile) self.layer = ds[layer_id] metro = get_metro() self.metro_name = metro['metro_name'].upper() self.location_type, _ = LocationType.objects.get_or_create( name='ZIP Code', plural_name='ZIP Codes', scope='U.S.A.', slug='zipcodes', is_browsable=True, is_significant=True, )
def city_list(request): city_type_slug = get_metro()['city_location_type'] cities_with_streets = set([City.from_norm_name(c['city']).slug for c in Street.objects.order_by().distinct().values('city')]) all_cities = [City.from_norm_name(v['slug']) for v in Location.objects.filter(location_type__slug=city_type_slug).values('slug', 'name').order_by('name')] all_cities = [city for city in all_cities if city.slug.strip()] return eb_render(request, 'db/city_list.html', {'all_cities': all_cities, 'cities_with_streets': cities_with_streets, 'bodyclass': 'city-list', })
def __init__(self, request, context, queryset, *args, **kwargs): NewsitemFilter.__init__(self, request, context, queryset, *args, **kwargs) self.location_object = None args = list(args) if "block" not in kwargs: # We do this first so we consume the right number of args # before getting to block_radius. try: if get_metro()["multiple_cities"]: self.city_slug = args.pop(0) else: self.city_slug = "" self.street_slug = args.pop(0) self.block_range = args.pop(0) except IndexError: raise FilterError("not enough args, need a street and a block range") try: block_radius = args.pop(0) self.block_radius = radius_from_slug(block_radius) except (TypeError, ValueError): raise FilterError("bad radius %r" % block_radius) except IndexError: self.block_radius = context.get("block_radius") if self.block_radius is None: # Redirect to a URL that includes some radius, either # from a cookie, or the default radius. # TODO: Filters are used in various contexts, but the # redirect URL is tailored only for the schema_filter # view. xy_radius, block_radius, cookies_to_set = block_radius_value(request) radius_param = urllib.quote("," + radius_slug(block_radius)) radius_url = request.get_full_path() + radius_param raise FilterError("missing radius", url=radius_url) if "block" in kwargs: # needs block_radius to already be there. self._update_block(kwargs["block"]) if self.location_object is not None: block = self.location_object else: m = re.search("^%s$" % constants.BLOCK_URL_REGEX, self.block_range) if not m: raise FilterError("Invalid block URL: %r" % self.block_range) url_to_block_args = m.groups() block = url_to_block(self.city_slug, self.street_slug, *url_to_block_args) self._update_block(block) self._got_args = True
def METRO_NAME(): """Prints the metro_name from get_metro(), titlecase. Example: .. code-block:: html+django <h1>{% METRO_NAME %}</h1> """ name = allmetros.get_metro()["metro_name"] if name[0] != name[0].upper: name = name.title() return name
def get_metro(context): """ Tag that puts get_metro() into the context as METRO Example: .. code-block:: html+django {% get_metro %} <p>Current metro is {{ METRO.city_name }}</p> """ context["METRO"] = allmetros.get_metro() return u""
def get_metro(context): """ Tag that puts get_metro() into the context as METRO Example: .. code-block:: html+django {% get_metro %} <p>Current metro is {{ METRO.city_name }}</p> """ context['METRO'] = allmetros.get_metro() return u''
def METRO_NAME(): """Prints the metro_name from get_metro(), titlecase. Example: .. code-block:: html+django <h1>{% METRO_NAME %}</h1> """ name = allmetros.get_metro()['metro_name'] if name[0] != name[0].upper: name = name.title() return name
def location_type_detail(request, slug): lt = get_object_or_404(LocationType, slug=slug) order_by = get_metro()['multiple_cities'] and ('city', 'display_order') or ('display_order',) loc_list = Location.objects.filter(location_type__id=lt.id, is_public=True).order_by(*order_by) lt_list = [{'location_type': i, 'is_current': i == lt} for i in LocationType.objects.filter(is_significant=True).order_by('plural_name')] context = { 'location_type': lt, 'location_list': loc_list, 'location_type_list': lt_list, 'bodyclass': 'location-type-detail', 'bodyid': slug, } context['breadcrumbs'] = breadcrumbs.location_type_detail(context) return eb_render(request, 'db/location_type_detail.html', context)
def get_city_locations(): """ If we have configured multiple_cities, find all Locations of the city_location_type. Otherwise, empty query set. """ from ebpub.metros.allmetros import get_metro metro = get_metro() if metro['multiple_cities']: cities = Location.objects.filter(location_type__slug=metro['city_location_type']) cities = cities.exclude(location_type__name__startswith='Unknown') return cities else: return Location.objects.filter(id=None)
def get_object(self, bits): # TODO: This duplicates the logic in the URLconf. Fix Django to allow # for RSS feed URL parsing in the URLconf. # See http://code.djangoproject.com/ticket/4720 # XXX That bug is fixed, see http://docs.djangoproject.com/en/1.2/ref/contrib/syndication/#a-complex-example; we can replace the bits arg with a normal list of args from the url config, and ditch the regex. if get_metro()['multiple_cities']: street_re = re.compile(r'^([-a-z]{3,40})/([-a-z0-9]{1,64})/%s$' % BLOCK_URL_REGEX) else: street_re = re.compile(r'^()([-a-z0-9]{1,64})/%s$' % BLOCK_URL_REGEX) m = street_re.search('/'.join(bits)) if not m: raise Block.DoesNotExist city_slug, street_slug, from_num, to_num, predir, postdir = m.groups() return url_to_block(city_slug, street_slug, from_num, to_num, predir, postdir)
def add_location(name, wkt, loc_type, source='UNKNOWN'): geom = fromstr(wkt, srid=4326) name = name.strip().title() loc, created = Location.objects.get_or_create( name=name, slug=slugify(name), normalized_name=normalize(name), location_type=loc_type, location=geom, display_order=0, city=get_metro()['city_name'].upper(), source=source) print '%s %s %s' % (created and 'Created' or 'Found', loc_type.name, name) return loc
def add_location(name, wkt, loc_type, source='UNKNOWN'): geom = fromstr(wkt, srid=4326) loc, created = Location.objects.get_or_create( name=name, slug=slugify(name), normalized_name=normalize(name), location_type=loc_type, location=geom, centroid=geom.centroid, display_order=0, city=get_metro()['city_name'].upper(), source=source ) print '%s %s %s' % (created and 'Created' or 'Found', loc_type.name, name) return loc
def get_or_create_location_type(slug, name, name_plural, verbose): metro = get_metro() metro_name = metro['metro_name'].upper() try: location_type = LocationType.objects.get(slug = slug) logger.info("Location type %s already exists, ignoring type-name and type-name-plural" % slug) except LocationType.DoesNotExist: location_type, _ = LocationType.objects.get_or_create( name = name, plural_name = name_plural, scope = metro_name, slug = slug, is_browsable = True, is_significant = True, ) return location_type
def send_verification_email(email, task): domain = get_metro()['short_name'] + '.' + settings.EB_DOMAIN url = 'http://%s%s' % (domain, verification_url(email, task)) template_name = {CREATE_TASK: 'register', RESET_TASK: 'password_reset'}[task] text_content = render_to_string('accounts/%s_email.txt' % template_name, {'url': url, 'email': email}) html_content = render_to_string('accounts/%s_email.html' % template_name, {'url': url, 'email': email}) if settings.DEBUG: print text_content print html_content else: subject = {CREATE_TASK: 'Please confirm account', RESET_TASK: 'Password reset request'}[task] conn = SMTPConnection() # Use default settings. message = EmailMultiAlternatives(subject, text_content, settings.GENERIC_EMAIL_SENDER, [email], connection=conn) message.attach_alternative(html_content, 'text/html') message.send()
def _update_block(self, block): self.location_object = self.context['place'] = block self.city_slug = block.city # XXX is that a slug? self.street_slug = block.street_slug self.block_range = block.number() + block.dir_url_bit() self.label = 'Area' # Assume we already have self.block_radius. value = '%s block%s around %s' % (self.block_radius, (self.block_radius != '1' and 's' or ''), block.pretty_name) self.short_value = value self.value = value self.url = 'streets=' if get_metro()['multiple_cities']: self.url += self.city_slug + ',' self.url += '%s,%s%s,%s' % (block.street_slug, block.number(), block.dir_url_bit(), radius_slug(self.block_radius)) self.location_name = block.pretty_name
def populate_streets(*args, **kwargs): """ Populates the streets table from the blocks table """ print 'Populating the streets table' cursor = connection.cursor() cursor.execute("TRUNCATE streets") cursor.execute(""" INSERT INTO streets (street, pretty_name, street_slug, suffix, city, state) SELECT DISTINCT street, street_pretty_name, street_slug, suffix, left_city, left_state FROM blocks UNION SELECT DISTINCT street, street_pretty_name, street_slug, suffix, right_city, right_state FROM blocks """) connection._commit() print "Deleting extraneous cities..." metro = get_metro()
def proper_city(block): """ Returns the "proper" city for block. This function is necessary because in the Block model there are two sides of the street, and the city on the left side could differ from the city on the right. This function uses knowledge about metros and cities to return the canonical city for our purposes for a block. Note that if ImproperCity is raised, it implies that there is a mismatch between the block data and our understanding about what should be in there. i.e., neither the left nor right side city is one of our metros or city within a multiple-city metro. """ from ebpub.db.models import Location metro = get_metro() if metro['multiple_cities']: cities = set([ l.name.upper() for l in Location.objects.filter( location_type__slug=metro['city_location_type']).exclude( location_type__name__startswith='Unknown') ]) else: cities = set([metro['city_name'].upper()]) # Determine the block's city, which because of blocks that # border two different municipalities, and because of metros # with multiple cities like NYC and Miami-Dade, means checking # both sides of the block and comparing with known city names. block_city = None if block.left_city != block.right_city: # Note that if both left_city and right_city are valid, then we # return the left_city. if block.left_city in cities: block_city = block.left_city elif block.right_city in cities: block_city = block.right_city elif block.left_city in cities: block_city = block.left_city if block_city is None: raise ImproperCity("Error: Unknown city '%s' from block %s (%s)" % (block.left_city, block.id, block)) return block_city
def handle(self, **options): shapefile = self.download_file() now = datetime.datetime.now() metro_name = get_metro()['metro_name'].upper() # get or create City location type type_data = {'name': 'City', 'plural_name': 'Cities', 'slug': 'cities', 'is_browsable': True, 'is_significant': True, 'scope': metro_name} try: type_ = LocationType.objects.get(slug=type_data['slug']) except LocationType.DoesNotExist: type_ = LocationType.objects.create(**type_data) # start with a fresh list of cities Location.objects.filter(location_type=type_).delete() # build list of cities locations = {} layer = DataSource(shapefile)[0] for feature in layer: name = self.clean_name(feature['Name']) # convert to 4326 geom = feature.geom.transform(4326, True).geos if name not in locations: locations[name] = { 'name': name, 'slug': slugify(name), 'location_type': type_, 'city': metro_name, 'source': 'Columbus County GIS data', 'is_public': True, 'creation_date': now, 'last_mod_date': now, 'display_order': 0, 'normalized_name': normalize(name), 'location': [], } location = locations[name] location['location'].append(geom) # create city locations for name, location in locations.iteritems(): location['location'] = make_multi(location['location']) Location.objects.create(**location) print 'Imported %d locations' % type_.location_set.count()
def populate_streets(*args, **kwargs): """ Populates the streets table from the blocks table """ print 'Populating the streets table' cursor = connection.cursor() cursor.execute("TRUNCATE streets") cursor.execute(""" INSERT INTO streets (street, pretty_name, street_slug, suffix, city, state) SELECT DISTINCT street, street_pretty_name, street_slug, suffix, left_city, left_state FROM blocks UNION SELECT DISTINCT street, street_pretty_name, street_slug, suffix, right_city, right_state FROM blocks """) connection._commit() print "Deleting extraneous cities..." metro = get_metro() cities = [l.name.upper() for l in Location.objects.filter(location_type__slug=metro['city_location_type']).exclude(location_type__name__startswith='Unknown')] Street.objects.exclude(city__in=cities).delete()
def _update_block(self, block): self.location_object = self.context['place'] = block self.city_slug = block.city # XXX is that a slug? self.street_slug = block.street_slug self.block_range = block.number() + block.dir_url_bit() self.label = 'Area' # Assume we already have self.block_radius. value = '%s block%s around %s' % (self.block_radius, (self.block_radius != '1' and 's' or ''), block.pretty_name) self.short_value = value self.value = value self.argname = 'streets' self.query_param_value = [] if get_metro()['multiple_cities']: self.query_param_value.append(self.city_slug) self.query_param_value.extend([block.street_slug, block.number() + block.dir_url_bit(), radius_slug(self.block_radius)]) self.query_param_value = ','.join(self.query_param_value) self.location_name = block.pretty_name self.got_args = True
def get_all_tile_coords(layer, cities=None, levels=(0, 5)): """ A shortcut for getting all the tile coordinates for a layer. Can be optionally constrained by city or a list of cities (slugs). """ if isinstance(layer, basestring): layer = get_eb_layer(layer) if cities is None: cities = METRO_DICT.keys() elif isinstance(cities, basestring): cities = [cities] for slug in cities: bboxes = [] city_ext = transform_extent(get_metro(slug)['extent'], layer.dest_srs) for level in xrange(*levels): bboxes.append(buffer_extent(city_ext, level, units=settings.MAP_UNITS)) for tile_coords in get_tile_coords(layer, levels=levels, bboxes=bboxes): yield tile_coords
def proper_city(block): """ Returns the "proper" city for block, as a string. This function is necessary because in the Block model there are two sides of the street, and the city on the left side could differ from the city on the right. This function uses knowledge about metros and cities to return the canonical city for our purposes for a block. In some blocks, this may return an empty string - eg. in unincorporated areas of rural counties, or when the city simply isn't one we know anything about. """ from ebpub.db.models import get_city_locations metro = get_metro() if metro["multiple_cities"]: cities = set([l.name.upper() for l in get_city_locations()]) else: cities = set([metro["city_name"].upper()]) # Determine the block's city, which because of blocks that # border two different municipalities, and because of metros # with multiple cities like NYC and Miami-Dade, means checking # both sides of the block and comparing with known city names. block_city = u"" if block.left_city != block.right_city: # Note that if both left_city and right_city are valid, then we # return the left_city. if block.left_city in cities: block_city = block.left_city elif block.right_city in cities: block_city = block.right_city elif block.left_city in cities: block_city = block.left_city if not block_city: # We may be in some other area that isn't a city we know about. # That shouldn't prevent us from doing anything useful with this block. block_city = _first_not_false(block.left_city, block.right_city, u"") return block_city
def proper_city(block): """ Returns the "proper" city for block, as a string. This function is necessary because in the Block model there are two sides of the street, and the city on the left side could differ from the city on the right. This function uses knowledge about metros and cities to return the canonical city for our purposes for a block. In some blocks, this may return an empty string - eg. in unincorporated areas of rural counties, or when the city simply isn't one we know anything about. """ from ebpub.db.models import get_city_locations metro = get_metro() if metro['multiple_cities']: cities = set([l.name.upper() for l in get_city_locations()]) else: cities = set([metro['city_name'].upper()]) # Determine the block's city, which because of blocks that # border two different municipalities, and because of metros # with multiple cities like NYC and Miami-Dade, means checking # both sides of the block and comparing with known city names. block_city = u'' if block.left_city != block.right_city: # Note that if both left_city and right_city are valid, then we # return the left_city. if block.left_city in cities: block_city = block.left_city elif block.right_city in cities: block_city = block.right_city elif block.left_city in cities: block_city = block.left_city if not block_city: # We may be in some other area that isn't a city we know about. # That shouldn't prevent us from doing anything useful with this block. block_city = _first_not_false(block.left_city, block.right_city, u'') return block_city
def cover_city(city_slug, radius): """ An iterator that yields a centroid (lng, lat) for a circle buffer with radius given. The total buffers completely cover the city and no buffers that do not intersect with the city boundary are included. Radius is in kilometers. """ def shapefile_path(city): return os.path.normpath( os.path.join(settings.SHAPEFILE_ROOT, city, 'city_4326')) ds = DataSource(shapefile_path(city_slug) + '.shp') city_geom = reduce_layer_geom(ds[0], 'union') city_geom.srid = 4326 city_geom.transform(900913) for (x, y) in cover_region(get_metro(city_slug)['extent'], radius): pt = Point(x, y, srid=4326) pt.transform(900913) buf = pt.buffer(radius) if buf.intersects(city_geom.geos): yield (x, y)
def _update_block(self, block): self.location_object = self.context['place'] = block self.city_slug = block.city # XXX is that a slug? self.street_slug = block.street_slug self.block_range = block.number() + block.dir_url_bit() self.label = 'Area' # Assume we already have self.block_radius. value = '%s block%s around %s' % (self.block_radius, (self.block_radius != '1' and 's' or ''), block.pretty_name) self.short_value = value self.value = value self.argname = 'streets' self.query_param_value = [] if get_metro()['multiple_cities']: self.query_param_value.append(self.city_slug) self.query_param_value.extend([ block.street_slug, block.number() + block.dir_url_bit(), radius_slug(self.block_radius) ]) self.query_param_value = ','.join(self.query_param_value) self.location_name = block.pretty_name self._got_args = True
def city_slug(self): if get_metro()['multiple_cities']: return self.city_object().slug return ''
def state(self): if self.left_state == self.right_state: return self.left_state else: return get_metro()['state']