def get_maps(document, lang): """Load and return maps that intersect with the document geometry. """ if document.geometry is None: return [] document_geom = select([DocumentGeometry.geom]). \ where(DocumentGeometry.document_id == document.document_id) document_geom_detail = select([DocumentGeometry.geom_detail]). \ where(DocumentGeometry.document_id == document.document_id) topo_maps = DBSession. \ query(TopoMap). \ filter(TopoMap.redirects_to.is_(None)). \ join( DocumentGeometry, TopoMap.document_id == DocumentGeometry.document_id). \ options(load_only( TopoMap.document_id, TopoMap.editor, TopoMap.code, TopoMap.version, TopoMap.protected)). \ options(joinedload(TopoMap.locales).load_only( DocumentLocale.lang, DocumentLocale.title, DocumentLocale.version)). \ filter( or_( DocumentGeometry.geom_detail.ST_Intersects( document_geom.label('t1')), DocumentGeometry.geom_detail.ST_Intersects( document_geom_detail.label('t2')) )). \ all() if lang is not None: set_best_locale(topo_maps, lang) return topo_maps
def get(self): """Get the filter preferences of the authenticated user. Request: `GET` `/users/preferences[?pl=...]` Parameters: `pl=...` (optional) When set only the given locale will be included (if available). Otherwise the default locale of the user will be used. """ user = self.get_user() lang = self.request.validated.get('lang') if not lang: lang = user.lang areas = user.feed_filter_areas if lang is not None: set_best_locale(areas, lang) return { 'followed_only': user.feed_followed_only, 'activities': user.feed_filter_activities, 'langs': user.feed_filter_langs, 'areas': [to_json_dict(a, schema_listing_area) for a in areas] }
def get(self): """Get the filter preferences of the authenticated user. Request: `GET` `/users/preferences[?pl=...]` Parameters: `pl=...` (optional) When set only the given locale will be included (if available). Otherwise the default locale of the user will be used. """ user = self.get_user() lang = self.request.validated.get("lang") if not lang: lang = user.lang areas = user.feed_filter_areas if lang is not None: set_best_locale(areas, lang) return { "followed_only": user.feed_followed_only, "activities": user.feed_filter_activities, "areas": [to_json_dict(a, schema_listing_area) for a in areas], }
def _get_documents( self, clazz, schema, clazz_locale, adapt_schema, custom_filter, include_areas, set_custom_fields, meta_params, load_documents): base_query = DBSession.query(clazz).\ filter(getattr(clazz, 'redirects_to').is_(None)) base_total_query = DBSession.query(getattr(clazz, 'document_id')).\ filter(getattr(clazz, 'redirects_to').is_(None)) if custom_filter: base_query = custom_filter(base_query) base_total_query = custom_filter(base_total_query) base_query = add_load_for_locales(base_query, clazz, clazz_locale) base_query = base_query.options(joinedload(getattr(clazz, 'geometry'))) if clazz == Outing: base_query = base_query. \ order_by(clazz.date_end.desc()). \ order_by(clazz.document_id.desc()) else: base_query = base_query.order_by(clazz.document_id.desc()) base_query = add_load_for_profiles(base_query, clazz) base_total_query = add_profile_filter(base_total_query, clazz) if include_areas: base_query = base_query. \ options( joinedload(getattr(clazz, '_areas')). load_only( 'document_id', 'area_type', 'version', 'protected', 'type'). joinedload('locales'). load_only( 'lang', 'title', 'version') ) documents, total = load_documents(base_query, base_total_query) set_available_langs(documents, loaded=True) lang = meta_params['lang'] if lang is not None: set_best_locale(documents, lang) if include_areas: self._set_areas_for_documents(documents, lang) if set_custom_fields: set_custom_fields(documents, lang) return { 'documents': [ to_json_dict( doc, schema if not adapt_schema else adapt_schema(schema, doc) ) for doc in documents ], 'total': total }
def _get_documents_from_ids(document_ids, base_query, documents_config, lang): """ Load the documents for the ids and return them as json dict. The returned list contains None values for documents that could not be loaded, and the list has the same order has the document id list. """ base_query = base_query.options( load_only(*documents_config.get_load_only_fields())) base_query = add_load_for_locales( base_query, documents_config.clazz, documents_config.clazz_locale, documents_config.get_load_only_fields_locales()) if len(documents_config.get_load_only_fields_geometry()) > 1: # only load the geometry if the fields list contains other columns than # 'version' base_query = base_query.options( joinedload(getattr(documents_config.clazz, 'geometry')).load_only( *documents_config.get_load_only_fields_geometry())) if documents_config.include_areas: base_query = base_query. \ options( joinedload(getattr(documents_config.clazz, '_areas')). load_only( 'document_id', 'area_type', 'version', 'protected', 'type'). joinedload('locales'). load_only( 'lang', 'title', 'version') ) documents = _load_documents(document_ids, documents_config.clazz, base_query) set_available_langs(documents, loaded=True) if lang is not None: set_best_locale(documents, lang) if documents_config.include_areas: _set_areas_for_documents(documents, lang) if documents_config.include_img_count: _set_img_count_for_documents(documents, document_ids) if documents_config.set_custom_fields: documents_config.set_custom_fields(documents, lang) # make sure the documents are returned in the same order document_index = {doc.document_id: doc for doc in documents} documents = [document_index.get(id) for id in document_ids] return [ to_json_dict( doc, documents_config.schema if not documents_config.adapt_schema else documents_config.adapt_schema(documents_config.schema, doc), with_special_geometry_attrs=True) if doc else None for doc in documents ]
def _get_documents_from_ids( document_ids, base_query, documents_config, lang): """ Load the documents for the ids and return them as json dict. The returned list contains None values for documents that could not be loaded, and the list has the same order has the document id list. """ base_query = base_query.options( load_only(*documents_config.get_load_only_fields()) ) base_query = add_load_for_locales( base_query, documents_config.clazz, documents_config.clazz_locale, documents_config.get_load_only_fields_locales()) if len(documents_config.get_load_only_fields_geometry()) > 1: # only load the geometry if the fields list contains other columns than # 'version' base_query = base_query.options( joinedload(getattr(documents_config.clazz, 'geometry')). load_only(*documents_config.get_load_only_fields_geometry()) ) if documents_config.include_areas: base_query = base_query. \ options( joinedload(getattr(documents_config.clazz, '_areas')). load_only( 'document_id', 'area_type', 'version', 'protected', 'type'). joinedload('locales'). load_only( 'lang', 'title', 'version') ) documents = _load_documents( document_ids, documents_config.clazz, base_query) set_available_langs(documents, loaded=True) if lang is not None: set_best_locale(documents, lang) if documents_config.include_areas: _set_areas_for_documents(documents, lang) if documents_config.set_custom_fields: documents_config.set_custom_fields(documents, lang) # make sure the documents are returned in the same order document_index = {doc.document_id: doc for doc in documents} documents = [document_index.get(id) for id in document_ids] return [ to_json_dict( doc, documents_config.schema if not documents_config.adapt_schema else documents_config.adapt_schema( documents_config.schema, doc) ) if doc else None for doc in documents ]
def _set_areas_for_documents(documents, lang): for document in documents: # expunge is set to False because the parent document of the areas # was already disconnected from the session at this point set_best_locale(document._areas, lang, expunge=False) document.areas = [ to_json_dict(m, schema_listing_area) for m in document._areas ]
def set_linked_routes(waypoint, lang): """ Set associated routes for the given waypoint including associated routes of child and grandchild waypoints. Note that this function returns a dict and not a list! """ with_query_waypoints = _get_select_children(waypoint) total = DBSession.query(Route.document_id). \ select_from(with_query_waypoints). \ join( Association, with_query_waypoints.c.document_id == Association.parent_document_id). \ join( Route, Association.child_document_id == Route.document_id). \ filter(Route.redirects_to.is_(None)). \ count() routes = limit_route_fields( DBSession.query(Route). select_from(with_query_waypoints). join( Association, with_query_waypoints.c.document_id == Association.parent_document_id). join( Route, Association.child_document_id == Route.document_id). filter(Route.redirects_to.is_(None)). order_by( with_query_waypoints.c.priority.desc(), Route.document_id.desc()). limit(NUM_ROUTES) ). \ all() if lang is not None: set_best_locale(routes, lang) waypoint.associations['all_routes'] = { 'total': total, 'routes': [ to_json_dict(route, schema_association_route) for route in routes ] }
def set_linked_routes(waypoint, lang): """ Set associated routes for the given waypoint including associated routes of child and grandchild waypoints. Note that this function returns a dict and not a list! """ with_query_waypoints = _get_select_children(waypoint) total = DBSession.query(Route.document_id). \ select_from(with_query_waypoints). \ join( Association, with_query_waypoints.c.document_id == Association.parent_document_id). \ join( Route, Association.child_document_id == Route.document_id). \ filter(Route.redirects_to.is_(None)). \ count() routes = limit_route_fields( DBSession.query(Route). select_from(with_query_waypoints). join( Association, with_query_waypoints.c.document_id == Association.parent_document_id). join( Route, Association.child_document_id == Route.document_id). filter(Route.redirects_to.is_(None)). order_by( with_query_waypoints.c.priority.desc(), Route.document_id.desc()). limit(NUM_ROUTES) ). \ all() if lang is not None: set_best_locale(routes, lang) waypoint.associations['all_routes'] = { 'total': total, 'routes': [to_json_dict(route, schema_association_route) for route in routes] }
def _get_document_for_cooking(clazz, document_id, lang, clazz_locale=None): """Get a document with a single locale this locale may not be the one requested, if this one doesn't exists in this case, the lang returned is given by lang_priority """ document_query = DBSession. \ query(clazz). \ filter(getattr(clazz, 'document_id') == document_id). \ options(joinedload('geometry')) document_query = add_load_for_locales(document_query, clazz, clazz_locale) document_query = add_load_for_profiles(document_query, clazz) document = document_query.first() if not document: raise HTTPNotFound('document not found') set_best_locale([document], lang) return document
def set_recent_outings(route, lang): """Set last 10 outings on the given route. """ recent_outings = DBSession.query(Outing). \ filter(Outing.redirects_to.is_(None)). \ join( Association, Outing.document_id == Association.child_document_id). \ filter(Association.parent_document_id == route.document_id). \ options(load_only( Outing.document_id, Outing.activities, Outing.date_start, Outing.date_end, Outing.version, Outing.protected)). \ options(joinedload(Outing.locales).load_only( DocumentLocale.lang, DocumentLocale.title, DocumentLocale.version)). \ order_by(Outing.date_end.desc()). \ limit(NUM_RECENT_OUTINGS). \ all() set_author(recent_outings, None) if lang is not None: set_best_locale(recent_outings, lang) total = DBSession.query(Outing.document_id). \ filter(Outing.redirects_to.is_(None)). \ join( Association, Outing.document_id == Association.child_document_id). \ filter(Association.parent_document_id == route.document_id). \ count() route.associations['recent_outings'] = { 'outings': [ to_json_dict(user, schema_association_outing) for user in recent_outings ], 'total': total }
def get_areas(document, lang): """Load and return areas linked with the given document. """ areas = DBSession. \ query(Area). \ filter(Area.redirects_to.is_(None)). \ join( AreaAssociation, Area.document_id == AreaAssociation.area_id). \ options(load_only( Area.document_id, Area.area_type, Area.version, Area.protected)). \ options(joinedload(Area.locales).load_only( DocumentLocale.lang, DocumentLocale.title, DocumentLocale.version)). \ filter( AreaAssociation.document_id == document.document_id ). \ all() if lang is not None: set_best_locale(areas, lang) return areas
def get_associations(document, lang, editing_view): """Load and return associated documents. """ types_to_include = associations_to_include.get(document.type, set()) if editing_view: edit_types = updatable_associations.get(document.type, set()) types_to_include = types_to_include.intersection(edit_types) associations = {} if 'waypoints' in types_to_include and \ 'waypoint_children' in types_to_include: associations['waypoints'] = get_linked_waypoint_parents(document) associations['waypoint_children'] = \ get_linked_waypoint_children(document) elif 'waypoints' in types_to_include: waypoint_parents = get_linked_waypoint_parents(document) waypoint_children = get_linked_waypoint_children(document) associations['waypoints'] = waypoint_parents + waypoint_children if 'routes' in types_to_include: if not editing_view and document.type == WAYPOINT_TYPE: # for waypoints the routes of child waypoints should also be # included (done in WaypointRest) pass else: associations['routes'] = get_linked_routes(document) if 'users' in types_to_include: associations['users'] = get_linked_users(document) if 'images' in types_to_include: associations['images'] = get_linked_images(document) if lang: for typ, docs in associations.items(): if typ != 'users': set_best_locale(docs, lang) return associations
def get_documents(document_ids, model, locale_model, lang): """Load the documents for the given ids. The documents are returned in the same order as the ids. If a document for a given id does not exist, the document is skipped. """ if not document_ids: return [] documents_query = DBSession.\ query(model).\ filter(model.redirects_to.is_(None)).\ filter(model.document_id.in_(document_ids)).\ options(joinedload(model.locales.of_type(locale_model))). \ options(joinedload(model.geometry)) documents_query = add_load_for_profiles(documents_query, model) documents = documents_query.all() if lang is not None: set_best_locale(documents, lang) # make sure the documents stay in the same order as returned by ES document_index = {doc.document_id: doc for doc in documents} return [document_index[id] for id in document_ids if id in document_index]
def get_maps(document, lang): """Load and return areas linked with the given document. """ maps = DBSession. \ query(TopoMap). \ filter(TopoMap.redirects_to.is_(None)). \ join( TopoMapAssociation, TopoMap.document_id == TopoMapAssociation.topo_map_id). \ options(load_only( TopoMap.document_id, TopoMap.version, TopoMap.protected, TopoMap.editor, TopoMap.scale, TopoMap.code)). \ options(joinedload(TopoMap.locales).load_only( DocumentLocale.lang, DocumentLocale.title, DocumentLocale.version)). \ filter( TopoMapAssociation.document_id == document.document_id ). \ all() if lang is not None: set_best_locale(maps, lang) return maps
def _get_documents(self, clazz, schema, clazz_locale, adapt_schema, custom_filter, include_areas, set_custom_fields, meta_params, load_documents): base_query = DBSession.query(clazz).\ filter(getattr(clazz, 'redirects_to').is_(None)) base_total_query = DBSession.query(getattr(clazz, 'document_id')).\ filter(getattr(clazz, 'redirects_to').is_(None)) if custom_filter: base_query = custom_filter(base_query) base_total_query = custom_filter(base_total_query) base_query = add_load_for_locales(base_query, clazz, clazz_locale) base_query = base_query.options(joinedload(getattr(clazz, 'geometry'))) if clazz == Outing: base_query = base_query. \ order_by(clazz.date_end.desc()). \ order_by(clazz.document_id.desc()) else: base_query = base_query.order_by(clazz.document_id.desc()) base_query = add_load_for_profiles(base_query, clazz) base_total_query = add_profile_filter(base_total_query, clazz) if include_areas: base_query = base_query. \ options( joinedload(getattr(clazz, '_areas')). load_only( 'document_id', 'area_type', 'version', 'protected', 'type'). joinedload('locales'). load_only( 'lang', 'title', 'version') ) documents, total = load_documents(base_query, base_total_query) set_available_langs(documents, loaded=True) lang = meta_params['lang'] if lang is not None: set_best_locale(documents, lang) if include_areas: self._set_areas_for_documents(documents, lang) if set_custom_fields: set_custom_fields(documents, lang) return { 'documents': [ to_json_dict( doc, schema if not adapt_schema else adapt_schema(schema, doc)) for doc in documents ], 'total': total }
def _load_document_info(self, document_id, lang, clazz): is_route = clazz == Route locales_type = with_polymorphic(DocumentLocale, RouteLocale) \ if is_route else DocumentLocale locales_attr = getattr(clazz, 'locales') locales_type_eager = locales_attr.of_type(RouteLocale) \ if is_route else locales_attr locales_load_only = [ DocumentLocale.lang, DocumentLocale.title, DocumentLocale.version] if is_route: locales_load_only.append(RouteLocale.title_prefix) document_query = DBSession. \ query(clazz). \ options(load_only( Document.document_id, Document.version, Document.redirects_to, Document.protected)). \ join(locales_type). \ filter(getattr(clazz, 'document_id') == document_id). \ filter(DocumentLocale.lang == lang). \ options(contains_eager(locales_type_eager, alias=locales_type). load_only(*locales_load_only)) document_query = add_load_for_profiles(document_query, clazz) document = document_query.first() if not document: # the requested locale might not be available, try to get the # document with all locales and set the "best" document_query = DBSession. \ query(clazz). \ options(load_only( Document.document_id, Document.version, Document.redirects_to, Document.protected)). \ filter(getattr(clazz, 'document_id') == document_id). \ options(joinedload(locales_type_eager). load_only(*locales_load_only)) document_query = add_load_for_profiles(document_query, clazz) document = document_query.first() if not document: raise HTTPNotFound('document not found') set_best_locale([document], lang) if document.redirects_to: return { 'redirects_to': document.redirects_to, 'available_langs': get_available_langs( document.redirects_to) } assert len(document.locales) == 1 locale = document.locales[0] return { 'document_id': document.document_id, 'locales': [{ 'lang': locale.lang, 'title': locale.title if clazz != UserProfile else document.name, 'title_prefix': locale.title_prefix if is_route else None }] }
def _load_document_info(self, document_id, lang, clazz): is_route = clazz == Route locales_type = with_polymorphic(DocumentLocale, RouteLocale) \ if is_route else DocumentLocale locales_attr = getattr(clazz, 'locales') locales_type_eager = locales_attr.of_type(RouteLocale) \ if is_route else locales_attr locales_load_only = [ DocumentLocale.lang, DocumentLocale.title, DocumentLocale.version ] if is_route: locales_load_only.append(RouteLocale.title_prefix) document_query = DBSession. \ query(clazz). \ options(load_only( Document.document_id, Document.version, Document.redirects_to, Document.protected)). \ join(locales_type). \ filter(getattr(clazz, 'document_id') == document_id). \ filter(DocumentLocale.lang == lang). \ options(contains_eager(locales_type_eager, alias=locales_type). load_only(*locales_load_only)) document_query = add_load_for_profiles(document_query, clazz) document = document_query.first() if not document: # the requested locale might not be available, try to get the # document with all locales and set the "best" document_query = DBSession. \ query(clazz). \ options(load_only( Document.document_id, Document.version, Document.redirects_to, Document.protected)). \ filter(getattr(clazz, 'document_id') == document_id). \ options(joinedload(locales_type_eager). load_only(*locales_load_only)) document_query = add_load_for_profiles(document_query, clazz) document = document_query.first() if not document: raise HTTPNotFound('document not found') set_best_locale([document], lang) if document.redirects_to: return { 'redirects_to': document.redirects_to, 'available_langs': get_available_langs(document.redirects_to) } assert len(document.locales) == 1 locale = document.locales[0] return { 'document_id': document.document_id, 'locales': [{ 'lang': locale.lang, 'title': locale.title if clazz != UserProfile else document.name, 'title_prefix': locale.title_prefix if is_route else None }] }
def set_recent_outings(waypoint, lang): """Set last 10 outings on routes associated to the given waypoint. """ t_outing_route = aliased(Association, name='a1') t_route_wp = aliased(Association, name='a2') t_route = aliased(Document, name='r') with_query_waypoints = _get_select_children(waypoint) recent_outings = DBSession.query(Outing). \ filter(Outing.redirects_to.is_(None)). \ join( t_outing_route, Outing.document_id == t_outing_route.child_document_id). \ join( t_route, and_( t_outing_route.parent_document_id == t_route.document_id, t_route.type == ROUTE_TYPE)). \ join( t_route_wp, t_route_wp.child_document_id == t_route.document_id). \ join( with_query_waypoints, with_query_waypoints.c.document_id == t_route_wp.parent_document_id ). \ options(load_only( Outing.document_id, Outing.activities, Outing.date_start, Outing.date_end, Outing.version, Outing.protected)). \ options(joinedload(Outing.locales).load_only( DocumentLocale.lang, DocumentLocale.title, DocumentLocale.version)). \ order_by(Outing.date_end.desc()). \ limit(NUM_RECENT_OUTINGS). \ all() set_author(recent_outings, None) if lang is not None: set_best_locale(recent_outings, lang) total = DBSession.query(Outing.document_id). \ filter(Outing.redirects_to.is_(None)). \ join( t_outing_route, Outing.document_id == t_outing_route.child_document_id). \ join( t_route, and_( t_outing_route.parent_document_id == t_route.document_id, t_route.type == ROUTE_TYPE)). \ join( t_route_wp, t_route_wp.child_document_id == t_route.document_id). \ join( with_query_waypoints, with_query_waypoints.c.document_id == t_route_wp.parent_document_id ). \ count() waypoint.associations['recent_outings'] = { 'total': total, 'outings': [ to_json_dict(outing, schema_association_outing) for outing in recent_outings ] }