Esempio n. 1
0
File: views.py Progetto: 3taps/geo
def main(request):
    """ Respond to the "/" URL.

        This is the main entry point for the sanity_checker application.  We
        search for "suspicious" locations, and list them as possible problems
        that need fixing.

        Note that, for speed, we bypass the ORM and access the MySQL database
        directly.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    if request.method == "GET":

        # We're displaying the page for the first time.

        pass

    elif request.method == "POST":

        # See if the user clicked on our "Proceed" button.

        if request.POST.get("proceed") != None:
            return HttpResponseRedirect(
                        reverse("sanity_checker.views.check"))

    # Finally, display the page to the user.

    menu_html = menus.generate(request, "Location Sanity-Checker",
                               "sanity_checker", "main")

    return render_to_response("sanity_checker/templates/sanity_check.html",
                              {'menu_html' : menu_html},
                              context_instance=RequestContext(request))
Esempio n. 2
0
File: views.py Progetto: 3taps/geo
def busy(request):
    """ Display the main page when our tableau-calculating daemon is busy.

        We display the status of the daemon, and reload the page on a regular
        basis so the user can see the status as it changes.
    """
    num_to_go = TableauCacheRequest.objects.count()

    if num_to_go == 0:
        # Redirect the user back to the "idle" page.
        return HttpResponseRedirect(reverse("tableau_cache.views.idle"))

    if request.method == "POST":

        # See if the user clicked on our "Cancel" button.

        if request.POST.get("cancel") == "Cancel":

            # Delete the remaining requests, and return to the "idle" view.

            TableauCacheRequest.objects.all().delete()
            return HttpResponseRedirect(reverse("tableau_cache.views.idle"))

    # Finally, display our page to the user.

    menu_html = menus.generate(request, "Tableau Cache",
                               "tableau_cache", "main")

    return render_to_response("tableau_cache/templates/main_busy.html",
                              {'num_to_go' : num_to_go,
                               'menu_html' : menu_html,
                              },
                              context_instance=RequestContext(request))
Esempio n. 3
0
File: main.py Progetto: 3taps/geo
def main(request):
    """ Respond to the "/" URL.

        This is the main entry point for the tableau_editor application.

        We let the user select a location to edit the tableaux for.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    levels = []
    for level in Level.objects.all():
        levels.append(level)

    starred_locs = []
    for loc in Location.objects.filter(starred=True):
        starred_locs.append(loc)

    menu_html = menus.generate(request, "Tableau Editor", "tableau_editor", "main")

    base_url = reverse("tableau_editor.views.select", args=["Z"])[:-2]

    selector_html = location_selector.generate(
        request, "Edit the tableaux for a location", "Tableau Editor", "tableau_editor", "main", base_url
    )

    return render_to_response(
        "tableau_editor/templates/main.html",
        {"menu_html": menu_html, "selector_html": selector_html, "starred_locs": starred_locs, "levels": levels},
        context_instance=RequestContext(request),
    )
Esempio n. 4
0
def create_tableaux_for_location(request, loc_code):
    """ Create the factory-based tableaux for the given location.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    if request.method == "GET":
        # Ask the user to confirm the operation.
        return render_to_response("shared/templates/confirm.html",
                                  {'title'   : "Whenua Admin",
                                   'heading' : "Create Factory Tableaux",
                                   'message' : "Are you sure you want to " +
                                               "create a new set of factory " +
                                               "tableaux for this location?" +
                                               "  If you proceed, the " +
                                               "existing factory tableaux " +
                                               "will be overwritten.",
                                  },
                                  context_instance=RequestContext(request))
    elif request.POST['confirm'] != "1":
        # The user cancelled -> go back to the main tableau editor page.
        return HttpResponseRedirect(reverse("tableau_editor.views.select",
                                            args=[loc_code]))

    # If we get here, we're ready to create the factory tableau for this
    # location.  Load the location object into memory.

    try:
        location = Location.objects.get(code=loc_code)
    except Location.DoesNotExist:
        # Should never happen.
        return HttpResponseRedirect(reverse("tableau_editor.views.select",
                                            args=[loc_code]))

    # Build a list of tableau factories we need to run.

    factories = factory_generator.calc_factories_for_location(location)

    # Create each tableau in turn, keeping track of any errors which occur
    # along the way.

    results = []
    for factory in factories:
        err_msg = factory_generator.create_tableau(factory, location)
        results.append({'factory'  : factory,
                        'location' : location,
                        'err_msg'  : err_msg})

    # Finally, display the results to the caller.

    menu_html = menus.generate(request, "Tableau Editor",
                               "tableau_editor", "create_factory")

    return render_to_response("tableau_editor/templates/" +
                              "create_factory_results.html",
                              {'menu_html' : menu_html,
                               'results'   : results,
                               'loc_code'  : loc_code,
                              },
                              context_instance=RequestContext(request))
Esempio n. 5
0
def create_all_busy(request):
    """ Respond to the "/create_all_busy" URL.

        We display the status of the generation request, along with any
        errors which may have occurred.
    """
    num_to_go = TableauFactoryGenerationRequest.objects.count()

    if num_to_go == 0:
        # Redirect the user back to the "idle" page.
        return HttpResponseRedirect(reverse(
                    "tableau_editor.views.create_factory.create_all_idle"))

    if request.method == "POST":

        # See if the user clicked on our "Cancel" button.

        if request.POST.get("cancel") == "Cancel":

            # Delete the remaining requests, and return to the "idle" view.

            TableauFactoryGenerationRequest.objects.all().delete()
            return HttpResponseRedirect(reverse(
                        "tableau_editor.views.create_factory.create_all_idle"))

        # See if the user clicked on our "Finished" button.

        if request.POST.get("finished") != None:
            return HttpResponseRedirect(
                        reverse("tableau_editor.views.tableau_factories.main"))

    # Finally, display our page to the user.

    menu_html = menus.generate(request, "Tableau Editor",
                               "tableau_editor", "create_all_tableaux")

    errors = []
    for error in TableauFactoryGenerationError.objects.all():
        try:
            factory = TableauFactory.objects.get(id=error.factory_id)
        except TableauFactory.DoesNotExist:
            continue # Should never happen.

        try:
            location = Location.objects.get(code=error.loc_code)
        except Location.DoesNotExist:
            continue # Should never happen.

        errors.append({'factory'  : factory,
                       'location' : location,
                       'err_msg'  : error.err_msg})

    return render_to_response("tableau_editor/templates/create_all_busy.html",
                              {'num_to_go' : num_to_go,
                               'menu_html' : menu_html,
                               'errors'    : errors,
                              },
                              context_instance=RequestContext(request))
Esempio n. 6
0
File: views.py Progetto: 3taps/geo
def import_locations(request):
    """ Respond to the "import" URL.

        We let the user import location data from a tab-delimited text file.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    if request.method == "GET":
        # We're displaying the form for the first time -> set up our default
        # values.
        log = []

    elif request.method == "POST":
        # The user is submitting our form -> see what the user wants to do.

        if request.POST.get("finished") != None:
            # The user clicked on the "Finished" button -> redirect the user
            # back to the main admin page.
            return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

        log = [] # Log of import results.

        # Extract the uploaded file, and save it to a temporary file on disk.

        if 'upload' not in request.FILES:
            log.append("Please select a file to import!")
        else:
            upload_file = request.FILES['upload']

            f = TemporaryFile()
            for chunk in upload_file.chunks():
                chunk = chunk.replace("\r\n", "\n") # Fix weird line endings.
                chunk = chunk.replace("\n\r", "\n") # ditto.
                chunk = chunk.replace("\r",   "\n") # ditto.
                f.write(chunk)
            upload_file.close()
            f.seek(0)

            # Import the locations from the temporary file.

            import_data(f, log)

    menu_html = menus.generate(request, "Location Editor",
                               "import_export", "import_locations")

    return render_to_response("import_export/templates/import.html",
                              {'menu_html' : menu_html,
                               'log'       : log},
                              context_instance=RequestContext(request))
Esempio n. 7
0
File: main.py Progetto: 3taps/geo
def main(request):
    """ Respond to a "/" request.
    
        This is our top-most view.
    """
    is_daemon_running = daemonMonitor.is_daemon_running()

    menu_html = menus.generate(request, "Admin Home",
                               "admin_interface", "main")

    return render_to_response("admin_interface/templates/main.html",
                              {'is_daemon_running' : is_daemon_running,
                               'menu_html'         : menu_html},
                              context_instance=RequestContext(request))
Esempio n. 8
0
File: main.py Progetto: 3taps/geo
def main(request):
    """ Implement the "/" URL.

        This is the main entry point for the location_editor application.

        We let the user select a location to edit, either by typing in the
        desired location name or code, or by selecting the location level to
        start browsing.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    levels = []
    for level in Level.objects.all():
        levels.append(level)

    starred_locs = []
    for loc in Location.objects.filter(starred=True):
        starred_locs.append(loc)

    has_import_export = ("import_export" in settings.INSTALLED_APPS)

    menu_html = menus.generate(request, "Location Editor",
                               "location_editor", "main")

    base_url = reverse("location_editor.views.details", args=["Z"])[:-2]

    selector_html = location_selector.generate(request,
                                               "Select a location to edit",
                                               "Location Editor",
                                               "location_editor", "main",
                                               base_url)

    return render_to_response("location_editor/templates/main.html",
                              {'menu_html'         : menu_html,
                               'selector_html'     : selector_html,
                               'starred_locs'      : starred_locs,
                               'levels'            : levels,
                               'has_import_export' : has_import_export},
                              context_instance=RequestContext(request))
Esempio n. 9
0
File: login.py Progetto: 3taps/geo
def login(request):
    """ Respond to a "/login" URL.

        We let the user log in.
    """
    if request.method == "GET":
        # We're displaying the form for the first time.

        err_msg = None

    elif request.method == "POST":
        # Respond to the user submitting our form.
        if request.POST.get("cancel") == "Cancel":
            return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

        err_msg  = None # initially.
        username = request.POST['username']
        password = request.POST['password']

        user = auth.authenticate(username=request.POST['username'],
                                 password=request.POST['password'])
        if user == None:
            err_msg = "Incorrect username or password."

        if err_msg == None:
            auth.login(request, user)
            return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    # Display the page to the user.

    menu_html = menus.generate(request, "User Login",
                               "admin_interface", "login")

    return render_to_response("admin_interface/templates/login.html",
                              {'menu_html' : menu_html,
                               'err_msg'   : err_msg},
                              context_instance=RequestContext(request))
Esempio n. 10
0
File: main.py Progetto: 3taps/geo
def main(request):
    """Respond to the "/" URL.

        This is the main entry point for the polygon_editor application.

        We display a menu of available options within the polygon builder.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    options = [] # List of (label, url) tuples.

    options.append(("Polygon Builder",
                    reverse("polygon_editor.views.builder.main")))
    options.append(("Polygon Validator",
                    reverse("polygon_editor.views.validator")))

    menu_html = menus.generate(request, "Polygon Editor",
                               "polygon_editor", "main")

    return render_to_response("polygon_editor/templates/main.html",
                              {'menu_html' : menu_html,
                               'options'   : options},
                               context_instance=RequestContext(request))
Esempio n. 11
0
File: names.py Progetto: 3taps/geo
def names(request, loc_code):
    """ Respond to the "/names/XYZ/" URL.

        We let the user edit the names for the given location.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    try:
        location = Location.objects.get(code=loc_code)
    except Location.DoesNotExist:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    loc_names = []
    for loc_name in LocationName.objects.filter(location=location):
        loc_names.append(loc_name)

    imports = []
    imports.append('<link href="' + settings.MEDIA_URL + 'editor.css" ' +
                         'rel="stylesheet" type="text/css">')

    if request.method == "GET":

        # We're displaying the form for the first time.  Process our CGI
        # parameters (if any).

        confirm = request.GET.get("confirm")

    elif request.method == "POST":

        # Respond to the user clicking on one of our buttons.

        # Did the user click on the "Finished" button?

        if request.POST.get("finished") == "Finished":
            return HttpResponseRedirect(
                        reverse("location_editor.views.main"))

        # Did the user click on one of our "Edit" buttons?  We redirect the
        # user to the "Edit" page for the associated location name.

        for loc_name in loc_names:
            editValue = request.POST.get("edit-" + str(loc_name.id))
            if editValue == "Edit":
                return HttpResponseRedirect(
                            reverse("location_editor.views.edit_name",
                                    args=[loc_name.id]))

        # Did the user click on one of our "Delete" buttons?  We firstly
        # display the confirmation button beside the entry, and only delete the
        # entry if the user confirms.

        for loc_name in loc_names:
            deleteValue = request.POST.get("del-" + str(loc_name.id))
            if deleteValue == "Delete":
                # The user clicked on the "Delete" button for the first time ->
                # redisplay the page with the confirmation buttons.
                return HttpResponseRedirect(
                            reverse("location_editor.views.names",
                                    args=[loc_code]) +
                            "?confirm=" + str(loc_name.id))
            elif deleteValue == "Yes":
                # The user clicked on our "Yes" confirmation button.  Remove
                # this location name entry.  If this is the last occurrence of
                # this name, remove the name as well.

                name = loc_name.name
                loc_name.delete()

                if name.locationname_set.count() == 0:
                    name.delete()

                # Redisplay the updated page without the confirmation buttons.

                return HttpResponseRedirect(
                            reverse("location_editor.views.names",
                                    args=[loc_code]))
            elif deleteValue == "No":
                # The user clicked on the "No" confirmation button.  Redisplay
                # the page without the confirmation buttons.
                return HttpResponseRedirect(
                            reverse("location_editor.views.names",
                                    args=[loc_code]))

        # Did the user click on the "Add" button?

        if request.POST.get("add") == "Add Name":
            return HttpResponseRedirect(
                        reverse("location_editor.views.add_name",
                                args=[loc_code]))

        # If we get here, we're going to display the form again.  Grab our
        # "confirm" parameter so the form can display the appropriate
        # confirmation buttons.

        confirm = request.POST.get("confirm")

    # If we get here, display the list of names for this location.

    menu_html = menus.generate(request, "Location Editor",
                               "location_editor", "names")

    return render_to_response("location_editor/templates/wrapper.html",
                              {'menu_html'       : menu_html,
                               'tab'             : "names",
                               'heading'         : "Editing " + str(location),
                               'location'        : location,
                               'template_name'   : "names.html",
                               'extra_head_tags' : imports,
                               'errMsg'          : None,
                               'form'            : None,
                               'confirm'         : confirm,
                               'loc_names'       : loc_names,
                              },
                              context_instance=RequestContext(request))
Esempio n. 12
0
File: add.py Progetto: 3taps/geo
def add(request, level=None):
    """ Respond to the "/add" URL.

        If a level was supplied, we let the user add the location with that
        level.  Otherwise, we let the user choose which level of location to
        add.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    if level == None:
        # The user hasn't chosen a level yet.  Display the "Choose a Level"
        # page.

        levels = []
        for level in Level.objects.all():
            levels.append(level)

        menu_html = menus.generate(request, "Location Editor",
                                   "location_editor", "add")

        return render_to_response("location_editor/templates/" +
                                  "add_select_level.html",
                                  {'menu_html' : menu_html,
                                   'levels'    : levels,
                                   },
                                  context_instance=RequestContext(request))

    # If we get here, we know what level of location to add.  Display the
    # "Add Location" form.

    try:
        level = Level.objects.get(level=level)
    except Level.DoesNotExist:
        return HttpResponseRedirect(reverse("location_editor.views.main"))

    if request.method == "GET":
        form   = LocationDetailsForm()
        errMsg = None
    elif request.method == "POST":
        if request.POST.get("cancel") == "Cancel":
            return HttpResponseRedirect(reverse("location_editor.views.main"))

        form = LocationDetailsForm(request.POST)
        errMsg = None
        if form.is_valid():
            code         = request.POST['code']
            name         = request.POST['name']
            display_name = request.POST['display_name']
            abbreviation = request.POST['abbreviation']
            display_lat  = request.POST['display_point_lat']
            display_long = request.POST['display_point_long']

            if code == "":
                errMsg = "You must enter a code for this location."
            elif name == "":
                errMsg = "You must enter a name for this location."
            elif Location.objects.filter(code=code).count() > 0:
                    errMsg = "There is already a location with that code."
            elif Location.objects.filter(level=level, name=name).count() > 0:
                    errMsg = "There is already a " + level.name.lower() \
                           + " with that name."

            if errMsg == None:
                location = Location()
                location.level         = level
                location.code          = code
                location.name          = name
                location.display_name  = display_name
                location.abbreviation  = abbreviation
                location.min_zoom_lat  = decimal.Decimal("0.00")
                location.min_zoom_long = decimal.Decimal("0.00")
                location.max_zoom_lat  = decimal.Decimal("0.00")
                location.max_zoom_long = decimal.Decimal("0.00")

                if display_lat != "":
                    location.display_lat = decimal.Decimal(display_lat)

                if display_long != "":
                    location.display_long = decimal.Decimal(display_long)

                location.population    = 0
                location.area          = 0
                location.averageIncome = 0
                location.save()

                # Finally, redirect the user to the "details" page for the
                # newly-added location.

                return HttpResponseRedirect(
                            reverse("location_editor.views.details",
                                    args=[location.code]))

    return render_to_response("shared/templates/editForm.html",
                              {'title'   : "Whenua Admin",
                               'heading' : "Add " + level.name,
                               'errMsg'  : errMsg,
                               'form'    : form},
                              context_instance=RequestContext(request))
Esempio n. 13
0
def add_layout(request, tableau_id):
    """ Respond to the /add_layout/NNN/" URL.

        We let the user add a new layout to the given tableau.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    try:
        tableau = Tableau.objects.get(id=tableau_id)
    except Tableau.DoesNotExist:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    if request.method == "GET":

        # We're displaying this form for the first time -> set up our default
        # values.

        width   = 0
        height  = 0
        err_msg = None

    elif request.method == "POST":

        # The user is submitting this form.  See what the user wants to do.

        if request.POST.get("cancel") != None:
            # The user clicked on the "Cancel" button -> redirect the user back
            # to the "Edit" page for this tableau.
            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_tableau",
                                args=[tableau.id]))

        # If we get here, the user is attempting to add a new layout.  Check
        # that the entered size is valid.

        err_msg = None # initially.

        try:
            width = int(request.POST.get("width"))
        except:
            err_msg = "You must enter a valid width, in pixels."

        if err_msg == None:
            try:
                height = int(request.POST.get("height"))
            except:
                err_msg = "You must enter a valid height, in pixels."

        if err_msg == None:
            if width < 10 or width > 2000:
                err_msg = "The width must be between 10 and 2000 pixels."

        if err_msg == None:
            if height < 10 or height > 2000:
                err_msg = "The height must be between 10 and 2000 pixels."

        if err_msg == None:
            if TableauLayout.objects.filter(tableau=tableau,
                                            width=width,
                                            height=height).exists():
                err_msg = "There is already a tableau with that size."

        # If everything is okay, add the new layout.

        if err_msg == None:
            layout = TableauLayout()
            layout.tableau = tableau
            layout.width   = width
            layout.height  = height
            layout.save()

            # Return the user back to the "Edit Tableau" page.

            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_tableau",
                                args=[tableau.id]))

    # Finally, display our page.

    menu_html = menus.generate(request, "Tableau Editor",
                               "tableau_editor", "add_layout")

    return render_to_response("tableau_editor/templates/add_layout.html",
                              {'menu_html' : menu_html,
                               'heading'   : "Add Layout for Tableau '" +
                                             tableau.name + '"',
                               'width'     : width,
                               'height'    : height,
                               'err_msg'   : err_msg,
                              },
                              context_instance=RequestContext(request))
Esempio n. 14
0
def edit_layout(request, layout_id):
    """ Respond to the "/edit_layout/NNN/" URL.

        We let the user edit the given tableau layout.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    try:
        layout = TableauLayout.objects.get(id=layout_id)
    except TableauLayout.DoesNotExist:
        return HttpResponseRedirect(
                    reverse("tableau_editor.views.main"))

    tableau = layout.tableau

    # Load the list of TableauLayoutViewPosition records for this layout into
    # memory, adding new records if they don't already exist.

    positions = []

    anchorX = 10
    anchorY = 10

    views = TableauView.objects.filter(tableau=tableau)
    for view in views.order_by("-ordinal_rank"):
        try:
            position = TableauLayoutViewPosition.objects.get(
                                                tableauLayout=layout,
                                                tableauView=view)
        except TableauLayoutViewPosition.DoesNotExist:
            # Create a new view position record for this view.  Note that we
            # have to set the view's rectangle up to have the aspect ratio of
            # the original view bounds, or else the view will be distorted when
            # it is displayed.

            proj = GlobalMercator()

            min_lat  = float(view.min_lat)
            min_long = float(view.min_long)
            max_lat  = float(view.max_lat)
            max_long = float(view.max_long)

            min_x,min_y = proj.LatLonToMeters(min_lat, min_long)
            max_x,max_y = proj.LatLonToMeters(max_lat, max_long)

            viewWidth  = max_x - min_x
            viewHeight = max_y - min_y

            if viewWidth == 0: viewWidth = 1.0
            if viewHeight == 0: viewHeight = 1.0

            aspectRatio = viewWidth / viewHeight

            boxWidth  = 40
            boxHeight = boxWidth / aspectRatio

            position = TableauLayoutViewPosition()
            position.tableauLayout = layout
            position.tableauView   = view
            position.min_x         = anchorX
            position.min_y         = anchorY
            position.max_x         = anchorX + boxWidth
            position.max_y         = anchorY + boxHeight
            position.save()

            anchorX = anchorX + 20
            if anchorX > layout.width - 10:
                anchorX = 10

            anchorY = anchorY + 20
            if anchorY > layout.height - 10:
                anchorY = 10

        positions.append(position)

    # See what the user wants to do.

    if request.method == "POST":

        if request.POST.get("update_size") != None:
            # The user clicked on the "Update" button to change the layout size
            # -> update the size of the layout.
            new_width = request.POST.get("width")
            if new_width != None:
                try:
                    layout.width = int(new_width)
                except ValueError:
                    pass

            new_height = request.POST.get("height")
            if new_height != None:
                try:
                    layout.height = int(new_height)
                except ValueError:
                    pass

            layout.save()

            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_layout",
                                args=[layout.id]))

        if request.POST.get("fit_contents") != None:
            # The user clicked on the "Resize Layout to Fit Contents" button.
            # Calculate the new size for the layout.
            new_width  = 10
            new_height = 10

            for position in positions:
                max_x = request.POST.get("view_"+str(position.id)+"_max_x")
                max_y = request.POST.get("view_"+str(position.id)+"_max_y")

                if max_x != None and max_y != None:
                    max_x = int(max_x)
                    max_y = int(max_y)

                    if max_x > new_width:
                        new_width = max_x

                    if max_y > new_height:
                        new_height = max_y

            layout.width  = new_width
            layout.height = new_height
            layout.save()

            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_layout",
                                args=[layout.id]))

        if request.POST.get("save") != None:
            # The user clicked on the "Save" button -> save the updated layout.
            for position in positions:
                min_x = request.POST.get("view_"+str(position.id)+"_min_x")
                max_x = request.POST.get("view_"+str(position.id)+"_max_x")
                min_y = request.POST.get("view_"+str(position.id)+"_min_y")
                max_y = request.POST.get("view_"+str(position.id)+"_max_y")

                if (min_x != None and min_y != None and max_x != None
                                                    and max_y != None):
                    position.min_x = int(min_x)
                    position.min_y = int(min_y)
                    position.max_x = int(max_x)
                    position.max_y = int(max_y)
                    position.save()

            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_tableau",
                                args=[tableau.id]))

        if request.POST.get("cancel") != None:
            # The user clicked on the "Cancel" button -> return to the main
            # "Edit Tableau" page.
            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_tableau",
                                args=[tableau.id]))

    # If we get here, we're displaying the form for the first time.  Do so.

    menu_html = menus.generate(request, "Tableau Editor",
                               "tableau_editor", "edit_layout")

    return render_to_response("tableau_editor/templates/edit_layout.html",
                              {'menu_html' : menu_html,
                               'heading'   : "Edit Layout for Tableau '" +
                                             tableau.name + "'",
                               'width'     : layout.width,
                               'height'    : layout.height,
                               'positions' : positions,
                              },
                              context_instance=RequestContext(request))
Esempio n. 15
0
File: views.py Progetto: 3taps/geo
def main(request):
    """ Implement the "/" URL.

        This is the main entry point for the geolocator_api_test application.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    if request.method == "GET":
        # We're displaying the page for the first time -> set up our default
        # values.

        req_type      = "unstructured"
        req_text      = ""
        req_country   = ""
        req_state     = ""
        req_metro     = ""
        req_region    = ""
        req_county    = ""
        req_city      = ""
        req_locality  = ""
        req_zipCode   = ""
        req_latitude  = ""
        req_longitude = ""
        req_source    = ""
        results       = []
        log           = []

    elif request.method == "POST":
        # Respond to the user submitting our form.

        # Extract the submitted request.

        req_type      = request.POST['req_type']
        req_text      = request.POST['req_text']
        req_country   = request.POST['req_country']
        req_state     = request.POST['req_state']
        req_metro     = request.POST['req_metro']
        req_region    = request.POST['req_region']
        req_county    = request.POST['req_county']
        req_city      = request.POST['req_city']
        req_locality  = request.POST['req_locality']
        req_zipCode   = request.POST['req_zipCode']
        req_latitude  = request.POST['req_latitude']
        req_longitude = request.POST['req_longitude']
        req_source    = request.POST['req_source']

        # Build the request to send to the Geolocator API.

        params = {}
        if req_type == "unstructured":
            params['text'] = req_text
        elif req_type == "structured":
            if req_country  != "": params['country']  = req_country
            if req_state    != "": params['state']    = req_state
            if req_metro    != "": params['metro']    = req_metro
            if req_region   != "": params['region']   = req_region
            if req_county   != "": params['county']   = req_county
            if req_city     != "": params['city']     = req_city
            if req_locality != "": params['locality'] = req_locality
            if req_zipCode  != "": params['zipCode']  = req_zipCode
        elif req_type == "coordinate":
            params['lat']  = req_latitude
            params['long'] = req_longitude

        if req_source != "":
            params['source'] = req_source
        params['verbose'] = "1"

        # Send off the request to the Geolocator API.

        code,response = geolocator.geolocate(params)

        if code != 200: # OK.
            log     = [response]
            results = []
        else:
            if "locations" not in response:
                results = []
                log = [repr(response)]
            else:
                results = []
                log = []
                for key,value in sorted(response['locations'][0].items()):
                    if key == "log":
                        log = value
                    else:
                        if isinstance(value, dict):
                            parts = []
                            for field in sorted(value.keys()):
                                parts.append(field + "=" + str(value[field]))
                            value = ", ".join(parts)
                        results.append((key, value))

            for i in range(len(log)):
                log[i] = log[i].replace(" ", "&nbsp;")

    # If we get here, display our form with the supplied parameters.

    menu_html = menus.generate(request, "Gelocator API Test",
                               "geolocator_api_test", "main")

    return render_to_response("geolocator_api_test/templates/testgeo.html",
                              {'menu_html'     : menu_html,
                               'req_type'      : req_type,
                               'req_text'      : req_text,
                               'req_country'   : req_country,
                               'req_state'     : req_state,
                               'req_metro'     : req_metro,
                               'req_region'    : req_region,
                               'req_county'    : req_county,
                               'req_city'      : req_city,
                               'req_locality'  : req_locality,
                               'req_zipCode'   : req_zipCode,
                               'req_latitude'  : req_latitude,
                               'req_longitude' : req_longitude,
                               'req_source'    : req_source,
                               'results'       : results,
                               'log'           : log,
                              },
                              context_instance=RequestContext(request))
Esempio n. 16
0
File: views.py Progetto: 3taps/geo
def main(request):
    """ Respond to a "/" request.

        This is the top-most view for the user_editor application.
    """
    if not request.user.is_superuser:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    users = []
    for user in User.objects.all():
        if not user.is_superuser:
            users.append(user)

    if request.method == "GET":

        # We're displaying the page for the first time.  Process our CGI
        # parameters (if any).

        confirm = request.GET.get("confirm")

    elif request.method == "POST":

        # Respond to the user clicking on one of our buttons.

        # Did the user click on one of our "Edit" buttons?  We redirect the
        # user to the "Edit" page for the associated user.

        for user in users:
            editValue = request.POST.get("edit-" + user.username)
            if editValue == "Edit":
                return HttpResponseRedirect(reverse("user_editor.views.edit",
                                                    args=[source.code]))

        # Did the user click on one of our "Delete" buttons?  We firstly
        # display the confirmation button beside the entry, and only delete the
        # entry if the user confirms.

        for user in users:
            deleteValue = request.POST.get("del-" + user.username)
            if deleteValue == "Delete":
                # The user clicked on the "Delete" button for the first time ->
                # redisplay the page with the confirmation buttons.
                return HttpResponseRedirect(reverse("user_editor.views.main") +
                                            "?confirm="+user.username)
            elif deleteValue == "Yes":
                # The user clicked on our "Yes" confirmation button.  Delete
                # this user.
                user.delete()
                return HttpResponseRedirect(reverse("user_editor.views.main"))
            elif deleteValue == "No":
                # The user clicked on the "No" confirmation button.  Redisplay
                # the page without the confirmation buttons.
                return HttpResponseRedirect(reverse("user_editor.views.main"))

        # Did the user click on the "Add" button?

        if request.POST.get("add") == "Add User":
            return HttpResponseRedirect(reverse("user_editor.views.add"))

        # If we get here, we're going to display the page again.  Grab our
        # "confirm" CGI parameter so the page can display the appropriate
        # confirmation buttons.

        confirm = request.POST.get("confirm")

    # If we get here, display the list of data sources.

    menu_html = menus.generate(request, "User Editor",
                               "user_editor", "main")

    return render_to_response("user_editor/templates/select_user.html",
                              {'menu_html' : menu_html,
                               'users'     : users,
                               'confirm'   : confirm,
                              },
                              context_instance=RequestContext(request))
Esempio n. 17
0
def add_view(request, tableau_id):
    """ Respond to the "/add_view/NNN/" URL.

        We let the user add a new view to the given tableau.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    try:
        tableau = Tableau.objects.get(id=tableau_id)
    except Tableau.DoesNotExist:
        return HttpResponseRedirect(reverse("location_editor.views.main"))

    # See what the user wants to do.

    if request.method == "GET":

        # We're displaying this form for the first time -> set up our default
        # values.

        name    = ""
        err_msg = None

    elif request.method == "POST":

        # The user is submitting this form.  See what the user wants to do.

        if request.POST.get("cancel") != None:
            # The user clicked on the "Cancel" button -> redirect the user back
            # to the "Edit Tableau" page for this tableau.
            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_tableau",
                                args=[tableau.id]))

        # If we get here, the user is attempting to add a new view.  Check that
        # the entered name is valid.

        name    = request.POST.get("name")
        err_msg = None # initially.

        if name == "":
            err_msg = "Please enter a name for this view."

        if TableauView.objects.filter(tableau=tableau, name=name).exists():
            err_msg = "Sorry, there is already a view with that name " \
                    + "for this tableau."

        if err_msg == None:
            # The entered name is valid -> add the view.
            query = TableauView.objects.filter(tableau=tableau)
            rank  = query.aggregate(Max("ordinal_rank"))['ordinal_rank__max']
            if rank == None: rank = 1
            else:            rank = rank + 1

            view = TableauView()
            view.tableau      = tableau
            view.name         = name
            view.ordinal_rank = rank
            view.min_lat      = 0
            view.max_lat      = 0
            view.min_long     = 0
            view.max_long     = 0
            view.save()

            # Return the user back to the main "Edit Tableau" page for this
            # tableau.

            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_tableau",
                                args=[tableau.id]))

    # Finally, display our page.

    menu_html = menus.generate(request, "Tableau Editor",
                               "tableau_editor", "add_view")

    return render_to_response("tableau_editor/templates/add_view.html",
                              {'menu_html' : menu_html,
                               'heading'   : "Add View for Tableau '" +
                                             tableau.name + "'",
                               'name'      : name,
                               'err_msg'   : err_msg,
                              },
                              context_instance=RequestContext(request))
Esempio n. 18
0
File: parents.py Progetto: 3taps/geo
def parents(request, loc_code):
    """ Respond to the "/geo/editor/location/parents/XYZ/" URL.

        We let the user edit the list of parents for the given location.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    try:
        location = Location.objects.get(code=loc_code)
    except Location.DoesNotExist:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    parents = []
    for parent in location.parents.all():
        parents.append(parent)

    if request.method == "GET":

        # We're visiting the page for the first time -> just display it.

        form    = AddLocationForm()
        errMsg  = None
        confirm = request.GET.get("confirm")

    elif request.method == "POST":

        # The user is submitting our form.  See what the user wants to do.

        # Did the user click on the "Finished" button?

        if request.POST.get("finished") == "Finished":
            return HttpResponseRedirect(
                        reverse("location_editor.views.main"))

        # Did the user click on one of our "Delete" buttons?  We firstly
        # display the confirmation button beside the entry, and only delete the
        # entry if the user confirms.

        for parent in location.parents.all():
            deleteValue = request.POST.get("del-" + parent.code)
            if deleteValue == "Delete":
                # The user clicked on the "Delete" button for the first time ->
                # redisplay the page with the confirmation buttons.
                return HttpResponseRedirect(
                            reverse("location_editor.views.parents",
                                    args=[loc_code]) +
                            "?confirm=" + parent.code)
            elif deleteValue == "Yes":
                # The user clicked on our "Yes" confirmation button.  Delete
                # this parent.
                location.parents.remove(parent)
                location.save()

                # Finally, tell the user's web browser to reload the page.

                return HttpResponseRedirect(
                            reverse("location_editor.views.parents",
                                    args=[loc_code]))
            elif deleteValue == "No":
                # The user clicked on the "No" confirmation button.  Redisplay
                # the page without the confirmation buttons.
                return HttpResponseRedirect(
                            reverse("location_editor.views.parents",
                                    args=[loc_code]))

        # Did the user click on the "Add" button?

        if request.POST.get("add") == "Add":
            # Respond to the user adding a new parent.
            form   = AddLocationForm(request.POST)
            errMsg = None
            if form.is_valid():
                new_parent_id = form.cleaned_data['loc_id']

                if new_parent_id == None:
                    errMsg = "Please enter a location"

                if errMsg == None:
                    try:
                        newParent = Location.objects.get(id=new_parent_id)
                    except Location.DoesNotExist:
                        errMsg = "No such location."

                    if errMsg == None:
                        filter = location.parents.filter(id=new_parent_id)
                        if filter.count() > 0:
                            errMsg = "That location is already listed as " \
                                   + "a parent!"

                    if errMsg == None:
                        location.parents.add(newParent)
                        location.save()

                        # Finally, tell the user's web browser to reload the
                        # page.

                        return HttpResponseRedirect(
                                    reverse("location_editor.views.parents",
                                            args=[loc_code]))

        # If we get here, we're going to display the form again.  Grab our
        # "confirm" parameter so the form can display the appropriate
        # confirmation buttons.

        confirm = request.POST.get("confirm")

    # If we get here, display the form to the user.

    imports = ['<script type="text/javascript" ' +
                        'src="'+settings.MEDIA_URL+'jquery-1.2.6.min.js">' +
                        '</script>',
               '<script type="text/javascript" ' +
                        'src="'+settings.MEDIA_URL+'jquery.autocomplete.js">' +
                        '</script>',
               '<link href="'+settings.MEDIA_URL+'jquery.autocomplete.css" ' +
                        'rel="stylesheet" type="text/css">',
               '<link href="'+settings.MEDIA_URL+'editor.css" rel="stylesheet" ' +
                        'type="text/css">',
              ]

    lookup_url = reverse("admin_interface.views.lookup.location")

    menu_html = menus.generate(request, "Location Editor",
                               "location_editor", "parents")

    return render_to_response("location_editor/templates/wrapper.html",
                          {'menu_html'       : menu_html,
                           'tab'             : "parents",
                           'heading'         : "Editing " + str(location),
                           'location'        : location,
                           'template_name'   : "parents.html",
                           'errMsg'          : errMsg,
                           'form'            : form,
                           'parents'         : parents,
                           'confirm'         : confirm,
                           'extra_head_tags' : imports,
                           'lookup_url'      : lookup_url,
                          },
                          context_instance=RequestContext(request))
Esempio n. 19
0
File: select.py Progetto: 3taps/geo
def select(request, loc_code):
    """ Respond to the "select/XYZ/" URL.

        We let the user view the list of tableaux for the given location.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    try:
        location = Location.objects.get(code=loc_code)
    except Location.DoesNotExist:
        return HttpResponseRedirect("tableau_editor.views.main")

    tableaux = []
    for tableau in Tableau.objects.filter(location=location):
        tableaux.append(tableau)

    err_msg = None # initially.

    if request.method == "GET":

        # We're displaying the form for the first time.  Process our CGI
        # parameters (if any).

        confirm = request.GET.get("confirm")

    elif request.method == "POST":

        # Respond to the user clicking on one of our buttons.

        # Did the user click on the "Finished" button?

        if request.POST.get("finished") != None:
            return HttpResponseRedirect(reverse("tableau_editor.views.main"))

        # Did the user click on the "Add Tableau" button?

        if request.POST.get("add") != None:
            return HttpResponseRedirect(
                        reverse("tableau_editor.views.add_tableau",
                                args=[loc_code]))

        # Did the user click on the "Create Factory Tableaux" button?

        if request.POST.get("create_factory") != None:
            return HttpResponseRedirect(
                        reverse("tableau_editor.views.create_factory." +
                                "create_tableaux_for_location",
                                args=[loc_code]))

        # Did the user click on one of our "Edit" buttons?  We redirect the
        # user to the "Edit" page for the associated tableau.

        for tableau in tableaux:
            editValue = request.POST.get("edit-" + str(tableau.id))
            if editValue == "Edit":
                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_tableau",
                                    args=[tableau.id]))

        # Did the user click on one of our "Delete" buttons?  We firstly
        # display the confirmation button beside the entry, and only delete the
        # entry if the user confirms.

        for tableau in tableaux:
            deleteValue = request.POST.get("del-" + str(tableau.id))
            if deleteValue == "Delete":
                # The user clicked on the "Delete" button for the first time.
                # We allow the user to delete a tableau if it doesn't have a
                # name of "DEFAULT".

                if tableau.name.upper() == "DEFAULT":
                    err_msg = "Sorry, you can't delete the default tableau."
                else:
                    # redisplay the page with the confirmation buttons.
                    return HttpResponseRedirect(
                                reverse("tableau_editor.views.select",
                                        args=[loc_code]) +
                                        "?confirm=" + str(tableau.id))
            elif deleteValue == "Yes":
                # The user clicked on our "Yes" confirmation button.  Remove
                # this tableau.

                tableau.delete()

                # Redisplay the updated page without the confirmation buttons.

                return HttpResponseRedirect(
                            reverse("tableau_editor.views.select",
                                    args=[loc_code]))
            elif deleteValue == "No":
                # The user clicked on the "No" confirmation button.  Redisplay
                # the page without the confirmation buttons.
                return HttpResponseRedirect(
                            reverse("tableau_editor.views.select",
                                    args=[loc_code]))

        # If we get here, we're going to display the form again.  Grab our
        # "confirm" parameter so the form can display the appropriate
        # confirmation buttons.

        confirm = request.POST.get("confirm")

    # If we get here, display the list of names for this location.

    menu_html = menus.generate(request, "Tableau Editor",
                               "tableau_editor", "select")

    return render_to_response("tableau_editor/templates/select.html",
                              {'menu_html': menu_html,
                               'heading'  : "Edit Tableau for "+str(location),
                               'errMsg'   : err_msg,
                               'confirm'  : confirm,
                               'tableaux' : tableaux,
                              },
                              context_instance=RequestContext(request))
Esempio n. 20
0
def edit(request, rec_id):
    """ Respond to the "/render_instructions/edit" URL.
    """
    try:
        render = TableauRenderingInstructions.objects.get(id=rec_id)
    except TableauRenderingInstructions.DoesNotExit:
        raise Http404

    if render.type == TableauRenderingInstructions.TYPE_TABLEAU:
        type = "tableau"
    elif render.type == TableauRenderingInstructions.TYPE_VIEW:
        type = "view"
    elif render.type == TableauRenderingInstructions.TYPE_LOCATION:
        type = "location"
    elif render.type == TableauRenderingInstructions.TYPE_BUBBLE:
        type = "bubble"
    else:
        type = None

    # See what the user wants to do, if anything.

    if request.method == "GET":

        # We're displaying the form for the first time -> nothing to do.

        err_msg = None

    elif request.method == "POST":

        err_msg = None # initially.

        # See if the user wants to save their changes.

        if request.POST.get("ok") != None:

            # Extract the entered values from our CGI parameters.

            render.name           = request.POST.get("name")
            render.border_size    = float(request.POST.get("border_size"))
            render.border_color   = request.POST.get("border_color")
            render.border_opacity = float(request.POST.get("border_opacity"))
            render.fill_color     = request.POST.get("fill_color")
            render.fill_opacity   = float(request.POST.get("fill_opacity"))

            # Check that the entered name is valid.

            if render.name == "":
                err_msg = "You must enter a name."
            else:
                is_dup = False # initially.
                for aRender in TableauRenderingInstructions.objects.filter(
                                            name=render.name):
                    if aRender.id != render.id:
                        is_dup = True
                        break

                if is_dup:
                    err_msg = "That name is already in use."

            if err_msg == None:
                # Save the changed values, and redirect the user back to the
                # "list" view for this type of rendering instruction.

                render.save()

                return HttpResponseRedirect(
                        reverse("tableau_editor.views.render_instructions.list",
                                args=[type]))

        # See if the user clicked on the "Cancel" button.

        if request.POST.get("cancel") != None:

            # Go back to the "list" view for this type of rendering
            # instruction.

            return HttpResponseRedirect(
                       reverse("tableau_editor.views.render_instructions.list",
                               args=[type]))

    # If we get here, we're going to display the page.  Do so.

    menu_html = menus.generate(request, "Tableau Editor",
                               "tableau_editor", "render_instructions.edit")

    return render_to_response("tableau_editor/templates/render_edit.html",
                              {'menu_html'      : menu_html,
                               'type'           : type,
                               'render'         : render,
                               'preview_width'  : 200,
                               'preview_height' : 100,
                               'err_msg'        : err_msg},
                               context_instance=RequestContext(request))
Esempio n. 21
0
def add_filter(request, view_id):
    """ Respond to the "/add_filter/NNN/" URL.

        We let the user add a new filter to the given tableau view.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    try:
        view = TableauView.objects.get(id=view_id)
    except TableauView.DoesNotExist:
        return HttpResponseRedirect(reverse("location_editor.views.main"))

    # See what the user wants to do.

    if request.method == "POST":
        # The user is submitting the form.  See what the user wants to do.

        if request.POST.get("cancel") != None:
            # The user clicked on the "Cancel" button -> redirect the user back
            # to the "Edit View" page for this view.
            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_view",
                                args=[view.id]))

        # If we get here, the user wants to add a new view filter.

        type = request.POST.get("type")

        filter = TableauViewFilter()
        filter.tableauView = view

        if type == "cur_loc":
            filter.type  = TableauViewFilter.TYPE_CUR_LOCATION
            filter.value = ""
        elif type == "level":
            filter.type  = TableauViewFilter.TYPE_LEVEL
            filter.value = ""
        elif type == "location":
            filter.type  = TableauViewFilter.TYPE_LOCATION
            filter.value = ""
        elif type == "parents":
            filter.type  = TableauViewFilter.TYPE_RELATION
            filter.value = "parent"
        elif type == "children":
            filter.type  = TableauViewFilter.TYPE_RELATION
            filter.value = "child"
        elif type == "neighbors":
            filter.type  = TableauViewFilter.TYPE_RELATION
            filter.value = "neighbor"
        elif type == "peers":
            filter.type  = TableauViewFilter.TYPE_RELATION
            filter.value = "peer"
        else:
            filter.type  = TableauViewFilter.TYPE_LEVEL
            filter.value = ""
        
        filter.save()   

        return HttpResponseRedirect(
                    reverse("tableau_editor.views.edit_view",
                            args=[view.id]))

    # If we get here, we're displaying the form for the first time -> do so.

    cur_loc = view.tableau.location

    menu_html = menus.generate(request, "Tableau Editor",
                               "tableau_editor", "add_filter")

    return render_to_response("tableau_editor/templates/add_view_filter.html",
                              {'menu_html' : menu_html,
                               'heading'   : "Add Filter for Tableau View '" +
                                             view.name + "'",
                               'cur_loc'   : cur_loc,
                              },
                              context_instance=RequestContext(request))
Esempio n. 22
0
File: preview.py Progetto: 3taps/geo
def preview(request):
    """ Respond to the "/preview/" URL.

        We preview the tableau for the given location.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    if request.method == "GET":
        loc_code     = request.GET.get("location")
        tableau_name = request.GET.get("tableau")
    elif request.method == "POST":
        loc_code     = request.POST.get("location")
        tableau_name = request.POST.get("tableau")

        if request.POST.get("finished") != None:
            # Redirect the user back to the main "edit tableau" page.

            try:
                tableau = Tableau.objects.get(location__code=loc_code,
                                              name=tableau_name)
            except Tableau.DoesNotExist:
                return HttpResponseRedirect(
                            reverse("location_editor.views.tableaux",
                                    args=[loc_code]))

            return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_tableau",
                                    args=[tableau.id]))

    # Prepare the tableau to display.

    max_width  = 800
    max_height = 600

    try:
        tableau = Tableau.objects.get(location__code=loc_code,
                                      name=tableau_name)
    except Tableau.DoesNotExist:
        return HttpResponseRedirect(
                    reverse("location_editor.views.tableaux",
                            args=[loc_code]))

    layout              = tableau.tableaulayout_set.all()[0]
    layout_aspect_ratio = float(layout.width) / float(layout.height)

    if max_width / layout_aspect_ratio > max_height:
        height = max_height
        width  = int(height * layout_aspect_ratio)
    else:
        width  = max_width
        height = int(width / layout_aspect_ratio)

    generated_tableau = tableauGenerator.generate_tableau(tableau,
                                                          width, height)

    shapes = []

    # Add a rectangle to show the tableau's bounds.

    render = generated_tableau['render']

    shapes.append({'type'        : "RECTANGLE",
                   'x'           : 0,
                   'y'           : 0,
                   'width'       : width,
                   'height'      : height,
                   'fillColour'  : render.get('fill_color',     "none"),
                   'fillOpacity' : render.get('fill_opacity',   1.0),
                   'lineColour'  : render.get('border_color',   "none"),
                   'lineSize'    : render.get('border_size',    0.0),
                   'lineOpacity' : render.get('border_opacity', 1.0),
                  })

    # Process the tableau's views.

    for view in generated_tableau['views']:

        # Draw the view's outline.

        render = view['render']

        shapes.append({'type'        : "RECTANGLE",
                       'x'           : view['min_x'],
                       'y'           : view['min_y'],
                       'width'       : view['max_x'] - view['min_x'] + 1,
                       'height'      : view['max_y'] - view['min_y'] + 1,
                       'fillColour'  : render.get('fill_color',     "none"),
                       'fillOpacity' : render.get('fill_opacity',   1.0),
                       'lineColour'  : render.get('border_color',   "none"),
                       'lineSize'    : render.get('border_size',    0.0),
                       'lineOpacity' : render.get('border_opacity', 1.0),
                       })

        # Draw the view's location polygons.

        for location in view['locations']:
            render = location['render']
            for polygon in location['polygons']:
                exterior = []
                for x,y in polygon['exterior']:
                    exterior.append([x, y])
                shapes.append(
                      {'type'        : "POLYGON",
                       'exterior'    : exterior,
                       'fillColour'  : render.get('fill_color',     "none"),
                       'fillOpacity' : render.get('fill_opacity',   1.0),
                       'lineColour'  : render.get('border_color',   "none"),
                       'lineSize'    : render.get('border_size',    0.0),
                       'lineOpacity' : render.get('border_opacity', 1.0),
                      })

    # Display the generated web page.

    menu_html = menus.generate(request, "Tableau Editor",
                               "tableau_editor", "preview")

    return render_to_response("tableau_editor/templates/preview.html",
                              {'menu_html'    : menu_html,
                               'heading'      : "Previewing tableau '" +
                                                tableau_name + "'",
                               'loc_code'     : loc_code,
                               'tableau_name' : tableau_name,
                               'width'        : width,
                               'height'       : height,
                               'shapes'       : shapes,
                              },
                              context_instance=RequestContext(request))
Esempio n. 23
0
def list(request, type):
    """ Respond to the "/render_instructions/list/<TYPE>" URL.

        We let the user view the list of tableau rendering instructions for the
        given type of element.
    """
    if not request.user.is_superuser:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    # See if we've been given a valid "type" parameter.  If not, reload the
    # page with type="tableau".

    if type == "tableau":
        type_num = TableauRenderingInstructions.TYPE_TABLEAU
    elif type == "view":
        type_num = TableauRenderingInstructions.TYPE_VIEW
    elif type == "location":
        type_num = TableauRenderingInstructions.TYPE_LOCATION
    elif type == "bubble":
        type_num = TableauRenderingInstructions.TYPE_BUBBLE
    else:
        return HttpResponseRedirect(
                  reverse("tableau_editor.views.render_instructions.list") +
                  "tableau/")

    # Load the list of current tableau rendering instructions of the given type
    # into memory.

    renders = []
    for render in TableauRenderingInstructions.objects.filter(type=type_num):
        renders.append(render)

    # See what the user wants to do.

    if request.method == "GET":

        # We're displaying the form for the first time.  Process our CGI
        # parameters (if any).

        confirm = request.GET.get("confirm")
        err_msg = None

    elif request.method == "POST":

        confirm = request.POST.get("confirm")
        err_msg = None # initially.

        # If the user clicked on the "Finished" button, redirect the user back
        # to the main admin page.

        if request.POST.get("finished") != None:
            return HttpResponseRedirect(reverse("tableau_editor.views.main"))

        # See if the user clicked on the "Add" button.

        if request.POST.get("add") != None:
            new_name = request.POST.get("name")
            name_ok  = True # initially.

            if new_name in [None, ""]:
                err_msg = "Please enter a name."
                name_ok = False

            if name_ok:
                for render in renders:
                    if new_name.upper() == render.name.upper():
                        err_msg = "That name is already in use."
                        name_ok = False
                        break

            if name_ok:
                # Create a new set of tableau rendering instructions for this
                # name.

                render = TableauRenderingInstructions()
                render.type = type_num
                render.name = new_name

                if len(renders) == 0:
                    # Make the first set of rendering instructions the default.
                    render.default = True
                else:
                    render.default = False

                render.border_size    = 0
                render.border_color   = "000000" # black.
                render.border_opacity = 1.0
                render.fill_color     = "ffffff" # white.
                render.fill_opacity   = 1.0
                render.save()

                # Reload the page so that the newly-created location shows up.

                return HttpResponseRedirect(
                           reverse("tableau_editor.views." +
                                   "render_instructions.list",
                                   args=[type]))

        # If the user clicked on one of our "Edit" buttons, redirect the user
        # to the "Edit Rendering Instruction" page.

        for render in renders:
            if request.POST.get("edit-" + str(render.id)) != None:
                return HttpResponseRedirect(
                           reverse("tableau_editor.views." +
                                   "render_instructions.edit",
                                   args=[render.id]))

        # If the user clicked on one of our "Delete" buttons, we firstly
        # display the confirmation button beside the instructions, and only
        # delete the instructions if the user confirms.

        for render in renders:
            deleteValue = request.POST.get("del-" + str(render.id))
            if deleteValue == "Delete":
                # Prevent the user from deleting the default rendering
                # instructions.
                if render.default:
                    err_msg = "You can't delete the default " \
                            + "set of rendering instructions."
                else:
                    # Show the confirmation button.
                    return HttpResponseRedirect(
                               reverse("tableau_editor.views." +
                                       "render_instructions.list",
                                       args=[type]) +
                               "?confirm=" + str(render.id))
            elif deleteValue == "Yes":
                # Delete this set of rendering instructions.

                render.delete()

                # Reload the page to show the updated list of rendering
                # instructions.

                return HttpResponseRedirect(
                           reverse("tableau_editor.views." +
                                   "render_instructions.list",
                                   args=[type]))

        # If the user clicked on one of our "Set Default" buttons, change the
        # default template.

        for render in renders:
            if request.POST.get("default-" + str(render.id)) != None:
                for r in renders:
                    if r.default:
                        r.default = False
                        r.save()

                render.default = True
                render.save()

                # Reload the page to show the updated list of rendering
                # instructions.

                return HttpResponseRedirect(
                           reverse("tableau_editor.views." +
                                   "render_instructions.list",
                                   args=[type]))

    # Finally, display the generated web page.

    menu_html = menus.generate(request, "Tableau Editor",
                               "tableau_editor", "render_instructions.list")

    return render_to_response("tableau_editor/templates/render_list.html",
                              {'menu_html' : menu_html,
                               'heading'   : "Tableau Rendering Instructions",
                               'type'      : type,
                               'renders'   : renders,
                               'confirm'   : confirm,
                               'err_msg'   : err_msg},
                               context_instance=RequestContext(request))
Esempio n. 24
0
File: views.py Progetto: 3taps/geo
def fix_disowned(request):
    """ Respond to the "/fixdisowned" URL.

        We fix any "disowned" locations -- locations where the parent/child,
        child/parent, or neighbour/neighbour relations aren't symmetrical.

        In particular:

          * If a location has a parent which doesn't list the locaiton as a
            child, a child entry will be added to the parent.

          * If a location has a child which doesn't list the location as a
            parent, a parent entry will be added to the child.

          * If a location has a neighbour which doesn't list the location as a
            neighbour, a neighbour entry will be added to the neighbour.
    """
    # Display a "please wait" message while we work.

    if not pleasewait.shown(request):
        return pleasewait.message(request,
                                  "Whenua Admin",
                                  "Location Sanity-Checker",
                                  "Fixing disowned locations, please wait...")

    # Get a connection to our database.

    cursor = connections['geo_shared'].cursor()

    # Load the list of Level records into memory.

    levelIDToNumber = {} # Maps Level record ID to level number.

    for level in Level.objects.all():
        levelIDToNumber[level.id] = level.level

    # Load the list of Location records into memory.

    locations = {} # Maps record ID to a (code, level_num, name, display_name)
                   # tuple.
    
    cursor.execute("SELECT id,code,level_id,name,display_name " +
                   "FROM shared_location")
    row = cursor.fetchone()
    while row != None:
        id,code,level_id,name,display_name = row

        level_num = levelIDToNumber[level_id]
        locations[id] = (code, level_num, name, display_name)

        row = cursor.fetchone()

    # Load the list of location parents into memory.

    location_parents = {} # Maps record ID to a set of parent record IDs.

    cursor.execute("SELECT from_location_id,to_location_id " +
                   "FROM shared_location_parents")
    row = cursor.fetchone()
    while row != None:
        from_loc_id,to_loc_id = row

        try:
            location_parents[from_loc_id].add(to_loc_id)
        except KeyError:
            location_parents[from_loc_id] = set([to_loc_id])

        row = cursor.fetchone()

    # Load the list of location children into memory.

    location_children = {} # Maps record ID to set of child record IDs.

    cursor.execute("SELECT from_location_id,to_location_id " +
                   "FROM shared_location_children")
    row = cursor.fetchone()
    while row != None:
        from_loc_id,to_loc_id = row

        try:
            location_children[from_loc_id].add(to_loc_id)
        except KeyError:
            location_children[from_loc_id] = set([to_loc_id])

        row = cursor.fetchone()

    # Load the list of location neighbours into memory.

    location_neighbours = {} # Maps record ID to set of neighbour record IDs.

    cursor.execute("SELECT from_location_id,to_location_id " +
                   "FROM shared_location_neighbors")
    row = cursor.fetchone()
    while row != None:
        from_loc_id,to_loc_id = row

        try:
            location_neighbours[from_loc_id].add(to_loc_id)
        except KeyError:
            location_neighbours[from_loc_id] = set([to_loc_id])

        row = cursor.fetchone()

    # Fix any locations which have been "disowned" by their parents.  That is,
    # location A lists location B as a parent, but location B doesn't list
    # location A as a child.

    num_parents_fixed = 0
    for loc_id in locations.keys():
        if loc_id not in location_parents: continue # No parents.

        for parent_id in location_parents[loc_id]:
            disowned = False
            if parent_id not in location_children:
                disowned = True
            elif loc_id not in location_children[parent_id]:
                disowned = True

            if disowned:
                location = Location.objects.get(id=loc_id)
                parent   = Location.objects.get(id=parent_id)
                parent.children.add(location)
                num_parents_fixed = num_parents_fixed + 1

    # Fix any locations which have been "disowned" by their children.  That is,
    # location A lists location B as a child, but location B doesn't list
    # location A as a parent.

    num_children_fixed = 0
    for loc_id in locations.keys():
        if loc_id not in location_children: continue # No children.

        for child_id in location_children[loc_id]:
            disowned = False
            if child_id not in location_parents:
                disowned = True
            elif loc_id not in location_parents[child_id]:
                disowned = True

            if disowned:
                location = Location.objects.get(id=loc_id)
                child    = Location.objects.get(id=child_id)
                child.parents.add(location)
                num_children_fixed = num_children_fixed + 1

    # Fix any locations which are "disowned" by their neighbours.  That is,
    # location A lists location B as a neighbour, but location B doesn't list
    # location A as a neighbour.

    num_neighbours_fixed = 0
    for loc_id in locations.keys():
        if loc_id not in location_neighbours: continue # No neighbours.

        for neighbour_id in location_neighbours[loc_id]:
            disowned = False
            if neighbour_id not in location_neighbours:
                disowned = True
            elif loc_id not in location_neighbours[neighbour_id]:
                disowned = True

            if disowned:
                location  = Location.objects.get(id=loc_id)
                neighbour = Location.objects.get(id=neighbour_id)
                neighbour.neighbors.add(location)
                num_neighbours_fixed = num_neighbours_fixed + 1

    # Finally, tell the user the results.

    admin_home_url = reverse(settings.ADMIN_HOME_VIEW)
    menu_html      = menus.generate(request, "sanity_checker", "main")

    return render_to_response("sanity_checker/templates/disowned_fixed.html",
                              {'menu_html'            : menu_html,
                               'num_parents_fixed'    : num_parents_fixed,
                               'num_children_fixed'   : num_children_fixed,
                               'num_neighbours_fixed' : num_neighbours_fixed,
                               'admin_home_url'       : admin_home_url},
                              context_instance=RequestContext(request))
Esempio n. 25
0
def add_tableau(request, loc_code):
    """ Respond to the "/add_tableau/XYZ" URL.

        We let the user add a new tableau to the given location.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    try:
        location = Location.objects.get(code=loc_code)
    except Location.DoesNotExist:
        return HttpResponseRedirect(reverse("location_editor.views.main"))

    if request.method == "GET":

        # We're displaying this form for the first time -> set up our default
        # values.

        name    = ""
        err_msg = None

    elif request.method == "POST":

        # The user is submitting this form.  See what the user wants to do.

        if request.POST.get("cancel") != None:
            # The user clicked on the "Cancel" button -> redirect the user back
            # to the main tableau page for this location.
            return HttpResponseRedirect(
                        reverse("tableau_editor.views.select",
                                args=[location.code]))

        # If we get here, the user is attempting to add a new tableau.  Check
        # that the entered name is valid.

        name    = request.POST.get("name")
        err_msg = None # initially.

        if Tableau.objects.filter(location=location, name=name).exists():
            err_msg = "Sorry, there is already a tableau with that name " \
                    + "for this location."

        if err_msg == None:
            # The entered name is valid -> add the tableau.
            tableau = Tableau()
            tableau.location  = location
            tableau.name      = name
            tableau.meta_data = "{}"
            tableau.save()

            # Return the user back to the main list of tableaux for this
            # location.

            return HttpResponseRedirect(
                        reverse("tableau_editor.views.select",
                                args=[location.code]))

    # Finally, display our page.

    menu_html = menus.generate(request, "Tableau Editor",
                               "tableau_editor", "add_tableau")

    return render_to_response("tableau_editor/templates/add_tableau.html",
                              {'menu_html' : menu_html,
                               'heading'   : "Add Tableau for "+str(location),
                               'name'      : name,
                               'err_msg'   : err_msg,
                              },
                              context_instance=RequestContext(request))
Esempio n. 26
0
File: views.py Progetto: 3taps/geo
def check(request):
    """ Respond to the "/check" URL.

        We display a "please wait" message while performing the sanity check,
        and then finally display the results back to the caller.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    # Display a "please wait" message while waiting for the results to be
    # calculated.

    if not pleasewait.shown(request):
        return pleasewait.message(request,
                                  "Whenua Admin",
                                  "Location Sanity-Checker",
                                  "Checking locations, please wait...")

    # Get a connection to our database.

    cursor = connections['geo_shared'].cursor()

    # Load the list of Level records into memory.

    levelIDToNumber   = {} # Maps Level record ID to level number.
    levelNumberToName = {} # Maps Level number to name.

    for level in Level.objects.all():
        levelIDToNumber[level.id]      = level.level
        levelNumberToName[level.level] = level.name

    # Load the list of Location records into memory.

    locations = {} # Maps record ID to a (code, level_num, name, display_name)
                   # tuple.

    cursor.execute("SELECT id,code,level_id,name,display_name " +
                   "FROM shared_location")
    row = cursor.fetchone()
    while row != None:
        id,code,level_id,name,display_name = row

        level_num = levelIDToNumber[level_id]
        locations[id] = (code, level_num, name, display_name)

        row = cursor.fetchone()

    # Load the list of location parents into memory.

    location_parents = {} # Maps record ID to a set of parent record IDs.

    cursor.execute("SELECT from_location_id,to_location_id " +
                   "FROM shared_location_parents")
    row = cursor.fetchone()
    while row != None:
        from_loc_id,to_loc_id = row

        try:
            location_parents[from_loc_id].add(to_loc_id)
        except KeyError:
            location_parents[from_loc_id] = set([to_loc_id])

        row = cursor.fetchone()

    # Load the list of location children into memory.

    location_children = {} # Maps record ID to set of child record IDs.

    cursor.execute("SELECT from_location_id,to_location_id " +
                   "FROM shared_location_children")
    row = cursor.fetchone()
    while row != None:
        from_loc_id,to_loc_id = row

        try:
            location_children[from_loc_id].add(to_loc_id)
        except KeyError:
            location_children[from_loc_id] = set([to_loc_id])

        row = cursor.fetchone()

    # Load the list of location neighbours into memory.

    location_neighbours = {} # Maps record ID to set of neighbour record IDs.

    cursor.execute("SELECT from_location_id,to_location_id " +
                   "FROM shared_location_neighbors")
    row = cursor.fetchone()
    while row != None:
        from_loc_id,to_loc_id = row

        try:
            location_neighbours[from_loc_id].add(to_loc_id)
        except KeyError:
            location_neighbours[from_loc_id] = set([to_loc_id])

        row = cursor.fetchone()

    # Load the list of names into memory.

    names = {} # Maps record ID to name.

    cursor.execute("SELECT id,name FROM shared_name")
    row = cursor.fetchone()
    while row != None:
        id,name = row

        names[id] = name

        row = cursor.fetchone()

    # Load the list of names used by each location into memory.

    location_names = {} # Maps location record ID to set of name record IDs.

    cursor.execute("select location_id,name_id FROM shared_locationname")
    row = cursor.fetchone()
    while row != None:
        loc_id,name_id = row

        try:
            location_names[loc_id].add(name_id)
        except KeyError:
            location_names[loc_id] = set([name_id])

        row = cursor.fetchone()

    # Now that we've got all the information we need in memory, start looking
    # for potentially bad locations.

    bad_locs = [] # List of potentially bad locations.  Each list item is a
                  # dictionary with the following entries:
                  #
                  #     'code'
                  #
                  #         The location's code.
                  #
                  #     'level'
                  #
                  #         A descriptive name for this location's level
                  #
                  #     'name'
                  #
                  #         The name for this location.
                  #
                  #     'problem'
                  #
                  #         A string describing what was wrong with the
                  #         location.

    # Find any locations that aren't countries and lack parents.

    for loc_id in locations.keys():
        level_num = locations[loc_id][1]
        if level_num == 1: continue # ignore countries.

        if len(location_parents.get(loc_id, [])) == 0:
            # This location has no parents -> flag it as a bad location.
            code,level_num,name,display_name = locations[loc_id]
            bad_locs.append({'code'    : code,
                             'level'   : levelNumberToName[level_num],
                             'name'    : name,
                             'problem' : "lacks a parent"})

    # Find any locations which lack a name.

    for loc_id in locations.keys():
        level_num = locations[loc_id][1]
        if level_num == 8: continue # ZIP codes don't have names.

        if len(location_names.get(loc_id, [])) == 0:
            # This location has no name -> flag it as a bad location.
            code,level_num,name,display_name = locations[loc_id]
            bad_locs.append({'code'    : code,
                             'level'   : levelNumberToName[level_num],
                             'name'    : name,
                             'problem' : "has no names"})

    # Find any locations which have names ending or starting with a space.

    bad_name_ids = set() # Set of name IDs which have bad values.
    for name_id,name in names.items():
        badName = False
        if name.startswith(" "): badName = True
        if name.endswith(" "): badName = True

        if badName:
            bad_name_ids.add(name_id)

    for loc_id,name_ids_for_loc in location_names.items():
        for bad_name_id in name_ids_for_loc.intersection(bad_name_ids):
            code,level_num,name,display_name = locations[loc_id]
            bad_name = names[bad_name_id]
            bad_locs.append({'code'    : code,
                             'level'   : levelNumberToName[level_num],
                             'name'    : name,
                             'problem' : "has a name (" + bad_name + ") " +
                                         "starting or ending with a space"})

    # Find any locations which have been "disowned" by their parents.  That is,
    # location A lists location B as a parent, but location B doesn't list
    # location A as a child.

    for loc_id in locations.keys():
        if loc_id not in location_parents: continue # No parents.

        for parent_id in location_parents[loc_id]:
            disowned = False
            if parent_id not in location_children:
                disowned = True
            elif loc_id not in location_children[parent_id]:
                disowned = True

            if disowned:
                code,level_num,name,display_name = locations[loc_id]
                parent_code = locations[parent_id][0]
                parent_name = locations[parent_id][2]

                bad_locs.append({'code'    : code,
                                 'level'   : levelNumberToName[level_num],
                                 'name'    : name,
                                 'problem' : "has been disowned by parent " +
                                             parent_name+" ("+parent_code+")",
                                })

    # Find any locations which have been "disowned" by their children.  That
    # is, location A lists location B as a child, but location B doesn't list
    # location A as a parent.

    for loc_id in locations.keys():
        if loc_id not in location_children: continue # No children.

        for child_id in location_children[loc_id]:
            disowned = False
            if child_id not in location_parents:
                disowned = True
            elif loc_id not in location_parents[child_id]:
                disowned = True

            if disowned:
                code,level_num,name,display_name = locations[loc_id]
                child_code = locations[child_id][0]
                child_name = locations[child_id][2]

                bad_locs.append({'code'    : code,
                                 'level'   : levelNumberToName[level_num],
                                 'name'    : name,
                                 'problem' : "has been disowned by child " +
                                             child_name+" ("+child_code+")",
                                })

    # Find any locations which are "disowned" by their neighbours.  That is,
    # location A lists location B as a neighbour, but location B doesn't list
    # location A as a neighbour.

    for loc_id in locations.keys():
        if loc_id not in location_neighbours: continue # No neighbours.

        for neighbour_id in location_neighbours[loc_id]:
            disowned = False
            if neighbour_id not in location_neighbours:
                disowned = True
            elif loc_id not in location_neighbours[neighbour_id]:
                disowned = True

            if disowned:
                code,level_num,name,display_name = locations[loc_id]
                neighbour_code = locations[neighbour_id][0]
                neighbour_name = locations[neighbour_id][2]

                bad_locs.append({'code'    : code,
                                 'level'   : levelNumberToName[level_num],
                                 'name'    : name,
                                 'problem' : "has been disowned by neighbor " +
                                             neighbour_name +
                                             " (" + neighbour_code + ")",
                                })

    # Find any locations which lack a default tableau.

    cursor.execute("SELECT id FROM shared_location WHERE NOT EXISTS (" +
                   "SELECT * FROM shared_tableau WHERE shared_location.id=" +
                   "shared_tableau.location_id AND shared_tableau.name=" +
                   '"DEFAULT")')
    row = cursor.fetchone()
    while row != None:
        loc_id = row[0]
        code,level_num,name,display_name = locations[loc_id]
        bad_locs.append({'code'    : code,
                         'level'   : levelNumberToName[level_num],
                         'name'    : name,
                         'problem' : "is missing a default tableau"})
        row = cursor.fetchone()

    # Finally, display the potentially-bad locations to the user.

    admin_home_url = reverse(settings.ADMIN_HOME_VIEW)
    menu_html      = menus.generate(request, "sanity_checker", "main")

    return render_to_response("sanity_checker/templates/results.html",
                              {'menu_html'      : menu_html,
                               'bad_locs'       : bad_locs,
                               'admin_home_url' : admin_home_url},
                              context_instance=RequestContext(request))
Esempio n. 27
0
def create_all_idle(request):
    """ Respond to the "/create_all_idle" URL.

        We display the accumulated errors, if any, and give the user the chance
        to start generating all the factory tableaux.
    """
    num_to_go = TableauFactoryGenerationRequest.objects.count()

    if request.method == "GET":

        pass # We're displaying the page for the first time -> nothing to do.

    elif request.method == "POST":

        # If the user clicked on our "Finished" button, go back to the main
        # tableau factory page.

        if request.POST.get("finished") != None:
            return HttpResponseRedirect(
                        reverse("tableau_editor.views.tableau_factories.main"))

        # If the user clicked on our "Create all Factory Tableaux" button,
        # start generating the requests.

        if request.POST.get("create_all_tableaux") != None:

                # Add entries to the tableau factory generation request queue
                # to create the requested factory tableaux.

                _queue_requests()

                # Clear the previous list of errors.

                _clear_errors()

                # Redirect the user to the "busy" page so we can see the
                # ongoing progress of the tableau creation.

                return HttpResponseRedirect(reverse(
                        "tableau_editor.views.create_factory.create_all_busy"))

    # Finally, display our page to the user.

    menu_html = menus.generate(request, "Tableau Editor",
                               "tableau_editor", "create_all_tableaux")

    errors = []
    for error in TableauFactoryGenerationError.objects.all():
        try:
            factory = TableauFactory.objects.get(id=error.factory_id)
        except TableauFactory.DoesNotExist:
            continue # Should never happen.

        try:
            location = Location.objects.get(code=error.loc_code)
        except Location.DoesNotExist:
            continue # Should never happen.

        errors.append({'factory'  : factory,
                       'location' : location,
                       'err_msg'  : error.err_msg})

    return render_to_response("tableau_editor/templates/create_all_idle.html",
                              {'num_to_go' : num_to_go,
                               'menu_html' : menu_html,
                               'errors'    : errors,
                              },
                              context_instance=RequestContext(request))
Esempio n. 28
0
File: outline.py Progetto: 3taps/geo
def outline(request, loc_code):
    """ Respond to the "/outline/XYZ/" URL.

        We let the user edit the outline for the given location.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    try:
        location = Location.objects.get(code=loc_code)
    except Location.DoesNotExist:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    try:
        outline = Outline.objects.get(location=location)
    except Outline.DoesNotExist:
        outline = Outline()
        outline.location = location
        outline.save()

    formType = getMapForm()

    if request.method == "GET":

        # We're visiting the page for the first time -> just display it.

        wkt = outline.outline
        form = formType({'geometry' : wkt})

    elif request.method == "POST":

        # The user is submitting our form.  If the user clicked on the
        # "Finished" button, redirect the user back to the main location editor
        # page.

        if request.POST.get("finished") == "Finished":
            return HttpResponseRedirect(
                        reverse("location_editor.views.main"))

        # Save the updated outline back into the database.

        form = formType(request.POST)
        try:
            if form.is_valid():
                wkt = form.cleaned_data['geometry']
                outline.outline = wkt
                outline.save()

                # Finally, tell the user's web browser to reload the page.

                return HttpResponseRedirect(
                            reverse("location_editor.views.outline",
                                    args=[loc_code]))
        except ValueError:
            pass

    # If we get here, display the form.

    imports = []
    imports.append('<script src="http://openlayers.org/api/OpenLayers.js">')
    imports.append('</script>')

    menu_html = menus.generate(request, "Location Editor",
                               "location_editor", "outline")

    return render_to_response("location_editor/templates/wrapper.html",
                              {'menu_html'       : menu_html,
                               'tab'             : "outline",
                               'heading'         : "Editing " + str(location),
                               'location'        : location,
                               'template_name'   : "outline.html",
                               'extra_head_tags' : imports,
                               'errMsg'          : None,
                               'form'            : form,
                              },
                              context_instance=RequestContext(request))
Esempio n. 29
0
def edit_view(request, view_id):
    """ Respond to the "/edit_view/NNN/" URL.

        We let the user edit the given tableau view.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    try:
        view = TableauView.objects.get(id=view_id)
    except TableauView.DoesNotExist:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    tableau = view.tableau

    filters = []
    for filter in TableauViewFilter.objects.filter(tableauView=view):
        filters.append(filter)

    try:
        meta_data_dict = eval(view.meta_data)
    except:
        meta_data_dict = {}

    meta_data = []
    for key,value in sorted(meta_data_dict.items()):
        meta_data.append({'key'   : key,
                          'value' : value})

    if view.bounds_render == None:
        cur_render = None
    else:
        cur_render = view.bounds_render.name

    all_renders = []
    for render in TableauRenderingInstructions.objects.filter(
                            type=TableauRenderingInstructions.TYPE_VIEW):
        all_renders.append(render.name)

    # See what the user wants to do.

    if request.method == "GET":

        # We're displaying the form for the first time.  Process our CGI
        # parameters (if any).

        err_msg        = None
        confirm_filter = request.GET.get("confirm_filter")

    elif request.method == "POST":

        err_msg        = None # initially.
        confirm_filter = request.POST.get("confirm_filter")

        # If the user clicked on the "Finished" button, redirect the user back
        # to the "Edit Tableau" page for this tableau.

        if request.POST.get("finished") != None:
            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_tableau",
                                args=[tableau.id]))

        # If the user clicked on the "Update Name" button, update the view's
        # name.

        if request.POST.get("update-name") != None:
            name = request.POST.get("name")

            if name.upper() != view.name.upper():
                if TableauView.objects.filter(tableau=tableau,
                                              name=name).exists():
                    err_msg = "That name is already used by another " \
                            + " view within this tableau."

                if err_msg == None:
                    view.name = name
                    view.save()
                    return HttpResponseRedirect(
                                reverse("tableau_editor.views.edit_view",
                                        args=[view.id]))

        # If the user clicked on the "Reset Bounds" button, reset the view's
        # bounds to the location's display bounds.

        if request.POST.get("reset_bounds") != None:
            view.min_lat  = tableau.location.min_zoom_lat
            view.max_lat  = tableau.location.max_zoom_lat
            view.min_long = tableau.location.min_zoom_long
            view.max_long = tableau.location.max_zoom_long
            view.save()

            updateViewPositions(view)

            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_view",
                                args=[view.id]))

        # If the user dragged out a new view bounds, update the view's bounds
        # and redisplay the page.

        if request.POST.get("set_bounds") == "yes":
            # Store the updated bounds into the TableauView record.  Note that
            # we have to convert the coordinates from meters to lat/long values
            # before saving them.

            min_x = float(request.POST['min_x'])
            min_y = float(request.POST['min_y'])
            max_x = float(request.POST['max_x'])
            max_y = float(request.POST['max_y'])

            proj = GlobalMercator()

            min_lat,min_long = proj.MetersToLatLon(min_x, min_y)
            max_lat,max_long = proj.MetersToLatLon(max_x, max_y)

            view.min_lat  = "%0.4f" % min_lat
            view.min_long = "%0.4f" % min_long
            view.max_lat  = "%0.4f" % max_lat
            view.max_long = "%0.4f" % max_long
            view.save()

            updateViewPositions(view)

            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_view",
                                args=[view.id]))

        # If the user clicked on the "Add Filter" button, redirect the user to
        # the "Add Tableau View Filter" page.

        if request.POST.get("add-filter") != None:
            return HttpResponseRedirect(
                        reverse("tableau_editor.views.add_filter",
                                args=[view.id]))

        # If the user clicked on the "Edit" button for a filter, display the
        # "Edit Tableau View Filter" page for the clicked-on filter.

        for filter in filters:
            if request.POST.get("edit-filter-" + str(filter.id)) == "Edit":
                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_filter",
                                    args=[filter.id]))

        # If the user clicked on the "Delete" button for a filter, firstly
        # display the confirmation button beside the filter, and only delete
        # the filter if the user confirms.

        for filter in filters:
            deleteValue = request.POST.get("del-filter-" + str(filter.id))
            if deleteValue == "Delete":
                # Show the confirmation button.
                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_view",
                                    args=[view.id]) +
                            "?confirm_filter="+str(filter.id))
            elif deleteValue == "Yes":
                # Delete this filter.
                filter.delete()
                # Redisplay the page without the confirmation buttons.
                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_view",
                                    args=[view.id]))

        # If the user clicked on the "Add Meta-Data" button, add the entered
        # key and value (if any) to the view's meta-data.

        if request.POST.get("add-meta") != None:
            key = request.POST.get("meta-data-key-new")
            value = request.POST.get("meta-data-value-new")

            if key not in ["", None] and value not in ["", None]:
                # Add the entered key and value to the tableau's meta-data.
                try:
                    meta_data_dict = eval(view.meta_data)
                except:
                    meta_data_dict = {}

                meta_data_dict[key] = value

                view.meta_data = repr(meta_data_dict)
                view.save()

            # Redisplay the page with the updated meta-data.

            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_view",
                                args=[view.id]))

        # If the user clicked on the "Update Meta-Data" button, update the
        # associated meta-data value.

        for i in range(len(meta_data)):
            if request.POST.get("update-meta-" + str(i)) != None:
                key   = request.POST.get("meta-data-key-" + str(i))
                value = request.POST.get("meta-data-value-" + str(i))

                if key not in ["", None] and value not in ["", None]:
                    # Store the updated key and value into the view's
                    # meta-data.
                    try:
                        meta_data_dict = eval(view.meta_data)
                    except:
                        meta_data_dict = {}

                    del meta_data_dict[meta_data[i]['key']]
                    meta_data_dict[key] = value

                    view.meta_data = repr(meta_data_dict)
                    view.save()

                # Redisplay the page with the updated meta-data.

                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_view",
                                    args=[view.id]))

        # If the user clicked on the "Remove Meta-Data" button, remove the
        # associated meta-data value.

        for i in range(len(meta_data)):
            if request.POST.get("del-meta-" + str(i)) != None:
                try:
                    meta_data_dict = eval(view.meta_data)
                except:
                    meta_data_dict = {}

                del meta_data_dict[meta_data[i]['key']]

                view.meta_data = repr(meta_data_dict)
                view.save()

                # Redisplay the page with the updated meta-data.

                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_view",
                                    args=[view.id]))

        # If the user clicked on the "Set" button beside a rendering
        # instruction, set the view's current rendering instruction.

        for render_name in all_renders:
            if request.POST.get("render-" + render_name) != None:
                try:
                    render = TableauRenderingInstructions.objects.get(
                                type=TableauRenderingInstructions.TYPE_VIEW,
                                name=render_name)
                except TableauRenderingInstructions.DoesNotExist:
                    render = None

                view.bounds_render = render
                view.save()

                # Redisplay the page with the updated rendering instruction.

                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_view",
                                    args=[view.id]))

        # If the user clicked on the "Set" button for the default rendering
        # instruction, set the view to use the default.

        if request.POST.get("render-") != None:
            view.bounds_render = None
            view.save()

            # Redisplay the page with the updated rendering instruction.

            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_view",
                                args=[view.id]))

    # If we get here, we're going to display the page.  Calculate the
    # information we need to display the bounding box map.

    try:
        outline = Outline.objects.get(location=tableau.location)
    except Outline.DoesNotExist:
        outline = None

    if outline != None:
        # Convert the outline to WKT format, reprojecting it into Spherical
        # Mercator projection so we can display it on the map.
        ogrGeom = outline.outline.ogr
        ogrGeom.transform(900913)
        wkt = ogrGeom.wkt
    else:
        wkt = None

    if outline != None and outline.outline != None:
        min_long,min_lat,max_long,max_lat = outline.outline.extent
    else:
        if view.min_long != None:
            min_long = float(view.min_long)
        else:
            min_long = 0

        if view.min_lat != None:
            min_lat = float(view.min_lat)
        else:
            min_lat = 0

        if view.max_long != None:
            max_long = float(view.max_long)
        else:
            max_long = 0

        if view.max_lat != None:
            max_lat = float(view.max_lat)
        else:
            max_lat = 0

    if min_lat < MIN_ALLOWED_LATITUDE:
        min_lat = MIN_ALLOWED_LATITUDE
    elif min_lat > MAX_ALLOWED_LATITUDE:
        min_lat = MAX_ALLOWED_LATITUDE

    if max_lat < MIN_ALLOWED_LATITUDE:
        max_lat = MIN_ALLOWED_LATITUDE
    elif max_lat > MAX_ALLOWED_LATITUDE:
        max_lat = MAX_ALLOWED_LATITUDE

    proj = GlobalMercator()

    origin_lat  = float(min_lat + max_lat) / 2
    origin_long = float(min_long + max_long) / 2

    origin_x,origin_y = proj.LatLonToMeters(origin_lat, origin_long)

    mLeft,mBottom = proj.LatLonToMeters(min_lat, min_long)
    mRight,mTop   = proj.LatLonToMeters(max_lat, max_long)

    starting_zoom_level = None
    for zoom in range(MAX_ZOOM_LEVEL, -1, -1):
        pLeft,pBottom = proj.MetersToPixels(mLeft, mBottom, zoom)
        pRight, pTop  = proj.MetersToPixels(mRight, mTop, zoom)

        pixel_width = pRight - pLeft
        pixel_height = pTop - pBottom

        if pixel_width <= MAP_WIDTH and pixel_height <= MAP_HEIGHT:
            # We've reached a zoom level that fits the entire bounds onto
            # the map -> this is our desired starting zoom level.
            starting_zoom_level = zoom
            break

    if view.min_long != None and view.min_lat != None and \
       view.max_long != None and view.max_lat != None:
        has_bounds    = True

        bounds_left   = float(view.min_long)
        bounds_right  = float(view.max_long)
        bounds_bottom = float(view.min_lat)
        bounds_top    = float(view.max_lat)

        mBounds_left,mBounds_bottom = proj.LatLonToMeters(bounds_bottom,
                                                          bounds_left)
        mBounds_right,mBounds_top   = proj.LatLonToMeters(bounds_top,
                                                          bounds_right)
    else:
        has_bounds = False

    # Finally, display our web page.

    menu_html = menus.generate(request, "Tableau Editor",
                               "tableau_editor", "edit_view")

    return render_to_response("tableau_editor/templates/edit_view.html",
                              {'menu_html'           : menu_html,
                               'heading'             : "Edit View for " +
                                                       "Tableau '" +
                                                       tableau.name + "'",
                               'name'                : view.name,
                               'err_msg'             : err_msg,
                               'map_width'           : MAP_WIDTH,
                               'map_height'          : MAP_HEIGHT,
                               'wkt'                 : wkt,
                               'has_bounds'          : has_bounds,
                               'mBounds_left'        : mBounds_left,
                               'mBounds_bottom'      : mBounds_bottom,
                               'mBounds_right'       : mBounds_right,
                               'mBounds_top'         : mBounds_top,
                               'origin_x'            : origin_x,
                               'origin_y'            : origin_y,
                               'starting_zoom_level' : starting_zoom_level,
                               'filters'             : filters,
                               'meta_data'           : meta_data,
                               'meta_data_new'       : {'key'   : "",
                                                        'value' : ""},
                               'cur_render'          : cur_render,
                               'all_renders'         : all_renders,
                               'confirm_filter'      : confirm_filter,
                              },
                              context_instance=RequestContext(request))
Esempio n. 30
0
def edit_tableau(request, tableau_id):
    """ Respond to the "/edit_tableau/NN" URL.

        We let the user edit the Tableau record with the given ID.
    """
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse(settings.ADMIN_HOME_VIEW))

    try:
        tableau = Tableau.objects.get(id=tableau_id)
    except Tableau.DoesNotExist:
        return HttpResponseRedirect(
                    reverse("location_editor.views.main"))

    location = tableau.location

    views = []
    for view in TableauView.objects.filter(tableau=tableau).order_by(
                                                            "ordinal_rank"):
        views.append(view)

    layouts = []
    for layout in TableauLayout.objects.filter(tableau=tableau).order_by(
                                                            "width", "height"):
        layouts.append(layout)

    try:
        meta_data_dict = eval(tableau.meta_data)
    except:
        meta_data_dict = {}

    meta_data = []
    for key,value in sorted(meta_data_dict.items()):
        meta_data.append({'key'   : key,
                          'value' : value})

    if tableau.bounds_render == None:
        cur_render = None
    else:
        cur_render = tableau.bounds_render.name

    all_renders = []
    for render in TableauRenderingInstructions.objects.filter(
                            type=TableauRenderingInstructions.TYPE_TABLEAU):
        all_renders.append(render.name)

    # See what the user wants to do.

    if request.method == "GET":

        # We're displaying the form for the first time.  Process our CGI
        # parameters (if any).

        err_msg        = None
        confirm_view   = request.GET.get("confirm_view")
        confirm_layout = request.GET.get("confirm_layout")

    elif request.method == "POST":

        err_msg        = None # initially.
        confirm_view   = request.POST.get("confirm_view")
        confirm_layout = request.POST.get("confirm_layout")

        # If the user clicked on the "Finished" button, redirect the user back
        # to the main tableau page for this location.

        if request.POST.get("finished") != None:
            return HttpResponseRedirect(
                        reverse("tableau_editor.views.select",
                                args=[location.code]))

        # If the user clicked on the "Preview" button, redirect the user to the
        # "preview tableau" page for this location and tableau name.

        if request.POST.get("preview") != None:
            return HttpResponseRedirect(
                        reverse("tableau_editor.views.preview") +
                        "?location=" + location.code +
                        "&tableau=" + tableau.name)

        # If the user clicked on the "Update Name" button, update the tableau's
        # name.

        if request.POST.get("update-name") != None:
            name = request.POST.get("name")

            if name.upper() != tableau.name.upper():
                if tableau.name.upper() == "DEFAULT":
                    err_msg = "Sorry, you can't change the name of the " \
                            + "default tableau."

                if err_msg == None:
                    if Tableau.objects.filter(location=location,
                                              name=name).exists():
                        err_msg = "That name is already used by another " \
                                + " tableau for this location."

                if err_msg == None:
                    tableau.name = name
                    tableau.save()
                    return HttpResponseRedirect(
                                reverse("tableau_editor.views.edit_tableau",
                                        args=[tableau.id]))

        # If the user clicked on the "Add View" button, redirect the user to
        # the "Add Tableau View" page.

        if request.POST.get("add-view") != None:
            return HttpResponseRedirect(
                        reverse("tableau_editor.views.add_view",
                                args=[tableau.id]))

        # If the user clicked on the "Edit" button for a view, display the
        # "Edit Tableau View" page for the clicked-on view.

        for view in views:
            if request.POST.get("edit-view-" + str(view.id)) == "Edit":
                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_view",
                                    args=[view.id]))

        # If the user clicked on the "Delete" button for a view, firstly
        # display the confirmation button beside the view, and only delete the
        # view if the user confirms.

        for view in views:
            deleteValue = request.POST.get("del-view-" + str(view.id))
            if deleteValue == "Delete":
                # Show the confirmation button.
                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_tableau",
                                    args=[tableau.id]) +
                            "?confirm_view=" + str(view.id))
            elif deleteValue == "Yes":
                # Delete this view.
                view.delete()
                # Redisplay the page without the confirmation buttons.
                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_tableau",
                                    args=[tableau.id]))

        # If the user clicked on the "Move Forward" button for a view, update
        # the ordinal rankings for the tableau's views as appropriate.

        for viewNum,view in enumerate(views):
            if request.POST.get("move-view-forward-" + str(view.id)) != None:
                # Move the given view forward by swapping ordinal rankings.

                if viewNum > 0:
                    otherView = views[viewNum-1]

                    rank1 = otherView.ordinal_rank
                    rank2 = view.ordinal_rank

                    view.ordinal_rank = rank1
                    view.save()

                    otherView.ordinal_rank = rank2
                    otherView.save()

                # Redisplay the page.

                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_tableau",
                                    args=[tableau.id]))

        # If the user clicked on the "Move Backward" button for a view, update
        # the ordinal rankings for the tableau's views as appropriate.

        for viewNum,view in enumerate(views):
            if request.POST.get("move-view-backward-" + str(view.id)) != None:
                # Move the given view forward by swapping ordinal rankings.

                if viewNum < len(views)-1:
                    otherView = views[viewNum+1]

                    rank1 = view.ordinal_rank
                    rank2 = otherView.ordinal_rank

                    view.ordinal_rank = rank2
                    view.save()

                    otherView.ordinal_rank = rank1
                    otherView.save()

                # Redisplay the page.

                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_tableau",
                                    args=[tableau.id]))

        # If the user clicked on the "Add Layout" button, redirect the user to
        # the "Add Tableau Layout" page.

        if request.POST.get("add-layout") != None:
            return HttpResponseRedirect(
                        reverse("tableau_editor.views.add_layout",
                                args=[tableau.id]))

        # If the user clicked on the "Edit" button for a layout, display the
        # "Edit Tableau Layout" page for the clicked-on layout.

        for layout in layouts:
            if request.POST.get("edit-layout-" + str(layout.id)) == "Edit":
                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_layout",
                                    args=[layout.id]))

        # If the user clicked on the "Delete" button for a layout, firstly
        # display the confirmation button beside the layout, and only delete
        # the layout if the user confirms.

        for layout in layouts:
            deleteValue = request.POST.get("del-layout-" + str(layout.id))
            if deleteValue == "Delete":
                # Show the confirmation button.
                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_tableau",
                                    args=[tableau.id]) +
                            "?confirm_layout="+str(layout.id))
            elif deleteValue == "Yes":
                # Delete this layout.
                layout.delete()
                # Redisplay the page without the confirmation buttons.
                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_tableau",
                                    args=[tableau.id]))

        # If the user clicked on the "Add Meta-Data" button, add the entered
        # key and value (if any) to the tableau's meta-data.

        if request.POST.get("add-meta") != None:
            key = request.POST.get("meta-data-key-new")
            value = request.POST.get("meta-data-value-new")

            if key not in ["", None] and value not in ["", None]:
                # Add the entered key and value to the tableau's meta-data.
                try:
                    meta_data_dict = eval(tableau.meta_data)
                except:
                    meta_data_dict = {}

                meta_data_dict[key] = value

                tableau.meta_data = repr(meta_data_dict)
                tableau.save()

            # Redisplay the page with the updated meta-data.

            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_tableau",
                                args=[tableau.id]))

        # If the user clicked on the "Update Meta-Data" button, update the
        # associated meta-data value.

        for i in range(len(meta_data)):
            if request.POST.get("update-meta-" + str(i)) != None:
                key   = request.POST.get("meta-data-key-" + str(i))
                value = request.POST.get("meta-data-value-" + str(i))

                if key not in ["", None] and value not in ["", None]:
                    # Store the updated key and value into the tableau's
                    # meta-data.
                    try:
                        meta_data_dict = eval(tableau.meta_data)
                    except:
                        meta_data_dict = {}

                    del meta_data_dict[meta_data[i]['key']]
                    meta_data_dict[key] = value

                    tableau.meta_data = repr(meta_data_dict)
                    tableau.save()

                # Redisplay the page with the updated meta-data.

                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_tableau",
                                    args=[tableau.id]))

        # If the user clicked on the "Remove Meta-Data" button, remove the
        # associated meta-data value.

        for i in range(len(meta_data)):
            if request.POST.get("del-meta-" + str(i)) != None:
                try:
                    meta_data_dict = eval(tableau.meta_data)
                except:
                    meta_data_dict = {}

                del meta_data_dict[meta_data[i]['key']]

                tableau.meta_data = repr(meta_data_dict)
                tableau.save()

                # Redisplay the page with the updated meta-data.

                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_tableau",
                                    args=[tableau.id]))

        # If the user clicked on the "Set" button beside a rendering
        # instruction, set the template's current rendering instruction.

        for render_name in all_renders:
            if request.POST.get("render-" + render_name) != None:
                try:
                    render = TableauRenderingInstructions.objects.get(
                                type=TableauRenderingInstructions.TYPE_TABLEAU,
                                name=render_name)
                except TableauRenderingInstructions.DoesNotExist:
                    render = None

                tableau.bounds_render = render
                tableau.save()

                # Redisplay the page with the updated rendering instruction.

                return HttpResponseRedirect(
                            reverse("tableau_editor.views.edit_tableau",
                                    args=[tableau.id]))

        # If the user clicked on the "Set" button for the default rendering
        # instruction, set the template to use the default.

        if request.POST.get("render-") != None:
            tableau.bounds_render = None
            tableau.save()

            # Redisplay the page with the updated rendering instruction.

            return HttpResponseRedirect(
                        reverse("tableau_editor.views.edit_tableau",
                                args=[tableau.id]))

    # If we get here, display our page with the tableau's details.

    menu_html = menus.generate(request, "Tableau Editor",
                               "tableau_editor", "edit_tableau")

    return render_to_response("tableau_editor/templates/edit_tableau.html",
                              {'menu_html'      : menu_html,
                               'heading'        : "Edit Tableau for " +
                                                  str(location),
                               'name'           : tableau.name,
                               'err_msg'        : err_msg,
                               'views'          : views,
                               'layouts'        : layouts,
                               'meta_data'      : meta_data,
                               'meta_data_new'  : {'key'   : "",
                                                   'value' : ""},
                               'cur_render'     : cur_render,
                               'all_renders'    : all_renders,
                               'confirm_view'   : confirm_view,
                               'confirm_layout' : confirm_layout,
                              },
                              context_instance=RequestContext(request))