コード例 #1
0
ファイル: story_views.py プロジェクト: MarcBehrens/ScrumDo
def set_story_status( request, group_slug, story_id, status):
    story = get_object_or_404( Story, id=story_id )
    write_access_or_403(story.project,request.user)
    if story.status != status:
        # the status was actually changes
        story.status = status;
        story.save();
        signals.story_status_changed.send( sender=request, story=story, user=request.user )
        # statuses = [None, "TODO", "In Progress", "Reviewing", "Done"]
        # story.activity_signal.send(sender=story, user=request.user, story=story, action="changed status", status=statuses[status], project=story.project)
        onDemandCalculateVelocity( story.project )

    organization = _organizationOrNone( story.project )

    if( request.POST.get("return_type","mini") == "mini"):
        return render_to_response("stories/single_mini_story.html", {
            "story": story,
            "return_type": "mini",
            "project": story.project,
            "organization": organization
          }, context_instance=RequestContext(request))
    if( request.POST.get("return_type","mini") == "queue"):
        return render_to_response("stories/single_queue_story.html", {
            "story": story,
            "return_type": "queue",
            "project": story.project,
            "organization": organization
      }, context_instance=RequestContext(request))
    return render_to_response("stories/single_block_story.html", {
            "story": story,
            "return_type": "block",
            "project": story.project,
            "organization": organization
      }, context_instance=RequestContext(request))
コード例 #2
0
ファイル: story_views.py プロジェクト: vishalvishw10/ScrumDo
def scrum_board(request, group_slug, story_id):
    status_map = {
        "todo": Story.STATUS_TODO,
        "doing": Story.STATUS_DOING,
        "reviewing": Story.STATUS_REVIEWING,
        "done": Story.STATUS_DONE
    }
    story = get_object_or_404(Story, id=story_id)
    project = get_object_or_404(Project, slug=group_slug)
    if request.method == 'POST':
        if request.POST.get("status", None) == None:
            return HttpResponse("FAILED")
        target_status = status_map[request.POST.get("status")]
        reorderStory(story,
                     request.POST.get("before"),
                     request.POST.get("after"),
                     story.iteration,
                     field_name="board_rank")
        if story.status != target_status:
            story.status = target_status
            story.save()
            signals.story_status_changed.send(sender=request,
                                              story=story,
                                              user=request.user)
            onDemandCalculateVelocity(story.project)
        else:
            story.save()
    return HttpResponse("OK")
コード例 #3
0
ファイル: iteration_views.py プロジェクト: kod3r/ScrumDo
def iteration_import(request, group_slug, iteration_id):
    project = get_object_or_404(Project, slug=group_slug)
    iteration = get_object_or_404(Iteration, id=iteration_id)

    if iteration.locked:
        form_class = IterationImportFormWithUnlock
    else:
        form_class = IterationImportForm

    write_access_or_403(project, request.user)
    if request.method == "POST":
        form = form_class(request.POST)
        if form.is_valid():
            unlock = form.cleaned_data.get("unlock_iteration", False)
            if unlock:
                iteration.locked = False
                iteration.save()
            status = import_export.importIteration(iteration, request.FILES["import_file"], request.user)
            onDemandCalculateVelocity(project)
            return HttpResponseRedirect(
                reverse("iteration", kwargs={"group_slug": project.slug, "iteration_id": iteration.id})
            )
    else:
        form = form_class()

    return render_to_response(
        "projects/import_options.html",
        {"project": project, "iteration": iteration, "form": form},
        context_instance=RequestContext(request),
    )
コード例 #4
0
def _handleAddStoryInternal(form, project, request):
    story = form.save(commit=False)
    story.local_id = project.getNextId()
    story.project = project
    story.creator = request.user
    iteration_id = request.POST.get("iteration", None)
    if iteration_id != None:
        iteration = get_object_or_404(Iteration, id=iteration_id)
        if iteration.project != project:
            # Shenanigans!
            raise PermissionDenied()
        story.iteration = iteration
    else:
        story.iteration = project.get_default_iteration()
    story.rank = _calculate_rank(story.iteration,
                                 int(form.cleaned_data['general_rank']))
    logger.info("New Story %s" % story.summary)
    story.save()
    if story.points_value() > 0:
        onDemandCalculateVelocity(project)
    signals.story_created.send(sender=request, story=story, user=request.user)
    story.activity_signal.send(sender=story,
                               user=request.user,
                               story=story,
                               action="created",
                               project=project)
    request.user.message_set.create(message="Story #%d created." %
                                    story.local_id)
    return story
コード例 #5
0
def set_story_status(request, group_slug, story_id, status):
    story = get_object_or_404(Story, id=story_id)
    write_access_or_403(story.project, request.user)
    if story.status != status:
        # the status was actually changes
        story.status = status
        story.save()
        signals.story_status_changed.send(sender=request,
                                          story=story,
                                          user=request.user)
        statuses = [None, "TODO", "In Progress", "Reviewing", "Done"]
        story.activity_signal.send(sender=story,
                                   user=request.user,
                                   story=story,
                                   action="changed status",
                                   status=statuses[status],
                                   project=story.project)
        onDemandCalculateVelocity(story.project)
    if (request.POST.get("return_type", "mini") == "mini"):
        return render_to_response("stories/single_mini_story.html", {
            "story": story,
            "return_type": "mini",
        },
                                  context_instance=RequestContext(request))
    if (request.POST.get("return_type", "mini") == "queue"):
        return render_to_response("stories/single_queue_story.html", {
            "story": story,
            "return_type": "queue",
        },
                                  context_instance=RequestContext(request))
    return render_to_response("stories/single_block_story.html", {
        "story": story,
    },
                              context_instance=RequestContext(request))
コード例 #6
0
ファイル: story_views.py プロジェクト: cgbill/ScrumDo
def _handleAddStoryInternal( form , project, request):
    story = form.save( commit=False )
    story.local_id = project.getNextId()
    story.project = project
    story.creator = request.user
    iteration_id = request.POST.get("iteration",None)
    if iteration_id != None:
        iteration = get_object_or_404(Iteration, id=iteration_id)
        if iteration.project != project:
            # Shenanigans!
            raise PermissionDenied()
        story.iteration = iteration
    else:
        story.iteration = project.get_default_iteration()

    try:
        general_rank = int(form.cleaned_data['general_rank'])
    except:
        general_rank = 2 # bottom
        
    story.rank = _calculate_rank( story.iteration, general_rank )
    logger.info("New Story %s" % story.summary)
    story.save()
    if story.points_value() > 0:
        onDemandCalculateVelocity( project )
    signals.story_created.send( sender=request, story=story, user=request.user )
    story.activity_signal.send(sender=story, user=request.user, story=story, action="created", project=project)
    request.user.message_set.create(message="Story #%d created." % story.local_id )
    return story
コード例 #7
0
def iteration_import(request, group_slug, iteration_id):
    project = get_object_or_404(Project, slug=group_slug)
    iteration = get_object_or_404(Iteration, id=iteration_id)

    if iteration.locked:
        form_class = IterationImportFormWithUnlock
    else:
        form_class = IterationImportForm

    write_access_or_403(project,request.user)
    if request.method == "POST":
        form = form_class(request.POST)
        import_file = request.FILES.get("import_file",None)
        if form.is_valid() and import_file != None:
            unlock = form.cleaned_data.get("unlock_iteration",False)
            if unlock:
                iteration.locked = False
                iteration.save()
            status = import_export.importIteration(iteration, import_file, request.user )
            onDemandCalculateVelocity( project )
        return HttpResponseRedirect( reverse('iteration', kwargs={'group_slug':project.slug, 'iteration_id':iteration.id}) )
    else:
        form = form_class(  )

    return render_to_response('projects/import_options.html', { 'project':project, 'iteration':iteration, 'form': form,  }, context_instance=RequestContext(request))
コード例 #8
0
ファイル: story_views.py プロジェクト: netjackal/ScrumDo
def ajax_add_epic(request, group_slug):
    project = get_object_or_404(Project, slug=group_slug)
    write_access_or_403(project,request.user)
    if request.method == 'POST': # If the form has been submitted...        
        form = EpicForm( project, request.POST)
        if form.is_valid(): # All validation rules pass
            epic = form.save()
            onDemandCalculateVelocity(project)
            return HttpResponse(epic.id)
コード例 #9
0
ファイル: story_views.py プロジェクト: vishalvishw10/ScrumDo
def ajax_add_epic(request, group_slug):
    project = get_object_or_404(Project, slug=group_slug)
    write_access_or_403(project, request.user)
    if request.method == 'POST':  # If the form has been submitted...
        form = EpicForm(project, request.POST)
        if form.is_valid():  # All validation rules pass
            epic = form.save()
            onDemandCalculateVelocity(project)
            return HttpResponse(epic.id)
    return HttpResponse("")
コード例 #10
0
ファイル: story_views.py プロジェクト: paltman/ScrumDo
def story(request, group_slug, story_id):
    story = get_object_or_404( Story, id=story_id )
    project = get_object_or_404( Project, slug=group_slug )
    return_type = request.GET.get("return_type","mini")

    if request.method == 'POST': # If the form has been submitted...
        old_story = story.__dict__.copy()
        write_access_or_403(project,request.user)
        form = StoryForm( project, request.POST, project, instance=story) # A form bound to the POST data

        if form.is_valid(): # All validation rules pass
            story = form.save()
            diffs = utils.model_differences(old_story, story.__dict__, dicts=True)
            activities = 0
            if diffs.has_key("points"):
                story.activity_signal.send(sender=story, user=request.user, story=story, pointschange=True, action="changed point value", project=project, old=diffs['points'][0], new=diffs['points'][1])
                activities = activities + 1
            # to do other stories based on specific changes, simply add more if clauses like the one above

            if len(diffs) > activities:
                # this means that we have not accounted for all the changes above, so add a generic story edited activity
                story.activity_signal.send(sender=story, user=request.user, story=story, action="edited", project=project)

            signals.story_updated.send( sender=request, story=story, user=request.user )
            onDemandCalculateVelocity( project )

        if( request.POST['return_type'] == 'mini'):
            return render_to_response("stories/single_mini_story.html", {
                "story": story,
                "return_type": return_type,
              }, context_instance=RequestContext(request))
        if( request.POST['return_type'] == 'block'):
            return render_to_response("stories/single_block_story.html", {
                "story": story,
                "return_type": return_type,
                "project": story.project
              }, context_instance=RequestContext(request))
        if( request.POST['return_type'] == 'queue'):
            return render_to_response("stories/single_queue_story.html", {
                "story": story,
                "return_type": return_type,
              }, context_instance=RequestContext(request))

    else:
        read_access_or_403(project,request.user)
        form = StoryForm(project, instance=story )

    tags = project.tags.all().order_by("name")
    return   render_to_response("stories/story.html", {
        "story": story,
        "form": form,
        "project": project,
        "tags": tags,
        "return_type": return_type
      }, context_instance=RequestContext(request))
コード例 #11
0
ファイル: story_views.py プロジェクト: cgbill/ScrumDo
def story(request, group_slug, story_id):
    story = get_object_or_404( Story, id=story_id )
    project = get_object_or_404( Project, slug=group_slug )
    return_type = request.GET.get("return_type","mini")

    if request.method == 'POST': # If the form has been submitted...
        old_story = story.__dict__.copy()
        write_access_or_403(project,request.user)
        form = StoryForm( project, request.POST, project, instance=story) # A form bound to the POST data

        if form.is_valid(): # All validation rules pass
            story = form.save()
            diffs = utils.model_differences(old_story, story.__dict__, dicts=True)
            activities = 0
            if diffs.has_key("points"):
                story.activity_signal.send(sender=story, user=request.user, story=story, pointschange=True, action="changed point value", project=project, old=diffs['points'][0], new=diffs['points'][1])
                activities = activities + 1
            # to do other stories based on specific changes, simply add more if clauses like the one above

            if len(diffs) > activities:
                # this means that we have not accounted for all the changes above, so add a generic story edited activity
                story.activity_signal.send(sender=story, user=request.user, story=story, action="edited", project=project)

            signals.story_updated.send( sender=request, story=story, user=request.user )
            onDemandCalculateVelocity( project )

        if( request.POST['return_type'] == 'mini'):
            return render_to_response("stories/single_mini_story.html", {
                "story": story,
                "return_type": return_type,
              }, context_instance=RequestContext(request))
        if( request.POST['return_type'] == 'block'):
            return render_to_response("stories/single_block_story.html", {
                "story": story,
                "return_type": return_type,
                "project": story.project
              }, context_instance=RequestContext(request))
        if( request.POST['return_type'] == 'queue'):
            return render_to_response("stories/single_queue_story.html", {
                "story": story,
                "return_type": return_type,
              }, context_instance=RequestContext(request))

    else:
        read_access_or_403(project,request.user)
        form = StoryForm(project, instance=story )

    tags = project.tags.all().order_by("name")
    return   render_to_response("stories/story.html", {
        "story": story,
        "form": form,
        "project": project,
        "tags": tags,
        "return_type": return_type
      }, context_instance=RequestContext(request))
コード例 #12
0
ファイル: story_views.py プロジェクト: MarcBehrens/ScrumDo
def _handleAddStoryInternal( form , project, request):
    story = form.save( commit=False )
    story.local_id = project.getNextId()
    story.project = project
    story.creator = request.user
    iteration_id = request.POST.get("iteration",None)
    epic_id = request.POST.get("epic",None)

    if iteration_id != None:
        iteration = get_object_or_404(Iteration, id=iteration_id)
        if iteration.project != project:
            raise PermissionDenied() # Shenanigans!
        story.iteration = iteration
    else:
        story.iteration = project.get_default_iteration()

    if epic_id != None and epic_id != "":
        epic = Epic.objects.get(id=epic_id)
        if epic.project != project:
            raise PermissionDenied() # Shenanigans!
        story.epic = epic

    try:
        general_rank = int(form.cleaned_data['general_rank'])
    except:
        general_rank = 2 # bottom



    if request.POST.get("category_name") != "":
        category_name = request.POST.get("category_name","")
        category_name = category_name.replace(",","").strip()
        category_name = category_name[:50]
        if not category_name in project.getCategoryList():            
            project.categories = "%s, %s" % (project.categories, category_name)
            if len(project.categories) <= 1024:
                project.save()
            else:
                request.user.message_set.create(message="Too many categories")                        
        story.category = category_name
        

    story.rank = _calculate_rank( story.iteration, general_rank )
    # logger.info("New Story %s" % story.summary)
    story.save()
    if story.points_value() > 0:
        onDemandCalculateVelocity( project )
    signals.story_created.send( sender=request, story=story, user=request.user )
    # story.activity_signal.send(sender=story, user=request.user, story=story, action="created", project=project)
    request.user.message_set.create(message="Story #%d created." % story.local_id )
    return story
コード例 #13
0
ファイル: story_views.py プロジェクト: vishalvishw10/ScrumDo
def _handleAddStoryInternal(form, project, request):
    story = form.save(commit=False)
    story.local_id = project.getNextId()
    story.project = project
    story.creator = request.user
    iteration_id = request.POST.get("iteration", None)
    epic_id = request.POST.get("epic", None)

    if iteration_id != None:
        iteration = get_object_or_404(Iteration, id=iteration_id)
        if iteration.project != project:
            raise PermissionDenied()  # Shenanigans!
        story.iteration = iteration
    else:
        story.iteration = project.get_default_iteration()

    if epic_id != None and epic_id != "":
        epic = Epic.objects.get(id=epic_id)
        if epic.project != project:
            raise PermissionDenied()  # Shenanigans!
        story.epic = epic

    try:
        general_rank = int(form.cleaned_data['general_rank'])
    except:
        general_rank = 2  # bottom

    if request.POST.get("category_name") != "":
        category_name = request.POST.get("category_name", "")
        category_name = category_name.replace(",", "").strip()
        category_name = category_name[:50]
        if not category_name in project.getCategoryList():
            project.categories = "%s, %s" % (project.categories, category_name)
            if len(project.categories) <= 1024:
                project.save()
            else:
                request.user.message_set.create(message="Too many categories")
        story.category = category_name

    story.rank = _calculate_rank(story.iteration, general_rank)
    # logger.info("New Story %s" % story.summary)
    story.save()
    if story.points_value() > 0:
        onDemandCalculateVelocity(project)
    signals.story_created.send(sender=request, story=story, user=request.user)
    # story.activity_signal.send(sender=story, user=request.user, story=story, action="created", project=project)
    request.user.message_set.create(message="Story #%d created." %
                                    story.local_id)
    return story
コード例 #14
0
ファイル: story_views.py プロジェクト: netjackal/ScrumDo
def scrum_board( request, group_slug, story_id):
    status_map = {"todo":Story.STATUS_TODO, "doing":Story.STATUS_DOING, "reviewing":Story.STATUS_REVIEWING, "done":Story.STATUS_DONE};
    story = get_object_or_404( Story, id=story_id )
    project = get_object_or_404( Project, slug=group_slug )
    if request.method == 'POST':
        target_status = status_map[request.POST.get("status")]
        reorderStory( story, request.POST.get("before"), request.POST.get("after"), story.iteration, field_name="board_rank")
        if story.status != target_status:
            story.status = target_status
            story.save()
            story.activity_signal.send(sender=story, user=request.user, story=story, action="changed status", status=story.statusText(), project=story.project)
            onDemandCalculateVelocity( story.project )
        else:
            story.save()
    return HttpResponse("OK")
コード例 #15
0
ファイル: story_views.py プロジェクト: jacksonh/ScrumDo
def delete_story( request, group_slug, story_id ):
    if request.method == "POST":
        story = get_object_or_404( Story, id=story_id )
        write_access_or_403(story.project,request.user)
        signals.story_deleted.send( sender=request, story=story, user=request.user )
        story.activity_signal.send(sender=story, user=request.user, story=story, action="deleted", project=story.project)
        story.sync_queue.clear()
        story.delete()
        onDemandCalculateVelocity( story.project )

        redirTo = request.GET.get("redirectTo", "")
        if redirTo:
            return HttpResponseRedirect(redirTo );
        else:
            return HttpResponse("OK");
    else:
        return HttpResponse("FAIL");
コード例 #16
0
ファイル: story_views.py プロジェクト: MarcBehrens/ScrumDo
def edit_epic(request,  epic_id):
    epic = get_object_or_404(Epic, id=epic_id)
    project = epic.project
    write_access_or_403(project, request.user)
    
    if request.method == 'POST': # If the form has been submitted...        
        form = EpicForm( project, request.POST, instance=epic)
        if form.is_valid(): # All validation rules pass
            epic = form.save()
            onDemandCalculateVelocity(project)
            return HttpResponse("OK")
    else:
        form = EpicForm( project,  instance=epic)
    
    return render_to_response("projects/epic_edit.html", {
        "form":form,
        "epic":epic,
        "project":project
      }, context_instance=RequestContext(request))
コード例 #17
0
ファイル: story_views.py プロジェクト: vishalvishw10/ScrumDo
def edit_epic(request, epic_id):
    epic = get_object_or_404(Epic, id=epic_id)
    project = epic.project
    write_access_or_403(project, request.user)

    if request.method == 'POST':  # If the form has been submitted...
        form = EpicForm(project, request.POST, instance=epic)
        if form.is_valid():  # All validation rules pass
            epic = form.save()
            onDemandCalculateVelocity(project)
            return HttpResponse("OK")
    else:
        form = EpicForm(project, instance=epic)

    return render_to_response("projects/epic_edit.html", {
        "form": form,
        "epic": epic,
        "project": project
    },
                              context_instance=RequestContext(request))
コード例 #18
0
ファイル: story_views.py プロジェクト: vishalvishw10/ScrumDo
def story_edit(request, group_slug, story_id):
    story = get_object_or_404(Story, id=story_id)
    project = get_object_or_404(Project, slug=group_slug)
    return_type = request.GET.get("return_type", "mini")

    if request.method == 'POST':  # If the form has been submitted...
        old_story = story.__dict__.copy()
        write_access_or_403(project, request.user)
        form = StoryForm(project, request.POST, project,
                         instance=story)  # A form bound to the POST data

        if form.is_valid():  # All validation rules pass
            story = form.save(commit=False)

            if request.POST.get("category_name", "") != "":
                try:
                    category_name = request.POST.get("category_name")
                    category_name = category_name.replace(",", "").strip()
                    category_name = category_name[:50]
                    if not category_name in project.getCategoryList():
                        project.categories = "%s, %s" % (project.categories,
                                                         category_name)
                        if len(project.categories) <= 1024:
                            project.save()
                        else:
                            request.user.message_set.create(
                                message="Too many categories")
                    story.category = category_name
                except:
                    pass  # no category to use

            story.save()

            diffs = utils.model_differences(old_story,
                                            story.__dict__,
                                            dicts=True)
            activities = 0

            signals.story_updated.send(sender=request,
                                       story=story,
                                       diffs=diffs,
                                       user=request.user)
            onDemandCalculateVelocity(project)

        organization = _organizationOrNone(project)
        if (request.POST['return_type'] == 'mini'):
            return render_to_response("stories/single_mini_story.html", {
                "story": story,
                "return_type": return_type,
            },
                                      context_instance=RequestContext(request))
        if (request.POST['return_type'] == 'scrumboard'):
            return render_to_response("stories/single_scrum_board_story.html",
                                      {
                                          "story": story,
                                          "return_type": return_type,
                                          "project": story.project,
                                          "organization": organization
                                      },
                                      context_instance=RequestContext(request))
        if (request.POST['return_type'] == 'block'):
            return render_to_response("stories/single_block_story.html", {
                "story": story,
                "return_type": return_type,
                "project": story.project,
                "organization": organization
            },
                                      context_instance=RequestContext(request))
        if (request.POST['return_type'] == 'queue'):
            return render_to_response("stories/single_queue_story.html", {
                "story": story,
                'project': story.project,
                "organization": organization,
                "return_type": return_type,
            },
                                      context_instance=RequestContext(request))

    else:
        read_access_or_403(project, request.user)
        form = StoryForm(project, instance=story)

    tags = project.unique_tags()

    return render_to_response("stories/story.html", {
        "story": story,
        "form": form,
        "project": project,
        "return_type": return_type
    },
                              context_instance=RequestContext(request))
コード例 #19
0
ファイル: story_views.py プロジェクト: MarcBehrens/ScrumDo
def story_edit(request, group_slug, story_id):
    story = get_object_or_404( Story, id=story_id )
    project = get_object_or_404( Project, slug=group_slug )
    return_type = request.GET.get("return_type","mini")

    if request.method == 'POST': # If the form has been submitted...
        old_story = story.__dict__.copy()
        write_access_or_403(project,request.user)
        form = StoryForm( project, request.POST, project, instance=story) # A form bound to the POST data

        if form.is_valid(): # All validation rules pass
            story = form.save(commit=False)
            

            if request.POST.get("category_name","") != "":
                try:
                    category_name = request.POST.get("category_name")
                    category_name = category_name.replace(",","").strip()
                    category_name = category_name[:50]
                    if not category_name in project.getCategoryList():
                        project.categories = "%s, %s" % (project.categories, category_name)
                        if len(project.categories) <= 1024:
                            project.save()
                        else:
                            request.user.message_set.create(message="Too many categories")
                    story.category = category_name
                except:
                    pass # no category to use
                
            story.save()
            
            diffs = utils.model_differences(old_story, story.__dict__, dicts=True)
            activities = 0

            signals.story_updated.send( sender=request, story=story, diffs=diffs, user=request.user )
            onDemandCalculateVelocity( project )

        organization = _organizationOrNone( project )
        if( request.POST['return_type'] == 'mini'):
            return render_to_response("stories/single_mini_story.html", {
                "story": story,
                "return_type": return_type,
              }, context_instance=RequestContext(request))
        if( request.POST['return_type'] == 'scrumboard'):
            return render_to_response("stories/single_scrum_board_story.html", {
                "story": story,
                "return_type": return_type,
                "project": story.project,
                "organization": organization
              }, context_instance=RequestContext(request))
        if( request.POST['return_type'] == 'block'):
            return render_to_response("stories/single_block_story.html", {
                "story": story,
                "return_type": return_type,
                "project": story.project,
                "organization": organization
              }, context_instance=RequestContext(request))
        if( request.POST['return_type'] == 'queue'):
            return render_to_response("stories/single_queue_story.html", {
                "story": story,
                'project': story.project,
                "organization": organization,
                "return_type": return_type,
              }, context_instance=RequestContext(request))

    else:
        read_access_or_403(project,request.user)
        form = StoryForm(project, instance=story )

    tags = project.unique_tags()

    return   render_to_response("stories/story.html", {
        "story": story,
        "form": form,
        "project": project,
        "return_type": return_type
      }, context_instance=RequestContext(request))
コード例 #20
0
ファイル: story_views.py プロジェクト: netjackal/ScrumDo
def story(request, group_slug, story_id):
    story = get_object_or_404( Story, id=story_id )
    project = get_object_or_404( Project, slug=group_slug )
    return_type = request.GET.get("return_type","mini")

    if request.method == 'POST': # If the form has been submitted...
        old_story = story.__dict__.copy()
        write_access_or_403(project,request.user)
        form = StoryForm( project, request.POST, project, instance=story) # A form bound to the POST data

        if form.is_valid(): # All validation rules pass
            story = form.save(commit=False)
            
            if request.POST.get("category_name") != "":
                category_name = request.POST.get("category_name")
                category_name = category_name.replace(",","").strip()
                category_name = category_name[:25]
                if not category_name in project.getCategoryList():
                    project.categories = "%s, %s" % (project.categories, category_name)
                    if len(project.categories) <= 512:
                        project.save()
                    else:
                        request.user.message_set.create(message="Too many categories")
                        
                    
                story.category = category_name
                
            story.save()
            
            diffs = utils.model_differences(old_story, story.__dict__, dicts=True)
            activities = 0
            if diffs.has_key("points"):
                story.activity_signal.send(sender=story, user=request.user, story=story, pointschange=True, action="changed point value", project=project, old=diffs['points'][0], new=diffs['points'][1])
                activities = activities + 1
            # to do other stories based on specific changes, simply add more if clauses like the one above

            if len(diffs) > activities:
                # this means that we have not accounted for all the changes above, so add a generic story edited activity
                story.activity_signal.send(sender=story, user=request.user, story=story, action="edited", project=project)

            signals.story_updated.send( sender=request, story=story, user=request.user )
            onDemandCalculateVelocity( project )

        organization = _organizationOrNone( project )
        if( request.POST['return_type'] == 'mini'):
            return render_to_response("stories/single_mini_story.html", {
                "story": story,
                "return_type": return_type,
              }, context_instance=RequestContext(request))
        if( request.POST['return_type'] == 'scrumboard'):
            return render_to_response("stories/single_scrum_board_story.html", {
                "story": story,
                "return_type": return_type,
                "project": story.project,
                "organization": organization
              }, context_instance=RequestContext(request))
        if( request.POST['return_type'] == 'block'):
            return render_to_response("stories/single_block_story.html", {
                "story": story,
                "return_type": return_type,
                "project": story.project,
                "organization": organization
              }, context_instance=RequestContext(request))
        if( request.POST['return_type'] == 'queue'):
            return render_to_response("stories/single_queue_story.html", {
                "story": story,
                "return_type": return_type,
              }, context_instance=RequestContext(request))

    else:
        read_access_or_403(project,request.user)
        form = StoryForm(project, instance=story )

    tags = project.unique_tags()

    return   render_to_response("stories/story.html", {
        "story": story,
        "form": form,
        "project": project,
        "return_type": return_type
      }, context_instance=RequestContext(request))