def initial_context(self, request, scheme, value): context = super(EntityDetailView, self).initial_context(request) entity = get_entity(scheme, value) associations = [] if hasattr(self.conf, 'associations'): for association in self.conf.associations: id_type, id, associated_entities = association try: if id in entity.identifiers[id_type]: associations += [{'type': type, 'entities': [get_entity(ns, value) for ns, value in es]} for type, es in associated_entities] except (KeyError, Http404): pass for entity_group in entity.groups.all(): group_entities = filter(lambda e: e != entity, Entity.objects.filter(groups=entity_group)) if len(group_entities) > 0: associations.append({ 'type': entity_group.title, 'entities': group_entities, }) board = request.GET.get('board', 'departures') if board != 'departures': board = 'arrivals' context.update({ 'entity': entity, 'train_station': entity, # This allows the ldb metadata to be portable 'board': board, 'entity_types': entity.all_types.all(), 'associations': associations, }) return context
def initial_context(self, request, scheme, value, year, month, day): context = super(TimetableView, self).initial_context(request) context['entity'] = get_entity(scheme, value) if year and month and day: try: context['date'] = date(int(year), int(month), int(day)) except ValueError: raise Http404() else: context['date'] = date.today() if context['entity'].scheduledstop_set.all().count() == 0: # 404 on entities which don't have timetables raise Http404() services = context['entity'].scheduledstop_set.filter( journey__runs_from__lte=context['date'], journey__runs_until__gte=context['date'] ).exclude(activity__in=('D','N','F')).order_by('std') context['timetable'] = filter(lambda s: s.journey.runs_on(context['date']), services) context['title'] = _('Timetable for %(title)s on %(date)s') % { 'title': context['entity'].title, 'date': djangodate(context['date']) } return context
def initial_context(self, request, slug, entities): context = super(CreateView, self).initial_context(request) try: tour_type = self.conf.types[slug] except KeyError: raise Http404() else: tour_type['slug'] = slug context.update({ 'tour_type': tour_type, 'entities': [], 'attractions': dict( (et, sorted(et.entities_completion.filter(location__isnull=False), key=attrgetter('title'))) for et in EntityType.objects.filter( slug__in=tour_type['attraction_types'])), 'all_pois': sorted(Entity.objects.filter( all_types_completion__slug__in=tour_type['attraction_types']), key=attrgetter('title')) }) for entity in entities.split('/'): try: scheme, value = entity.split(':') except ValueError: continue context['entities'].append(get_entity(scheme, value)) return context
def handle_POST(self, request, context, scheme, value): entity = context['entity'] = get_entity(scheme, value) if entity.source.module_name != 'molly.providers.apps.maps.osm': raise Http404 form = UpdateOSMForm(request.POST) if form.is_valid(): new_metadata = copy.deepcopy(entity.metadata['osm']) for k in ('name', 'operator', 'phone', 'opening_hours', 'url', 'cuisine', 'food', 'food__hours', 'atm', 'collection_times', 'ref', 'capacity'): tag_name = k.replace('__', ':') if tag_name in new_metadata and not form.cleaned_data[k]: del new_metadata['osm']['tags'][tag_name] elif form.cleaned_data[k]: new_metadata['tags'][tag_name] = form.cleaned_data[k] new_metadata['attrs']['version'] = str(int(new_metadata['attrs']['version'])+1) osm_update = OSMUpdate( contributor_name = form.cleaned_data['contributor_name'], contributor_email = form.cleaned_data['contributor_email'], contributor_attribute = form.cleaned_data['contributor_attribute'], entity = entity, old = simplejson.dumps(entity.metadata), new = simplejson.dumps(new_metadata), notes = form.cleaned_data['notes'], ) osm_update.save() return self.redirect( reverse('places:entity-update', args=[scheme, value]) + '?submitted=true', request) else: context['form'] = form return self.render(request, context, 'places/update_osm')
def initial_context(self, request): context = super(RailView, self).initial_context(request) if context['train_station']: if getattr(self.conf, 'train_station_nearest', False) \ and context['location']: et = EntityType.objects.get(slug='rail-station') entity = et.entities_completion.filter(location__isnull=False) entity = entity.distance(context['location']).order_by('distance')[0] else: scheme, value = self.conf.train_station.split(':') entity = get_entity(scheme, value) context['entity'] = entity else: raise Http404() places_conf = app_by_application_name('molly.apps.places') attributions = [provider._ATTRIBUTION for provider in places_conf.providers if hasattr(provider, '_ATTRIBUTION')] context['attributions'] = attributions context['board'] = request.GET.get('board', 'departures') self.augment_metadata([entity], board=context['board']) return context
def _get_entity(self, stop_code, stop_name, source, entity_type): """Finds a bus stop entity or creates one if it cannot be found. If multiple entities are found we clean them up. """ scheme = 'naptan' try: entity = get_entity(scheme, stop_code) except: try: entity = Entity.objects.get(_identifiers__scheme=scheme, _identifiers__value=stop_code) logger.debug("Found Entity: %s" % entity) except Entity.DoesNotExist: logger.debug("Entity does not exist: %s-%s" % (stop_code, stop_name)) entity = Entity() except Entity.MultipleObjectsReturned: logger.warning("Multiple Entities found for : %s-%s" % (stop_code, stop_name)) Entity.objects.filter(_identifiers__scheme=scheme, _identifiers__value=stop_code).delete() entity = Entity() entity.primary_type = entity_type entity.source = source identifiers = {scheme: stop_code} set_name_in_language(entity, 'en', title=stop_name) entity.all_types = (entity_type,) entity.save(identifiers=identifiers) return entity
def breadcrumb(self, request, context, scheme, value): entity = get_entity(scheme, value) return Breadcrumb( 'places', lazy_parent('entity', scheme=scheme, value=value), _('Directions to %s') % context['entity'].title, lazy_reverse('entity-directions', args=[scheme, value]), )
def arrival_point_location(self, first_stop, arrival_point): """ Given an arrival point (which may be a park and ride, in which case directions using public transport are given), figure out directions to the first location """ sv, p_and_r, routes = self.conf.arrival_points[int(arrival_point)] entity = get_entity(*sv.split(':')) if p_and_r: # Get closest bus stop to first stop on route closest_stops = Entity.objects.filter( stoponroute__route__service_id__in=routes, ).distance(first_stop.location).order_by('distance') # Now, check that this stop comes *after* where we get on closest_stop = None # Go through all of our stops until we find the closest # one which matches our criteria for stop in closest_stops: # Now, check for each route that goes through this # stop that are the ones we're considering for route in stop.route_set.filter(service_id__in=routes): stoponroute = StopOnRoute.objects.get(entity=stop, route=route) # Get the closest stop to the origin that serves # this route closest_origin = Entity.objects.filter( stoponroute__route=route, ).distance(entity.location).order_by('distance')[0] origin_stop = StopOnRoute.objects.get(route=route, entity=closest_origin) if stoponroute.order > origin_stop.order: # now check that this stop comes after our # first stop... closest_stop = stop break if closest_stop: break p_and_r_context = { 'start': entity, 'routes': set(routes) & set(sor.route.service_id for sor in closest_stop.stoponroute_set.all()), 'origin_stop': origin_stop, 'closest_stop': closest_stop } start_location = closest_stop else: # Directions from that point to first stop start_location, p_and_r_context = entity, {} return start_location, p_and_r_context
def _scrape(self, route, url, output): self._output.write(route) url += '&showall=1' service = etree.parse(urlopen(url), parser = etree.HTMLParser()) route.stops.clear() for i, tr in enumerate(service.find('.//table').findall('tr')[1:]): try: stop_code = tr[1][0].text except IndexError: # Stops on ACIS Live that don't have codes, e.g., out of county # stops stop_name = tr[3][0].text try: entity = Entity.objects.get(source=self._get_source(), _identifiers__scheme='acisroute', _identifiers__value=stop_name) except Entity.DoesNotExist: entity = Entity(source=self._get_source()) entity_type = self._get_entity_type() entity.primary_type = entity_type identifiers = { 'acisroute': stop_name } entity.save(identifiers=identifiers) set_name_in_language(entity, 'en', title=stop_name) entity.all_types = (entity_type,) entity.update_all_types_completion() else: # TODO: Change identifier lookup based on ACIS region try: entity = get_entity('naptan', stop_code) if entity.source == self._get_source(): # Raise Http404 if this is a bus stop we came up with, # so any name changes, etc, get processed raise Http404() except Http404: # Out of zone bus stops with NaPTAN codes - alternatively, # the fake bus stops Oxontime made up for the TUBE route try: entity = Entity.objects.get(source=self._get_source(), _identifiers__scheme='naptan', _identifiers__value=stop_code) except Entity.DoesNotExist: entity = Entity(source=self._get_source()) identifiers = { 'naptan': stop_code } entity_type = self._get_entity_type() entity.primary_type = entity_type entity.save(identifiers=identifiers) set_name_in_language(entity, 'en', title=tr[3][0].text) entity.all_types = (entity_type,) entity.update_all_types_completion() entity.save() StopOnRoute.objects.create(route=route, entity=entity, order=i)
def get_metadata(self, request, scheme, value): entity = get_entity(scheme, value) user_location = request.session.get('geolocation:location') distance, bearing = entity.get_distance_and_bearing_from(user_location) additional = '<strong>%s</strong>' % capfirst(entity.primary_type.verbose_name) if distance: additional += ', approximately %.3fkm %s' % (distance/1000, bearing) return { 'title': entity.title, 'additional': additional, 'entity': entity, }
def breadcrumb(self, request, context, scheme, value): if request.session.get("geolocation:location"): parent_view = "nearby-detail" else: parent_view = "category-detail" entity = get_entity(scheme, value) return Breadcrumb( "places", lazy_parent(parent_view, ptypes=entity.primary_type.slug), context["entity"].title, lazy_reverse("entity", args=[scheme, value]), )
def breadcrumb(self, request, context, scheme, value): if request.session.get('geolocation:location'): parent_view = 'nearby-detail' else: parent_view = 'category-detail' entity = get_entity(scheme, value) return Breadcrumb( 'places', lazy_parent(parent_view, ptypes=entity.primary_type.slug), context['entity'].title, lazy_reverse('entity', args=[scheme, value]), )
def get_entity(self): """ Gets the entity for this library. This look up is done using the identifier namespace defined in the config. Returns None if no identifier can be found. """ if hasattr(app_by_local_name('library'), 'library_identifier'): library_identifier = app_by_local_name('library').library_identifier try: return get_entity(library_identifier, '/'.join(self.location)) except (Http404, Entity.MultipleObjectsReturned): return None else: return None
def initial_context(self, request, scheme, value): context = super(EntityDetailView, self).initial_context(request) entity = get_entity(scheme, value) associations = [] if hasattr(self.conf, "associations"): for association in self.conf.associations: id_type, id, associated_entities = association try: if id in entity.identifiers[id_type]: associations += [ {"type": type, "entities": [get_entity(ns, value) for ns, value in es]} for type, es in associated_entities ] except (KeyError, Http404): pass for entity_group in entity.groups.all(): group_entities = filter(lambda e: e != entity, Entity.objects.filter(groups=entity_group)) if len(group_entities) > 0: associations.append({"type": entity_group.title, "entities": group_entities}) board = request.GET.get("board", "departures") if board != "departures": board = "arrivals" context.update( { "entity": entity, "train_station": entity, # This allows the ldb metadata to be portable "board": board, "entity_types": entity.all_types.all(), "associations": associations, } ) return context
def get_metadata(self, request, scheme, value): entity = get_entity(scheme, value) user_location = request.session.get("geolocation:location") distance, bearing = entity.get_distance_and_bearing_from(user_location) additional = "<strong>%s</strong>" % capfirst(entity.primary_type.verbose_name) if distance: additional += ", " + _("about %(distance)dm %(bearing)s") % { "distance": int(math.ceil(distance / 10) * 10), "bearing": bearing, } routes = sorted(set(sor.route.service_id for sor in entity.stoponroute_set.all())) if routes: additional += ", " + ungettext( "service %(services)s stops here", "services %(services)s stop here", len(routes) ) % {"services": " ".join(routes)} return {"title": entity.title, "additional": additional, "entity": entity}
def initial_context(self, request): context = super(ParkAndRideView, self).initial_context(request) # If park and ride variable is set, then include those too: if context['park_and_rides']: park_and_rides = [] for park_and_ride in self.conf.park_and_rides: scheme, value = park_and_ride.split(':') entity = get_entity(scheme, value) park_and_rides.append(entity) context['park_and_rides'] = park_and_rides else: raise Http404() self.augment_metadata(park_and_rides) return context
def handle_POST(self, request, context, scheme, value): entity = context["entity"] = get_entity(scheme, value) if entity.source.module_name != "molly.providers.apps.maps.osm": raise Http404 form = UpdateOSMForm(request.POST) if form.is_valid(): new_metadata = copy.deepcopy(entity.metadata["osm"]) for k in ( "name", "operator", "phone", "opening_hours", "url", "cuisine", "food", "food__hours", "atm", "collection_times", "ref", "capacity", ): tag_name = k.replace("__", ":") if tag_name in new_metadata and not form.cleaned_data[k]: del new_metadata["osm"]["tags"][tag_name] elif form.cleaned_data[k]: new_metadata["tags"][tag_name] = form.cleaned_data[k] new_metadata["attrs"]["version"] = str(int(new_metadata["attrs"]["version"]) + 1) osm_update = OSMUpdate( contributor_name=form.cleaned_data["contributor_name"], contributor_email=form.cleaned_data["contributor_email"], contributor_attribute=form.cleaned_data["contributor_attribute"], entity=entity, old=simplejson.dumps(entity.metadata), new=simplejson.dumps(new_metadata), notes=form.cleaned_data["notes"], ) osm_update.save() return self.redirect(reverse("places:entity-update", args=[scheme, value]) + "?submitted=true", request) else: context["form"] = form return self.render(request, context, "places/update_osm")
def initial_context(self, request, scheme, value): context = super(EntityDirectionsView, self).initial_context(request) entity = get_entity(scheme, value) allowed_types = ALLOWED_ROUTING_TYPES type = request.GET.get('type') if type: request.session['places:directions-type'] = type else: type = request.session.get('places:directions-type', 'foot') if type not in allowed_types: type = 'foot' context.update({ 'entity': entity, 'type': type, 'allowed_types': allowed_types, }) return context
def get_metadata(self, request, scheme, value): entity = get_entity(scheme, value) user_location = request.session.get('geolocation:location') distance, bearing = entity.get_distance_and_bearing_from(user_location) additional = '<strong>%s</strong>' % capfirst(entity.primary_type.verbose_name) if distance: additional += ', ' + _('about %(distance)dm %(bearing)s') % { 'distance': int(math.ceil(distance/10)*10), 'bearing': bearing } routes = sorted(set(sor.route.service_id for sor in entity.stoponroute_set.all())) if routes: additional += ', ' + ungettext('service %(services)s stops here', 'services %(services)s stop here', len(routes)) % { 'services': ' '.join(routes) } return { 'title': entity.title, 'additional': additional, 'entity': entity, }
def endElement(self, name): if name in ('node','way') and self.valid: try: types = self.find_types(self.tags) except ValueError: self.ignore_count += 1 return # Ignore ways that lay partly outside our bounding box if name == 'way' and not all(id in self.node_locations for id in self.nodes): return # Ignore disused and under-construction entities if self.tags.get('life_cycle', 'in_use') != 'in_use' or self.tags.get('disused') in ('1', 'yes', 'true'): return # Memory management in debug mode reset_queries() if self.id in self.identities: entity = get_entity(*self.identities[self.id].split(':')) entity.metadata['osm'] = { 'attrs': dict(self.attrs), 'tags': dict(zip((k.replace(':', '_') for k in self.tags.keys()), self.tags.values())) } identifiers = entity.identifiers identifiers.update({ 'osm': self.id }) entity.save(identifiers=identifiers) entity.all_types = set(entity.all_types.all()) | set(self.entity_types[et] for et in types) entity.update_all_types_completion() self.ids.remove(self.id) else: try: entity = Entity.objects.get(source=self.source, _identifiers__scheme='osm', _identifiers__value=self.id) created = False except Entity.DoesNotExist: entity = Entity(source=self.source) created = True if not 'osm' in entity.metadata or \ entity.metadata['osm'].get('attrs', {}).get('timestamp', '') < self.attrs['timestamp']: if created: self.create_count += 1 else: self.modify_count += 1 if name == 'node': entity.location = Point(self.node_location, srid=4326) entity.geometry = entity.location elif name == 'way': cls = LinearRing if self.nodes[0] == self.nodes[-1] else LineString entity.geometry = cls([self.node_locations[n] for n in self.nodes], srid=4326) min_, max_ = (float('inf'), float('inf')), (float('-inf'), float('-inf')) for lon, lat in [self.node_locations[n] for n in self.nodes]: min_ = min(min_[0], lon), min(min_[1], lat) max_ = max(max_[0], lon), max(max_[1], lat) entity.location = Point( (min_[0]+max_[0])/2 , (min_[1]+max_[1])/2 , srid=4326) else: raise AssertionError("There should be no other types of entity we're to deal with.") names = dict() for lang_code, lang_name in settings.LANGUAGES: with override(lang_code): if '-' in lang_code: tags_to_try = ('name:%s' % lang_code, 'name:%s' % lang_code.split('-')[0], 'name', 'operator') else: tags_to_try = ('name:%s' % lang_code, 'name', 'operator') name = None for tag_to_try in tags_to_try: if self.tags.get(tag_to_try): name = self.tags.get(tag_to_try) break if name is None: try: name = reverse_geocode(*entity.location)[0]['name'] if not name: raise IndexError name = u"↝ %s" % name except IndexError: name = u"↝ %f, %f" % (self.node_location[1], self.node_location[0]) names[lang_code] = name entity.metadata['osm'] = { 'attrs': dict(self.attrs), 'tags': dict(zip((k.replace(':', '_') for k in self.tags.keys()), self.tags.values())) } entity.primary_type = self.entity_types[types[0]] identifiers = entity.identifiers identifiers.update({ 'osm': self.id }) entity.save(identifiers=identifiers) for lang_code, name in names.items(): set_name_in_language(entity, lang_code, title=name) entity.all_types = [self.entity_types[et] for et in types] entity.update_all_types_completion() else: self.unchanged_count += 1
def _scrape(self, route, url, output): url += '&showall=1' service = etree.parse(urlopen(url), parser = etree.HTMLParser()) route.stops.clear() for i, tr in enumerate(service.find('.//table').findall('tr')[1:]): try: stop_code = tr[1][0].text except IndexError: # Stops on ACIS Live that don't have codes, e.g., out of county # stops stop_name = tr[3][0].text try: entity = Entity.objects.get(source=self._get_source(), _identifiers__scheme='acisroute', _identifiers__value=stop_name) except Entity.DoesNotExist: entity = Entity(source=self._get_source()) entity_type = self._get_entity_type() entity.primary_type = entity_type identifiers = { 'acisroute': stop_name } entity.save(identifiers=identifiers) set_name_in_language(entity, 'en', title=stop_name) entity.all_types = (entity_type,) entity.update_all_types_completion() else: if stop_code.startswith('693') or stop_code.startswith('272') \ or stop_code.startswith('734') or stop_code.startswith('282'): # Oxontime uses NaPTAN code scheme = 'naptan' elif stop_code.startswith('450'): # West Yorkshire uses plate code scheme = 'plate' else: # Everyone else uses ATCO scheme = 'atco' if stop_code.startswith('370'): # Except South Yorkshire, which mangles the code stop_code = '3700%s' % stop_code[3:] try: entity = get_entity(scheme, stop_code) if entity.source == self._get_source(): # Raise Http404 if this is a bus stop we came up with, # so any name changes, etc, get processed raise Http404() except Http404: # Out of zone bus stops with NaPTAN codes - alternatively, # the fake bus stops Oxontime made up for the TUBE route try: entity = Entity.objects.get(source=self._get_source(), _identifiers__scheme=scheme, _identifiers__value=stop_code) except Entity.DoesNotExist: entity = Entity(source=self._get_source()) identifiers = {scheme: stop_code} entity_type = self._get_entity_type() entity.primary_type = entity_type entity.save(identifiers=identifiers) set_name_in_language(entity, 'en', title=tr[3][0].text) entity.all_types = (entity_type,) entity.update_all_types_completion() entity.save() StopOnRoute.objects.create(route=route, entity=entity, order=i)
def initial_context(self, request): # Get our location for location sorting location = request.session.get('geolocation:location') if location: location = Point(location, srid=4326) context, entities = {'location':location}, set() # If train station is set on config, then include that if hasattr(self.conf, 'train_station'): if getattr(self.conf, 'train_station_nearest', False) and location: et = EntityType.objects.get(slug='rail-station') entity = et.entities_completion.filter(location__isnull=False).distance(location).order_by('distance')[0] else: scheme, value = self.conf.train_station.split(':') entity = get_entity(scheme, value) entities.add(entity) context['train_station'] = entity # If park and ride variable is set, then include those too: if hasattr(self.conf, 'park_and_rides'): park_and_rides = [] for park_and_ride in self.conf.park_and_rides: scheme, value = park_and_ride.split(':') entity = get_entity(scheme, value) park_and_rides.append(entity) entities.add(entity) context['park_and_rides'] = park_and_rides # If service status provider is set, then include those too: if hasattr(self.conf, 'transit_status_provider'): context['transit_status'] = self.conf.transit_status_provider.get_status() context['nearby'] = {} for context_key in getattr(self.conf, 'nearby', {}): type_slug, count = self.conf.nearby[context_key] et = EntityType.objects.get(slug=type_slug) favourites = filter( lambda e: e is not None and et in e.all_types_completion.all(), [f.metadata.get('entity') for f in get_favourites(request)]) if request.GET.get(context_key) == 'nearby': if location: es = et.entities_completion.filter(location__isnull=False).distance(location).order_by('distance')[:count] else: es = [] results_type = 'Nearby' elif request.GET.get(context_key) == 'favourites': es = favourites results_type = 'Favourite' else: if len(favourites) == 0: if location: es = et.entities_completion.filter(location__isnull=False).distance(location).order_by('distance')[:count] else: es = [] else: es = favourites results_type = 'Favourite' if len(favourites) > 0 else 'Nearby' for e in (e for e in es if hasattr(e, 'distance')): distance, e.bearing = e.get_distance_and_bearing_from(location) entities |= set(es) context['nearby'][context_key] = { 'type': et, 'entities': es, 'results_type': results_type, } if getattr(self.conf, 'travel_alerts', False): es = Entity.objects.filter(primary_type__slug='travel-alert') if location: es = es.filter(location__isnull=False).distance(location).order_by('distance') else: es = es.order_by('title') entities |= set(es) context['travel_alerts'] = es # Get any real-time information for all the places we're about to display places_conf = app_by_application_name('molly.apps.places') for provider in reversed(places_conf.providers): provider.augment_metadata(entities, board=request.GET.get('board', 'departures')) context['board'] = request.GET.get('board', 'departures') return context
def get_entity_filter(value): return get_entity(*value)
def initial_context(self, request, scheme, value): context = super(ServiceDetailView, self).initial_context(request) service_id = request.GET.get('id') route_id = request.GET.get('route') route_pk = request.GET.get('routeid') journey = request.GET.get('journey') if service_id or route_id or route_pk or journey: entity = get_entity(scheme, value) else: raise Http404() context.update({ 'entity': entity, }) if service_id: # Add live information from the providers for provider in reversed(self.conf.providers): provider.augment_metadata((entity, )) # If we have no way of getting further journey details, 404 if 'service_details' not in entity.metadata: raise Http404 # Deal with train service data if entity.metadata['service_type'] == 'ldb': # LDB has + in URLs, but Django converts that to space service = entity.metadata['service_details'](service_id.replace(' ', '+')) else: service = entity.metadata['service_details'](service_id) if service is None: raise Http404 if 'error' in service: context.update({ 'title': 'An error occurred', 'service': { 'error': service['error'], }, }) return context context.update({ 'service': service, 'title': service['title'], 'zoom_controls': False, }) elif route_id or route_pk: if route_id: route = entity.route_set.filter(service_id=route_id).distinct() if route.count() == 0: raise Http404() elif route.count() > 1: context.update({ 'title': _('Multiple routes found'), 'multiple_routes': route }) return context else: route = route[0] else: route = get_object_or_404(Route, id=route_pk) i = 1 calling_points = [] previous = True for stop in route.stoponroute_set.all(): if stop.entity == entity: previous = False calling_point = { 'entity': stop.entity, 'at': previous } if stop.entity.location is not None: calling_point['stop_num'] = i i += 1 calling_points.append(calling_point) service = { 'entities': route.stops.all(), 'operator': route.operator, 'has_timetable': False, 'has_realtime': False, 'calling_points': calling_points } if entity not in service['entities']: raise Http404() context.update({ 'title': '%s: %s' % (route.service_id, route.service_name), 'service': service }) elif journey: journey = get_object_or_404(Journey, id=journey) route = journey.route entity_passed = False i = 1 calling_points = [] for stop in journey.scheduledstop_set.all(): if stop.entity == entity: entity_passed = True if not entity_passed and stop.std < datetime.now().time(): calling_point = { 'entity': stop.entity, 'st': stop.std.strftime('%H:%M'), 'at': True } else: calling_point = { 'entity': stop.entity, # Show arrival time (if it exists, else departure time) # if this stop is AFTER where we currently are, otherwise # show the time the bus left stops before this one (if # it exists) 'st': ((stop.sta or stop.std) if entity_passed else (stop.std or stop.sta)).strftime('%H:%M'), 'at': False } if stop.entity.location is not None: calling_point['stop_num'] = i i += 1 calling_points.append(calling_point) service = { 'entities': [s.entity for s in journey.scheduledstop_set.all()], 'operator': journey.route.operator, 'has_timetable': True, 'has_realtime': False, 'calling_points': calling_points, 'notes': journey.notes } if entity not in service['entities']: raise Http404() context.update({ 'title': '%s: %s' % (route.service_id, route.service_name), 'service': service }) if entity.location or len(filter(lambda e: e.location is not None, service['entities'])): map = Map( centre_point = (entity.location[0], entity.location[1], 'green', entity.title) if entity.location else None, points = [(e.location[0], e.location[1], 'red', e.title) for e in service['entities'] if e.location is not None], min_points = len(service['entities']), zoom = None, width = request.map_width, height = request.map_height, ) context.update({ 'map': map }) return context
def initial_context(self, request, tour, page=None): context = super(TourView, self).initial_context(request) tour = get_object_or_404(Tour, id=tour) context.update({ 'tour': tour, 'stops': StopOnTour.objects.filter(tour=tour) }) if page is not None: stop = get_object_or_404(StopOnTour, tour=tour, order=page) context['stop'] = stop try: context['next_stop'] = StopOnTour.objects.get(tour=tour, order=int(page)+1) except StopOnTour.DoesNotExist: pass try: context['previous_stop'] = StopOnTour.objects.get(tour=tour, order=int(page)-1) except StopOnTour.DoesNotExist: pass else: try: arrival_point = int(request.GET.get('arrival_point')) except (ValueError, TypeError): arrival_point = None arrival_route = request.GET.get('arrival_route') if arrival_point is not None or arrival_route: first_stop = tour.stops.all()[0] if arrival_point is not None: start_location, p_and_r_context = self.arrival_point_location(first_stop, arrival_point) context['p_and_r'] = p_and_r_context elif arrival_route is not None: start_location = self.arrival_route_location(first_stop, arrival_route) context['arrival_route'] = arrival_route if start_location is not None: context['first_directions'] = generate_route( [start_location.location, first_stop.location], 'foot') if 'error' not in context['first_directions']: context['directions_start'] = start_location context['directions_end'] = first_stop context['directions_map'] = Map( (start_location.location[0], start_location.location[1], 'green', ''), [(w['location'][0], w['location'][1], 'red', w['instruction']) for w in context['first_directions']['waypoints']], len(context['first_directions']['waypoints']), None, request.map_width, request.map_height, extra_points=[(first_stop.location[0], first_stop.location[1], 'red', first_stop.title)], paths=[(context['first_directions']['path'], '#3c3c3c')]) else: arrival_points = [] for i, arrival_point in enumerate(getattr(self.conf, 'arrival_points', [])): arrival_points.append((i, get_entity(*arrival_point[0].split(':')))) context.update({ 'arrival_points': arrival_points, 'arrival_routes': getattr(self.conf, 'arrival_routes', []), 'created': 'created' in request.GET }) return context
def initial_context(self, request, scheme, value): return { 'entity': get_entity(scheme, value), }
def handle_GET(self, request, context, scheme, value): entity = get_entity(scheme, value) return super(NearbyEntityListView, self).handle_GET(request, context, entity)
def initial_context(self, request, scheme, value): context = super(ServiceDetailView, self).initial_context(request) service_id = request.GET.get('id') route_id = request.GET.get('route') route_pk = request.GET.get('routeid') journey = request.GET.get('journey') if service_id or route_id or route_pk or journey: entity = get_entity(scheme, value) else: raise Http404() context.update({ 'entity': entity, }) if service_id: # Add live information from the providers for provider in reversed(self.conf.providers): provider.augment_metadata((entity, )) # If we have no way of getting further journey details, 404 if 'service_details' not in entity.metadata: raise Http404 # Deal with train service data if entity.metadata['service_type'] == 'ldb': # LDB has + in URLs, but Django converts that to space service = entity.metadata['service_details']( service_id.replace(' ', '+')) else: service = entity.metadata['service_details'](service_id) if service is None: raise Http404 if 'error' in service: context.update({ 'title': 'An error occurred', 'service': { 'error': service['error'], }, }) return context context.update({ 'service': service, 'title': service['title'], 'zoom_controls': False, }) elif route_id or route_pk: if route_id: route = entity.route_set.filter(service_id=route_id).distinct() if route.count() == 0: raise Http404() elif route.count() > 1: context.update({ 'title': _('Multiple routes found'), 'multiple_routes': route }) return context else: route = route[0] else: route = get_object_or_404(Route, id=route_pk) i = 1 calling_points = [] previous = True for stop in route.stoponroute_set.all(): if stop.entity == entity: previous = False calling_point = {'entity': stop.entity, 'at': previous} if stop.entity.location is not None: calling_point['stop_num'] = i i += 1 calling_points.append(calling_point) service = { 'entities': route.stops.all(), 'operator': route.operator, 'has_timetable': False, 'has_realtime': False, 'calling_points': calling_points } if entity not in service['entities']: raise Http404() context.update({ 'title': '%s: %s' % (route.service_id, route.service_name), 'service': service }) elif journey: journey = get_object_or_404(Journey, id=journey) route = journey.route entity_passed = False i = 1 calling_points = [] for stop in journey.scheduledstop_set.all(): if stop.entity == entity: entity_passed = True if not entity_passed and stop.std < datetime.now().time(): calling_point = { 'entity': stop.entity, 'st': stop.std.strftime('%H:%M'), 'at': True } else: calling_point = { 'entity': stop.entity, # Show arrival time (if it exists, else departure time) # if this stop is AFTER where we currently are, otherwise # show the time the bus left stops before this one (if # it exists) 'st': ((stop.sta or stop.std) if entity_passed else (stop.std or stop.sta)).strftime('%H:%M'), 'at': False } if stop.entity.location is not None: calling_point['stop_num'] = i i += 1 calling_points.append(calling_point) service = { 'entities': [s.entity for s in journey.scheduledstop_set.all()], 'operator': journey.route.operator, 'has_timetable': True, 'has_realtime': False, 'calling_points': calling_points, 'notes': journey.notes } if entity not in service['entities']: raise Http404() context.update({ 'title': '%s: %s' % (route.service_id, route.service_name), 'service': service }) if entity.location or len( filter(lambda e: e.location is not None, service['entities'])): map = Map( centre_point=(entity.location[0], entity.location[1], 'green', entity.title) if entity.location else None, points=[(e.location[0], e.location[1], 'red', e.title) for e in service['entities'] if e.location is not None], min_points=len(service['entities']), zoom=None, width=request.map_width, height=request.map_height, ) context.update({'map': map}) return context
def handle_GET(self, request, context, scheme, value, ptype): entity = get_entity(scheme, value) return super(NearbyEntityDetailView, self).handle_GET(request, context, ptype, entity)
def _scrape(self, route, url, output): url += '&showall=1' service = etree.parse(urlopen(url), parser=etree.HTMLParser()) route.stops.clear() for i, tr in enumerate(service.find('.//table').findall('tr')[1:]): try: stop_code = tr[1][0].text except IndexError: # Stops on ACIS Live that don't have codes, e.g., out of county # stops stop_name = tr[3][0].text try: entity = Entity.objects.get( source=self._get_source(), _identifiers__scheme='acisroute', _identifiers__value=stop_name) except Entity.DoesNotExist: entity = Entity(source=self._get_source()) entity_type = self._get_entity_type() entity.primary_type = entity_type identifiers = {'acisroute': stop_name} entity.save(identifiers=identifiers) set_name_in_language(entity, 'en', title=stop_name) entity.all_types = (entity_type, ) entity.update_all_types_completion() else: if stop_code.startswith('693') or stop_code.startswith('272') \ or stop_code.startswith('734') or stop_code.startswith('282'): # Oxontime uses NaPTAN code scheme = 'naptan' elif stop_code.startswith('450'): # West Yorkshire uses plate code scheme = 'plate' else: # Everyone else uses ATCO scheme = 'atco' if stop_code.startswith('370'): # Except South Yorkshire, which mangles the code stop_code = '3700%s' % stop_code[3:] try: entity = get_entity(scheme, stop_code) if entity.source == self._get_source(): # Raise Http404 if this is a bus stop we came up with, # so any name changes, etc, get processed raise Http404() except Http404: # Out of zone bus stops with NaPTAN codes - alternatively, # the fake bus stops Oxontime made up for the TUBE route try: entity = Entity.objects.get( source=self._get_source(), _identifiers__scheme=scheme, _identifiers__value=stop_code) except Entity.DoesNotExist: entity = Entity(source=self._get_source()) identifiers = {scheme: stop_code} entity_type = self._get_entity_type() entity.primary_type = entity_type entity.save(identifiers=identifiers) set_name_in_language(entity, 'en', title=tr[3][0].text) entity.all_types = (entity_type, ) entity.update_all_types_completion() entity.save() StopOnRoute.objects.create(route=route, entity=entity, order=i)
def initial_context(self, request, scheme, value): return dict( super(EntityUpdateView, self).initial_context(request), entity=get_entity(scheme, value), )
def get_metadata(self, request, scheme, value, ptype): entity = get_entity(type_slug, id) return super(NearbyEntityDetailView, self).get_metadata(request, ptype, entity)
def initial_context(self, request, scheme, value, ptype): entity = get_entity(scheme, value) context = super(NearbyEntityDetailView, self).initial_context(request, ptype, entity) context['entity'] = entity return context
def get_metadata(self, request, scheme, value): entity = get_entity(scheme, value) return super(NearbyEntityListView, self).get_metadata(request, entity)