Package madrona :: Package kmlapp :: Module views
[hide private]

Source Code for Module madrona.kmlapp.views

  1  from django.shortcuts import render_to_response 
  2  from django.contrib.auth.models import * 
  3  from django.template.loader import get_template 
  4  from django.template import Context 
  5  from django.http import HttpResponse, Http404 
  6  from madrona.common import default_mimetypes as mimetypes 
  7  from madrona.common import utils  
  8  from django.http import Http404 
  9  from madrona.common.utils import load_session, get_logger 
 10  from django.contrib.gis.db import models 
 11  from django.core.exceptions import FieldError 
 12  from django.conf import settings 
 13  from django.contrib.contenttypes.models import ContentType 
 14  from madrona.features import get_feature_models, get_collection_models, get_feature_by_uid 
 15  from madrona.features.models import FeatureCollection, Feature 
 16  try: 
 17      set 
 18  except NameError: 
 19      from sets import Set as set 
 20   
 21  log = get_logger() 
22 23 -def get_styles(features, collections, links=True):
24 """ 25 Based on which features and collection are provided, 26 the styles for all features are determined here 27 """ 28 models = [] 29 models.extend([f.kml_style for f in features]) 30 models.extend([c.kml_style for c in collections]) 31 if not links: 32 # Collections will be represented by Folders, not NetworkLinks 33 # So every feature n the entire tree will be in this KML Doc 34 # We need to recurse down to determine what's in there 35 for c in collections: 36 children = c.feature_set(recurse=True) 37 models.extend([child.kml_style for child in children]) 38 unique_set = set(models) 39 return list(unique_set)
40
41 -def get_user_data(user):
42 """ 43 Organizes user's Features and FeatureCollections. 44 Only returns objects owned by user, not shared 45 Returns only the features/collections at the top level, 46 nested child features will be handled later through 47 recursive calls to feature_set. 48 """ 49 toplevel_features = [] 50 toplevel_collections = [] 51 52 for fmodel in get_feature_models(): 53 unattached = list(fmodel.objects.filter(user=user, content_type=None, object_id=None)) 54 toplevel_features.extend(unattached) 55 56 for cmodel in get_collection_models(): 57 collections_top = list(cmodel.objects.filter(user=user, content_type=None, object_id=None)) 58 toplevel_collections.extend(collections_top) 59 60 return toplevel_features, toplevel_collections
61
62 -def get_data_for_feature(user, uid):
63 try: 64 f = get_feature_by_uid(uid) 65 except: 66 return False, HttpResponse("Feature %s does not exist" % uid, status=404) 67 68 viewable, response = f.is_viewable(user) 69 if not viewable: 70 return viewable, response 71 72 features = [] 73 collections = [] 74 75 if isinstance(f, FeatureCollection): 76 obj_id = f.pk 77 ct = ContentType.objects.get_for_model(f.__class__) 78 for fmodel in get_feature_models(): 79 unattached = list(fmodel.objects.filter(content_type=ct,object_id=obj_id)) 80 features.extend(unattached) 81 82 for cmodel in get_collection_models(): 83 collections_top = list(cmodel.objects.filter(content_type=ct,object_id=obj_id)) 84 collections.extend(collections_top) 85 elif isinstance(f, Feature): 86 features.append(f) 87 88 return features, collections
89
90 -def get_public_data():
91 """ 92 No login necessary, everyone sees these 93 Public groups defined in settings.SHARING_TO_PUBLIC_GROUPS 94 """ 95 from django.conf import settings 96 public_groups = Group.objects.filter(name__in=settings.SHARING_TO_PUBLIC_GROUPS) 97 features = [] 98 collections = [] 99 100 for fmodel in get_feature_models(): 101 unattached = list(fmodel.objects.filter(sharing_groups__in=public_groups)) 102 features.extend(unattached) 103 104 for cmodel in get_collection_models(): 105 collections_top = list(cmodel.objects.filter(sharing_groups__in=public_groups)) 106 collections.extend(collections_top) 107 108 return features, collections
109
110 -def get_shared_data(shareuser, sharegroup, user):
111 sg = Group.objects.get(pk=sharegroup) 112 su = User.objects.get(pk=shareuser) 113 114 features = [] 115 collections = [] 116 117 for fmodel in get_feature_models(): 118 # Find top level features shared with user 119 # top-level == not belonging to any collections 120 # have to use content_type and object_id fields to determine 121 unattached = list( 122 fmodel.objects.shared_with_user(user,filter_groups=[sg]) 123 .filter(user=su, content_type=None,object_id=None) 124 ) 125 features.extend(unattached) 126 127 for cmodel in get_collection_models(): 128 collections_top = list( 129 cmodel.objects.shared_with_user(user,filter_groups=[sg]) 130 .filter(user=su, content_type=None,object_id=None) 131 ) 132 collections.extend(collections_top) 133 134 return features, collections
135
136 -def create_kmz(kml, zippath):
137 """ 138 Given a KML string and a "/" seperated path like "FOLDERNAME/doc.kml", 139 creates a zipped KMZ archive buffer that can be written directly to a 140 django response object 141 """ 142 import tempfile 143 from cStringIO import StringIO 144 import zipfile 145 146 # write out the kml to tempfile 147 #The Problem: for Windows, we need to close the file before we can access it again below (via zipout.write) 148 # this caused a Permissions Error when running from the local dev server (on Windows) 149 # as Windows considered the unclosed file to already be in use (and therefore unaccessible) 150 #The Solution: adding 'delete=False' to tempfile.NamedTemporaryFiles for developing environments using Python 2.6(sf 2-16-10) 151 # this will only happen if the user is using Python 2.6, previous versions of Python will treat the code as it was 152 # (this delete parameter isn't available until python 2.6) 153 #if the development environment is using 2.5 or earlier, then the temp file will still be closed via kmlfile.close() 154 #if the development environment is using 2.6 then the temporary file is deleted manually via os.unlink(kmlfile.name) (see below) 155 #This was reported (and perhaps more fully explained) in Issue 263 156 python26 = True 157 try: 158 kmlfile = tempfile.NamedTemporaryFile(delete=False) 159 except: 160 kmlfile = tempfile.NamedTemporaryFile() 161 python26 = False 162 kmlfile.write(kml.encode('utf-8')) 163 kmlfile.flush() 164 if python26: 165 kmlfile.close() 166 167 # zip it up into a kmz 168 kmzbuffer = StringIO() 169 zipout = zipfile.ZipFile(kmzbuffer,'w',zipfile.ZIP_DEFLATED) 170 zipout.write(kmlfile.name, zippath.encode('ascii')) 171 zipout.close() 172 173 # close out the tempfile 174 if python26: 175 import os 176 os.unlink(kmlfile.name) 177 else: 178 kmlfile.close() 179 # grab the content of the stringIO buffer 180 kmz = kmzbuffer.getvalue() 181 # close out the stringIO buffer 182 kmzbuffer.close() 183 184 return kmz
185 186 from django.views.decorators.cache import cache_control
187 188 @cache_control(no_cache=True) 189 -def create_kml(request, input_username=None, input_uid=None, 190 input_shareuser=None, input_sharegroup=None, links=False, kmz=False, 191 session_key='0'):
192 """ 193 Returns a KML/KMZ containing Feautures/FeatureCollections owned by user 194 """ 195 load_session(request, session_key) 196 user = request.user 197 if input_username and user.username != input_username: 198 log.warn("Input username from URL is %r but request.user.username is %r" % (input_username, user.username)) 199 return HttpResponse('Access denied', status=401) 200 201 if input_username: 202 features, collections = get_user_data(user) 203 elif input_uid: 204 features, collections = get_data_for_feature(user, input_uid) 205 elif input_shareuser and input_sharegroup: 206 features, collections = get_shared_data(input_shareuser, input_sharegroup, user) 207 else: 208 raise Http404 209 210 if not features and isinstance(collections, HttpResponse): 211 return collections # We got an http error going on 212 213 styles = get_styles(features,collections,links) 214 215 t = get_template('kmlapp/myshapes.kml') 216 context = Context({ 217 'user': user, 218 'features': features, 219 'collections': collections, 220 'use_network_links': links, 221 'request_path': request.path, 222 'styles': styles, 223 'session_key': session_key, 224 'shareuser': input_shareuser, 225 'sharegroup': input_sharegroup, 226 'feature_id': input_uid, 227 }) 228 kml = t.render(context) 229 mime = mimetypes.KML 230 if kmz: 231 mime = mimetypes.KMZ 232 kml = create_kmz(kml, 'mm/doc.kml') 233 response = HttpResponse(kml, mimetype=mime) 234 response['Content-Disposition'] = 'attachment' 235 return response
236
237 @cache_control(no_cache=True) 238 -def create_shared_kml(request, input_username, kmz=False, session_key='0'):
239 """ 240 Returns a KML/KMZ containing shared MPAs (organized into folders by groups and users who have shared them) 241 """ 242 load_session(request, session_key) 243 user = request.user 244 if input_username and user.username != input_username: 245 return HttpResponse('Access denied', status=401) 246 247 from madrona.features import groups_users_sharing_with 248 sharing_with = groups_users_sharing_with(user) 249 250 t = get_template('kmlapp/shared.kml') 251 kml = t.render(Context({'user': request.user, 'groups_users': sharing_with, 'request_path': request.path, 'session_key': session_key})) 252 253 mime = mimetypes.KML 254 if kmz: 255 mime = mimetypes.KMZ 256 kml = create_kmz(kml, 'mm/doc.kml') 257 response = HttpResponse(kml, mimetype=mime) 258 response['Content-Disposition'] = 'attachment' 259 return response
260
261 -def shared_public(request, kmz=False, session_key='0'):
262 """ 263 Shows all publically shared arrays 264 Must be shared with a special set of public groups 265 defined in settings.SHARING_TO_PUBLIC_GROUPS 266 """ 267 load_session(request, session_key) 268 user = request.user 269 features, collections = get_public_data() 270 271 styles = get_styles(features,collections) 272 273 # determine content types for sharing 274 t = get_template('kmlapp/public.kml') 275 kml = t.render(Context({'loggedin_user': request.user, 'user': request.user, 276 'features': features, 'collections': collections, 'styles': styles, 277 'use_network_links': True, 'request_path': request.path, 278 'session_key': session_key})) 279 280 mime = mimetypes.KML 281 if kmz: 282 mime = mimetypes.KMZ 283 kml = create_kmz(kml, 'mm/doc.kml') 284 response = HttpResponse(kml, mimetype=mime) 285 response['Content-Disposition'] = 'attachment' 286 return response
287