예제 #1
0
    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
예제 #2
0
 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
예제 #3
0
 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
예제 #4
0
    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')
예제 #5
0
    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
예제 #6
0
 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
예제 #7
0
 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]),
     )
예제 #8
0
 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
예제 #9
0
 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)
예제 #10
0
 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,
     }
예제 #11
0
 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]),
     )
예제 #12
0
 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]),
     )
예제 #13
0
 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
예제 #14
0
    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
예제 #15
0
 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}
예제 #16
0
    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
예제 #17
0
    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")
예제 #18
0
 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
예제 #19
0
 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,
     }
예제 #20
0
파일: osm.py 프로젝트: RCGTDev/mollyproject
 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
예제 #21
0
 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)
예제 #22
0
 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
예제 #23
0
def get_entity_filter(value):
    return get_entity(*value)
예제 #24
0
    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
예제 #25
0
def get_entity_filter(value):
    return get_entity(*value)
예제 #26
0
 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
예제 #27
0
 def initial_context(self, request, scheme, value):
     return {
         'entity': get_entity(scheme, value),
     }
예제 #28
0
 def handle_GET(self, request, context, scheme, value):
     entity = get_entity(scheme, value)
     return super(NearbyEntityListView, self).handle_GET(request, context, entity)
예제 #29
0
    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
예제 #30
0
 def handle_GET(self, request, context, scheme, value, ptype):
     entity = get_entity(scheme, value)
     return super(NearbyEntityDetailView,
                  self).handle_GET(request, context, ptype, entity)
예제 #31
0
    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)
예제 #32
0
 def initial_context(self, request, scheme, value):
     return {
         'entity': get_entity(scheme, value),
     }
예제 #33
0
 def initial_context(self, request, scheme, value):
     return dict(
         super(EntityUpdateView, self).initial_context(request),
         entity=get_entity(scheme, value),
     )
예제 #34
0
 def get_metadata(self, request, scheme, value, ptype):
     entity = get_entity(type_slug, id)
     return super(NearbyEntityDetailView,
                  self).get_metadata(request, ptype, entity)
예제 #35
0
 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
예제 #36
0
 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
예제 #37
0
 def get_metadata(self, request, scheme, value, ptype):
     entity = get_entity(type_slug, id)
     return super(NearbyEntityDetailView, self).get_metadata(request, ptype, entity)
예제 #38
0
 def handle_GET(self, request, context, scheme, value):
     entity = get_entity(scheme, value)
     return super(NearbyEntityListView,
                  self).handle_GET(request, context, entity)
예제 #39
0
 def handle_GET(self, request, context, scheme, value, ptype):
     entity = get_entity(scheme, value)
     return super(NearbyEntityDetailView, self).handle_GET(request, context, ptype, entity)
예제 #40
0
 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
예제 #41
0
 def get_metadata(self, request, scheme, value):
     entity = get_entity(scheme, value)
     return super(NearbyEntityListView, self).get_metadata(request, entity)