Beispiel #1
0
// Edit_sharing
func Edit_sharing(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "GET" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("pkey")
	shr := strings.Split(pkey, "::")
	owner := shr[0]
	project_name := shr[1]

	if strings.ToLower(owner) != strings.ToLower(user.String()) {
		msg := "Only the owner of a project can manage sharing."
		return_msg := "Return to dashboard"
		Message_page(w, r, user, msg, return_msg, "/dashboard")
		return
	}

	shared_users, err := Get_shared_users(pkey, &c)
	if err != nil {
		shared_users = make([]string, 0)
		c.Infof("Failed to retrieve sharing: %v %v", project_name, owner)
	}

	type TV struct {
		User           string
		LoggedIn       bool
		SharedUsers    []string
		AnySharedUsers bool
		ProjectName    string
		Pkey           string
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.SharedUsers = shared_users
	template_values.AnySharedUsers = len(shared_users) > 0
	template_values.ProjectName = project_name
	template_values.Pkey = pkey

	tmpl, err := template.ParseFiles("header.html",
		"edit_sharing.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "edit_sharing.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
// Create_project_step2 asks if the subject-level data are to be logged.
func Create_project_step2(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)

	if err := r.ParseForm(); err != nil {
		ServeError(&c, w, err)
		return
	}

	user := user.Current(c)
	project_name := r.FormValue("project_name")

	// Check if the project name has already been used.
	pkey := user.String() + "::" + project_name
	key := datastore.NewKey(c, "EncodedProject", pkey, 0, nil)
	var pr EncodedProject
	err := datastore.Get(c, key, &pr)
	if err == nil {
		msg := fmt.Sprintf("A project named \"%s\" belonging to user %s already exists.", project_name, user.String())
		return_msg := "Return to dashboard"
		Message_page(w, r, user, msg, return_msg, "/dashboard")
		return
	}

	type TV struct {
		User     string
		LoggedIn bool
		Name     string
		Pkey     string
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.Name = r.FormValue("project_name")

	tmpl, err := template.ParseFiles("header.html",
		"create_project_step2.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "create_project_step2.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
// Create_project_step1 gets the project name from the user.
func Delete_project_step1(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "GET" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)

	_, projlist, err := GetProjects(user.String(), false, &c)
	if err != nil {
		msg := "A datastore error occured, your projects cannot be retrieved."
		c.Errorf("Delete_project_step1: %v", err)
		return_msg := "Return to dashboard"
		Message_page(w, r, user, msg, return_msg, "/dashboard")
		return
	}

	if len(projlist) == 0 {
		msg := "You are not the owner of any projects.  A project can only be deleted by its owner."
		return_msg := "Return to dashboard"
		Message_page(w, r, user, msg, return_msg, "/dashboard")
		return
	}

	type TV struct {
		User     string
		LoggedIn bool
		Proj     []*EncodedProjectView
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.Proj = Format_encoded_projects(projlist)
	template_values.LoggedIn = user != nil

	tmpl, err := template.ParseFiles("header.html",
		"delete_project_step1.html")
	if err != nil {
		c.Errorf("Delete_project_step1: %v", err)
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "delete_project_step1.html",
		template_values); err != nil {
		c.Errorf("Delete_project_step1: %v", err)
	}
}
// Create_project_step1 gets the project name from the user.
func Create_project_step1(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "GET" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)

	type TV struct {
		User     string
		LoggedIn bool
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil

	tmpl, err := template.ParseFiles("header.html",
		"create_project_step1.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "create_project_step1.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
Beispiel #5
0
func Copy_project(w http.ResponseWriter, r *http.Request) {

	if r.Method != "GET" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("pkey")

	ok := Check_access(user, pkey, &c, &w, r)

	if !ok {
		msg := "Only the project owner can copy a project."
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg,
			"/project_dashboard?pkey="+pkey)
		return
	}

	key := datastore.NewKey(c, "EncodedProject", pkey, 0, nil)
	var eproj EncodedProject
	err := datastore.Get(c, key, &eproj)
	if err != nil {
		c.Errorf("Copy_project: %v", err)
		msg := "Unknown datastore error."
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg,
			"/project_dashboard?pkey="+pkey)
		return
	}

	type TV struct {
		User        string
		LoggedIn    bool
		Pkey        string
		ProjectName string
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.Pkey = pkey
	template_values.ProjectName = eproj.Name

	tmpl, err := template.ParseFiles("header.html", "copy_project.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "copy_project.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
Beispiel #6
0
func Dashboard(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "GET" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)

	_, projlist, err := GetProjects(user.String(), true, &c)
	if err != nil {
		msg := "A datastore error occured, projects cannot be retrieved."
		c.Errorf("Dashboard: %v", err)
		return_msg := "Return to dashboard"
		Message_page(w, r, nil, msg, return_msg, "/dashboard")
		return
	}

	type TV struct {
		User     string
		LoggedIn bool
		PRN      bool
		PR       []*EncodedProjectView
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.PR = Format_encoded_projects(projlist)
	template_values.PRN = len(projlist) > 0
	template_values.LoggedIn = user != nil

	tmpl, err := template.ParseFiles("header.html", "dashboard.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "dashboard.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
Beispiel #7
0
// Confirm_add_comment
func Confirm_add_comment(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("pkey")

	if ok := Check_access(user, pkey, &c, &w, r); !ok {
		return
	}

	proj, err := Get_project_from_key(pkey, &c)
	if err != nil {
		msg := "Datastore error, unable to add comment."
		return_msg := "Return to project"
		Message_page(w, r, user, msg, return_msg,
			"/project_dashboard?pkey="+pkey)
		c.Errorf("Confirm_add_comment [1]: %v", err)
		return
	}

	comment_text := r.FormValue("comment_text")
	comment_text = strings.TrimSpace(comment_text)
	comment_lines := strings.Split(comment_text, "\n")

	if len(comment_text) == 0 {
		msg := "No comment was entered."
		return_msg := "Return to project"
		Message_page(w, r, user, msg, return_msg,
			"/project_dashboard?pkey="+pkey)
		return
	}

	comment := new(Comment)
	comment.Person = user.String()
	comment.DateTime = time.Now()
	loc, _ := time.LoadLocation("America/New_York")
	t := comment.DateTime.In(loc)
	comment.Date = t.Format("2006-1-2")
	comment.Time = t.Format("3:04pm")
	comment.Comment = comment_lines
	proj.Comments = append(proj.Comments, comment)

	Store_project(proj, pkey, &c)

	msg := "Your comment has been added to the project."
	return_msg := "Return to project"
	Message_page(w, r, user, msg, return_msg,
		"/project_dashboard?pkey="+pkey)
}
// Create_project_step4
func Create_project_step4(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)

	if err := r.ParseForm(); err != nil {
		ServeError(&c, w, err)
		return
	}

	user := user.Current(c)

	numgroups, _ := strconv.Atoi(r.FormValue("numgroups"))

	type TV struct {
		User         string
		LoggedIn     bool
		Name         string
		Pkey         string
		StoreRawData bool
		NumGroups    int
		IX           []int
	}

	// Group numbers (they don't have names yet)
	IX := make([]int, numgroups, numgroups)
	for i := 0; i < numgroups; i++ {
		IX[i] = i + 1
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.Name = r.FormValue("project_name")
	template_values.StoreRawData = r.FormValue("store_rawdata") == "true"
	template_values.IX = IX
	template_values.NumGroups = numgroups

	tmpl, err := template.ParseFiles("header.html",
		"create_project_step4.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "create_project_step4.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
Beispiel #9
0
// View_comment
func View_comments(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "GET" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("pkey")

	if ok := Check_access(user, pkey, &c, &w, r); !ok {
		return
	}

	PR, _ := Get_project_from_key(pkey, &c)
	PV := Format_project(PR)

	for _, c := range PV.Comments {
		c.Date = c.DateTime.Format("2006-1-2")
		c.Time = c.DateTime.Format("3:04pm")
	}

	type TV struct {
		User         string
		LoggedIn     bool
		PR           *Project
		PV           *ProjectView
		Pkey         string
		Any_comments bool
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.PR = PR
	template_values.PV = PV
	template_values.Any_comments = len(PR.Comments) > 0
	template_values.Pkey = pkey

	tmpl, err := template.ParseFiles("header.html",
		"view_comments.html")
	if err != nil {
		c.Errorf("View_comments: %v", err)
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "view_comments.html",
		template_values); err != nil {
		c.Errorf("View_comments: %v", err)
	}
}
func validation_error_step8(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)

	user := user.Current(c)

	if err := r.ParseForm(); err != nil {
		ServeError(&c, w, err)
		return
	}

	type TV struct {
		User          string
		LoggedIn      bool
		Name          string
		NumGroups     int
		Pkey          string
		GroupNames    string
		StoreRawData  bool
		Numvar        int
		SamplingRates string
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.Name = r.FormValue("project_name")
	template_values.GroupNames = r.FormValue("group_names")
	template_values.NumGroups, _ = strconv.Atoi(r.FormValue("numgroups"))
	template_values.Numvar, _ = strconv.Atoi(r.FormValue("numvar"))
	template_values.StoreRawData = r.FormValue("store_rawdata") == "true"
	template_values.SamplingRates = r.FormValue("rates")

	tmpl, err := template.ParseFiles("header.html",
		"validation_error_step8.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "validation_error_step8.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
// Delete_project_step2 confirms that a project should be deleted.
func Delete_project_step2(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)

	user := user.Current(c)

	if err := r.ParseForm(); err != nil {
		ServeError(&c, w, err)
		return
	}

	pkey := r.FormValue("project_list")
	svec := strings.Split(pkey, "::")

	type TV struct {
		User        string
		LoggedIn    bool
		ProjectName string
		Pkey        string
		Nokey       bool
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.Pkey = pkey
	if len(svec) >= 2 {
		template_values.ProjectName = svec[1]
	}
	template_values.Nokey = len(pkey) == 0

	tmpl, err := template.ParseFiles("header.html",
		"delete_project_step2.html")
	if err != nil {
		c.Errorf("Delete_project_step2: %v", err)
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "delete_project_step2.html",
		template_values); err != nil {
		c.Errorf("Delete_project_step2: %v", err)
	}
}
// OpenClose_completed
func OpenClose_completed(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("pkey")

	if ok := Check_access(user, pkey, &c, &w, r); !ok {
		msg := "You do not have access to this page."
		return_msg := "Return"
		Message_page(w, r, user, msg, return_msg, "/")
		return
	}

	proj, err := Get_project_from_key(pkey, &c)
	if err != nil {
		msg := "Datastore error: unable to retrieve project."
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
		return
	}

	if proj.Owner != user.String() {
		msg := "Only the project owner can open or close a project for enrollment."
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
		return
	}

	status := r.FormValue("open")

	if status == "open" {
		msg := fmt.Sprintf("The project \"%s\" is now open for enrollment.", proj.Name)
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
		proj.Open = true
	} else {
		msg := fmt.Sprintf("The project \"%s\" is now closed for enrollment.", proj.Name)
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
		proj.Open = false
	}

	Store_project(proj, pkey, &c)
}
Beispiel #13
0
// Add_comment
func Add_comment(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "GET" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("pkey")

	if ok := Check_access(user, pkey, &c, &w, r); !ok {
		return
	}

	proj, _ := Get_project_from_key(pkey, &c)
	PV := Format_project(proj)

	type TV struct {
		User     string
		LoggedIn bool
		PR       *Project
		PV       *ProjectView
		Pkey     string
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.PR = proj
	template_values.PV = PV
	template_values.Pkey = pkey

	tmpl, err := template.ParseFiles("header.html",
		"add_comment.html")
	if err != nil {
		c.Errorf("Add_comment: %v", err)
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "add_comment.html",
		template_values); err != nil {
		c.Errorf("Add_comment: %v", err)
	}
}
// Create_project_step3 gets the number of treatment groups.
func Create_project_step3(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)

	if err := r.ParseForm(); err != nil {
		ServeError(&c, w, err)
		return
	}

	user := user.Current(c)

	type TV struct {
		User         string
		LoggedIn     bool
		Name         string
		Pkey         string
		StoreRawData bool
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.Name = r.FormValue("project_name")
	template_values.StoreRawData = r.FormValue("store_rawdata") == "yes"

	tmpl, err := template.ParseFiles("header.html",
		"create_project_step3.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "create_project_step3.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
// Information_page displays a page of information about this application.
func Information_page(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "GET" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)

	type TV struct {
		User     string
		LoggedIn bool
	}

	template_values := new(TV)
	if user != nil {
		template_values.User = user.String()
	} else {
		template_values.User = ""
	}
	template_values.LoggedIn = user != nil

	tmpl, err := template.ParseFiles("header.html", "information_page.html")
	if err != nil {
		c.Errorf("Information_page: %v", err)
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "information_page.html",
		template_values); err != nil {
		c.Errorf("Information page: %v", err)
	}
}
// Create_project_step6
func Create_project_step6(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)

	if err := r.ParseForm(); err != nil {
		ServeError(&c, w, err)
		return
	}

	user := user.Current(c)

	type TV struct {
		User          string
		LoggedIn      bool
		Name          string
		Pkey          string
		GroupNames    string
		StoreRawData  bool
		SamplingRates string
		NumGroups     int
	}

	numgroups, _ := strconv.Atoi(r.FormValue("numgroups"))

	// Get the sampling rates from the previous page
	group_names_arr := Clean_split(r.FormValue("group_names"), ",")
	sampling_rates := make([]string, numgroups, numgroups)
	for i := 0; i < numgroups; i++ {
		sampling_rates[i] = r.FormValue(fmt.Sprintf("rate%s", group_names_arr[i]))

		x, err := strconv.ParseFloat(sampling_rates[i], 64)
		if (err != nil) || (x <= 0) {
			msg := "The sampling rates must be positive numbers."
			return_msg := "Return to dashboard"
			Message_page(w, r, user, msg, return_msg, "/dashboard")
			return
		}
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.Name = r.FormValue("project_name")
	template_values.GroupNames = r.FormValue("group_names")
	template_values.StoreRawData = r.FormValue("store_rawdata") == "true"
	template_values.SamplingRates = strings.Join(sampling_rates, ",")
	template_values.NumGroups = numgroups

	tmpl, err := template.ParseFiles("header.html", "create_project_step6.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "create_project_step6.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
Beispiel #17
0
// Edit_sharing_confirm
func Edit_sharing_confirm(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("pkey")

	spkey := strings.Split(pkey, "::")
	project_name := spkey[1]

	ap := r.FormValue("additional_people")
	add_users := []string{}
	add_users = Clean_split(ap, ",")
	for k, x := range add_users {
		add_users[k] = strings.ToLower(x)
	}

	// Gmail addresses don't use @gmail.com.
	invalid_emails := make([]string, 0)
	for k, x := range add_users {
		uparts := strings.Split(x, "@")
		if len(uparts) != 2 {
			invalid_emails = append(invalid_emails, x)
		} else {
			if uparts[1] == "gmail.com" {
				add_users[k] = uparts[0]
			}
		}
	}

	if len(invalid_emails) > 0 {
		msg := "The project was not shared because the following email addresses are not valid: "
		msg += strings.Join(invalid_emails, ", ") + "."
		return_msg := "Return to project"
		Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
		return
	}

	var err error
	err = Add_sharing(pkey, add_users, &c)
	if err != nil {
		msg := "Datastore error: unable to update sharing information."
		return_msg := "Return to dashboard"
		Message_page(w, r, user, msg, return_msg, "/dashboard")
		c.Errorf("Edit_sharing_confirm [1]: %v", err)
		return
	}

	remove_users := r.Form["remove_users"]
	err = Remove_sharing(pkey, remove_users, &c)
	if err != nil {
		msg := "Datastore error: unable to update sharing information."
		return_msg := "Return to dashboard"
		Message_page(w, r, user, msg, return_msg, "/dashboard")
		c.Errorf("Edit_sharing_confirm [2]: %v", err)
		return
	}

	type TV struct {
		User        string
		LoggedIn    bool
		ProjectName string
		Pkey        string
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.ProjectName = project_name
	template_values.Pkey = pkey

	tmpl, err := template.ParseFiles("header.html",
		"edit_sharing_confirm.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "edit_sharing_confirm.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
// Create_project_step8
func Create_project_step8(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)

	if err := r.ParseForm(); err != nil {
		ServeError(&c, w, err)
		return
	}

	numgroups, _ := strconv.Atoi(r.FormValue("numgroups"))
	numvar, _ := strconv.Atoi(r.FormValue("numvar"))
	variables, ok := process_variable_info(r, numvar)

	if !ok {
		validation_error_step8(w, r)
		return
	}

	type TV struct {
		User          string
		LoggedIn      bool
		Name          string
		Pkey          string
		IX            []int
		GroupNames    string
		StoreRawData  bool
		NumGroups     int
		Numvar        int
		Variables     string
		SamplingRates string
	}

	IX := make([]int, numvar, numvar)

	for i := 0; i < numvar; i++ {
		IX[i] = i + 1
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.Name = r.FormValue("project_name")
	template_values.GroupNames = r.FormValue("group_names")
	template_values.IX = IX
	template_values.NumGroups = numgroups
	template_values.Numvar = numvar
	template_values.Variables = variables
	template_values.StoreRawData = r.FormValue("store_rawdata") == "true"
	template_values.SamplingRates = r.FormValue("rates")

	tmpl, err := template.ParseFiles("header.html",
		"create_project_step8.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "create_project_step8.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
Beispiel #19
0
func Copy_project_completed(w http.ResponseWriter, r *http.Request) {

	if r.Method != "GET" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("pkey")

	ok := Check_access(user, pkey, &c, &w, r)

	if !ok {
		msg := "You do not have access to the requested project."
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg,
			"/project_dashboard?pkey="+pkey)
		return
	}

	key := datastore.NewKey(c, "EncodedProject", pkey, 0, nil)
	var eproj EncodedProject
	err := datastore.Get(c, key, &eproj)
	if err != nil {
		msg := "Unknown error, the project was not copied."
		return_msg := "Return to dashboard"
		Message_page(w, r, user, msg, return_msg, "/dashboard")
		c.Errorf("Copy_project: %v", err)
		return
	}

	eproj_copy := Copy_encoded_project(&eproj)

	// Check if the name is valid (not blank)
	new_name := r.FormValue("new_project_name")
	new_name = strings.TrimSpace(new_name)
	if len(new_name) == 0 {
		msg := "A name for the new project must be provided."
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg,
			"/project_dashboard?pkey="+pkey)
		return
	}
	eproj_copy.Name = new_name

	// The owner of the copied project is the current user
	eproj_copy.Owner = user.String()

	// Check if the project name has already been used.
	new_pkey := user.String() + "::" + new_name
	new_key := datastore.NewKey(c, "EncodedProject", new_pkey, 0, nil)
	var pr EncodedProject
	err = datastore.Get(c, new_key, &pr)
	if err == nil {
		msg := fmt.Sprintf("A project named \"%s\" belonging to user %s already exists.", new_name,
			user.String())
		return_msg := "Return to dashboard"
		Message_page(w, r, user, msg, return_msg, "/dashboard")
		return
	}

	_, err = datastore.Put(c, new_key, eproj_copy)
	if err != nil {
		c.Errorf("Copy_project: %v", err)
		msg := "Unknown error, the project was not copied."
		return_msg := "Return to dashboard"
		Message_page(w, r, user, msg, return_msg, "/dashboard")
		return
	}

	c.Infof("Copied %s to %s", pkey, new_pkey)
	msg := "The project has been successfully copied."
	return_msg := "Return to dashboard"
	Message_page(w, r, user, msg, return_msg, "/dashboard")
	return
}
// Assign_treatment
func Assign_treatment(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("pkey")

	if ok := Check_access(user, pkey, &c, &w, r); !ok {
		return
	}

	if err := r.ParseForm(); err != nil {
		ServeError(&c, w, err)
		return
	}

	proj, err := Get_project_from_key(pkey, &c)
	if err != nil {
		c.Errorf("Assign_treatment %v", err)
		msg := "A datastore error occured, the project could not be loaded."
		return_msg := "Return to dashboard"
		Message_page(w, r, user, msg, return_msg, "/dashboard")
		return
	}

	subject_id := r.FormValue("subject_id")

	// Check this a second time in case someone lands on this page
	// without going through the previous checks
	// (e.g. inappropriate use of back button on browser).
	ok := check_before_assigning(proj, pkey, subject_id, user, w, r)
	if !ok {
		return
	}

	pview := Format_project(proj)

	fields := strings.Split(r.FormValue("fields"), ",")
	values := strings.Split(r.FormValue("values"), ",")

	// mpv maps variable names to values for the unit that is about
	// to be randomized to a treatment group.
	mpv := make(map[string]string)
	for i, x := range fields {
		mpv[x] = values[i]
	}

	ax, err := Do_assignment(&mpv, proj, subject_id, user.String())
	if err != nil {
		c.Errorf("%v", err)
	}

	proj.Modified = time.Now()

	// Update the project in the database.
	eproj, _ := Encode_Project(proj)
	key := datastore.NewKey(c, "EncodedProject", pkey, 0, nil)
	_, err = datastore.Put(c, key, eproj)
	if err != nil {
		c.Errorf("Assign_treatment: %v", err)
		msg := "A datastore error occured, the project could not be updated."
		return_msg := "Return to dashboard"
		Message_page(w, r, user, msg, return_msg, "/dashboard")
		return
	}

	type TV struct {
		User      string
		LoggedIn  bool
		PR        *Project
		PV        *ProjectView
		NumGroups int
		Ax        string
		Pkey      string
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.Ax = ax
	template_values.PR = proj
	template_values.PV = pview
	template_values.NumGroups = len(proj.GroupNames)
	template_values.Pkey = pkey

	tmpl, err := template.ParseFiles("header.html",
		"assign_treatment.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "assign_treatment.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
// View_statistics
func View_statistics(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "GET" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("pkey")

	if ok := Check_access(user, pkey, &c, &w, r); !ok {
		return
	}

	var err error
	project, err := Get_project_from_key(pkey, &c)
	if err != nil {
		c.Errorf("View_statistics [1]: %v", err)
		msg := "Datastore error: unable to view statistics."
		return_msg := "Return to dashboard"
		Message_page(w, r, user, msg, return_msg, "/dashboard")
		c.Errorf("View_statistics [1]: %v", err)
		return
	}
	project_view := Format_project(project)

	// Treatment assignment.
	tx_asgn := make([][]string, len(project.GroupNames))
	for k, v := range project.GroupNames {
		tx_asgn[k] = []string{v, fmt.Sprintf("%d", project.Assignments[k])}
	}

	num_groups := len(project.GroupNames)
	data := project.Data

	m := 0
	for _, v := range project.Variables {
		m += len(v.Levels)
	}

	// Balance statistics.
	bal_stat := make([][]string, m)
	jj := 0
	for j, v := range project.Variables {
		num_levels := len(v.Levels)
		for k := 0; k < num_levels; k++ {
			fstat := make([]string, 1+num_groups)
			fstat[0] = v.Name + "=" + v.Levels[k]
			for q := 0; q < num_groups; q++ {
				u := data[j][k][q]
				fstat[q+1] = fmt.Sprintf("%.0f", u)
			}
			bal_stat[jj] = fstat
			jj++
		}
	}

	type TV struct {
		User        string
		LoggedIn    bool
		Project     *Project
		AnyVars     bool
		ProjectView *ProjectView
		TxAsgn      [][]string
		BalStat     [][]string
		Pkey        string
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.Project = project
	template_values.AnyVars = len(project.Variables) > 0
	template_values.ProjectView = project_view
	template_values.TxAsgn = tx_asgn
	template_values.Pkey = pkey
	template_values.BalStat = bal_stat

	tmpl, err := template.ParseFiles("header.html", "view_statistics.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "view_statistics.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
// Assign_treatment_confirm
func Assign_treatment_confirm(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)

	user := user.Current(c)

	pkey := r.FormValue("pkey")

	if ok := Check_access(user, pkey, &c, &w, r); !ok {
		return
	}

	if err := r.ParseForm(); err != nil {
		ServeError(&c, w, err)
		return
	}

	subject_id := r.FormValue("subject_id")
	subject_id = strings.TrimSpace(subject_id)

	project, err := Get_project_from_key(pkey, &c)
	if err != nil {
		c.Errorf("Assign_treatment_confirm: %v", err)
		msg := "A datastore error occured, the project could not be loaded."
		return_msg := "Return to dashboard"
		Message_page(w, r, user, msg, return_msg, "/dashboard")
		return
	}

	ok := check_before_assigning(project, pkey, subject_id, user, w, r)
	if !ok {
		return
	}

	project_view := Format_project(project)

	Fields := strings.Split(r.FormValue("fields"), ",")
	FV := make([][]string, len(Fields)+1)
	Values := make([]string, len(Fields))

	FV[0] = []string{"Subject id", subject_id}
	for i, v := range Fields {
		x := r.FormValue(v)
		FV[i+1] = []string{v, x}
		Values[i] = x
	}

	type TV struct {
		User        string
		LoggedIn    bool
		Pkey        string
		Project     *Project
		ProjectView *ProjectView
		NumGroups   int
		Fields      string
		FV          [][]string
		Values      string
		SubjectId   string
		AnyVars     bool
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.Pkey = pkey
	template_values.Project = project
	template_values.ProjectView = project_view
	template_values.NumGroups = len(project.GroupNames)
	template_values.Fields = strings.Join(Fields, ",")
	template_values.FV = FV
	template_values.Values = strings.Join(Values, ",")
	template_values.SubjectId = subject_id
	template_values.AnyVars = len(project.Variables) > 0

	tmpl, err := template.ParseFiles("header.html",
		"assign_treatment_confirm.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "assign_treatment_confirm.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
// Assign_treatment_input
func Assign_treatment_input(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "GET" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)

	if err := r.ParseForm(); err != nil {
		ServeError(&c, w, err)
		return
	}

	pkey := r.FormValue("pkey")

	if ok := Check_access(user, pkey, &c, &w, r); !ok {
		return
	}

	PR, err := Get_project_from_key(pkey, &c)
	if err != nil {
		c.Errorf("Assign_treatment_input: %v", err)
		msg := "A datastore error occured, the project could not be loaded."
		return_msg := "Return to dashboard"
		Message_page(w, r, user, msg, return_msg, "/dashboard")
		return
	}

	if PR.Open == false {
		msg := "This project is currently not open for new enrollments.  The project owner can change this by following the \"Open/close enrollment\" link on the project dashboard."
		return_msg := "Return to project"
		Message_page(w, r, user, msg, return_msg,
			"/project_dashboard?pkey="+pkey)
		return
	}

	PV := Format_project(PR)

	type TV struct {
		User      string
		LoggedIn  bool
		PR        *Project
		PV        *ProjectView
		NumGroups int
		Fields    string
		Pkey      string
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.PR = PR
	template_values.PV = PV
	template_values.NumGroups = len(PR.GroupNames)
	template_values.Pkey = pkey

	S := make([]string, len(PR.Variables))
	for i, v := range PR.Variables {
		S[i] = v.Name
	}
	template_values.Fields = strings.Join(S, ",")

	tmpl, err := template.ParseFiles("header.html",
		"assign_treatment_input.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "assign_treatment_input.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
// Create_project_step1 gets the project name from the user.
func Project_dashboard(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "GET" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("pkey")

	if ok := Check_access(user, pkey, &c, &w, r); !ok {
		return
	}

	splkey := strings.Split(pkey, "::")
	owner := splkey[0]

	project, _ := Get_project_from_key(pkey, &c)
	project_view := Format_project(project)

	type TV struct {
		User            string
		LoggedIn        bool
		ProjView        *ProjectView
		NumGroups       int
		Sharing         string
		SharedUsers     []string
		Pkey            string
		ShowEditSharing bool
		Owner           string
		StoreRawData    string
		Open            string
		AnyVars         bool
	}

	susers, _ := Get_shared_users(pkey, &c)

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.ProjView = project_view
	template_values.NumGroups = len(project.GroupNames)
	template_values.AnyVars = len(project.Variables) > 0
	if project.StoreRawData {
		template_values.StoreRawData = "Yes"
	} else {
		template_values.StoreRawData = "No"
	}
	if len(susers) > 0 {
		template_values.Sharing = strings.Join(susers, ", ")
	} else {
		template_values.Sharing = "Nobody"
	}
	template_values.Pkey = pkey
	template_values.ShowEditSharing = owner == user.String()
	template_values.Owner = owner

	if project_view.Open {
		template_values.Open = "Yes"
	} else {
		template_values.Open = "No"
	}

	tmpl, err := template.ParseFiles("header.html", "project_dashboard.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "project_dashboard.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
// Create_project_step9 creates the project using all supplied
// information, and stores the project in the database.
func Create_project_step9(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)

	if err := r.ParseForm(); err != nil {
		ServeError(&c, w, err)
		return
	}

	user := user.Current(c)

	numvar, _ := strconv.Atoi(r.FormValue("numvar"))
	GroupNames := r.FormValue("group_names")
	project_name := r.FormValue("project_name")
	variables := r.FormValue("variables")
	VL := Clean_split(variables, ":")
	bias, _ := strconv.Atoi(r.FormValue("bias"))
	rates := r.FormValue("rates")

	// Parse and validate the variable information.
	VA := make([]Variable, numvar, numvar)
	for i, vl := range VL {
		vx := Clean_split(vl, ";")
		var va Variable
		va.Name = vx[0]
		va.Levels = Clean_split(vx[1], ",")
		va.Weight, _ = strconv.ParseFloat(vx[2], 64)
		va.Func = vx[3]
		VA[i] = va
	}

	var project Project
	project.Owner = user.String()
	project.Created = time.Now()
	project.Name = project_name
	project.Variables = VA
	project.Bias = bias
	project.GroupNames = Clean_split(GroupNames, ",")
	project.Assignments = make([]int, len(project.GroupNames))
	project.StoreRawData = r.FormValue("store_rawdata") == "true"
	project.Open = true

	// Convert the rates to numbers
	rates = r.FormValue("rates")
	rates_arr := Clean_split(rates, ",")
	rates_num := make([]float64, len(rates_arr))
	for i, x := range rates_arr {
		rates_num[i], _ = strconv.ParseFloat(x, 64)
	}
	project.SamplingRates = rates_num

	// Set up the data.
	numgroups := len(project.GroupNames)
	data0 := make([][][]float64, len(project.Variables))
	for j, va := range project.Variables {
		data0[j] = make([][]float64, len(va.Levels))
		for k, _ := range va.Levels {
			data0[j][k] = make([]float64, numgroups)
		}
	}
	project.Data = data0

	pkey := user.String() + "::" + project_name
	dkey := datastore.NewKey(c, "EncodedProject", pkey, 0, nil)
	eproj, err := Encode_Project(&project)
	if err != nil {
		c.Errorf("Create_project_step9 [2]: %v", err)
	}
	_, err = datastore.Put(c, dkey, eproj)
	if err != nil {
		msg := "A datastore error occured, the project was not created."
		c.Errorf("Create_project_step9: %v", err)
		return_msg := "Return to dashboard"
		Message_page(w, r, user, msg, return_msg, "/dashboard")
		return
	}

	// Remove any stale SharingByProject entities
	dkey = datastore.NewKey(c, "SharingByProject", pkey, 0, nil)
	err = datastore.Delete(c, dkey)
	if err != nil {
		c.Errorf("Create_project_step9 [3]: %v", err)
	}

	type TV struct {
		User     string
		LoggedIn bool
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil

	tmpl, err := template.ParseFiles("header.html",
		"create_project_step9.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "create_project_step9.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
// Remove_subject
func Remove_subject(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "GET" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("pkey")

	if ok := Check_access(user, pkey, &c, &w, r); !ok {
		return
	}

	proj, err := Get_project_from_key(pkey, &c)
	if err != nil {
		msg := "Datastore error: unable to retrieve project."
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
		return
	}

	if proj.Owner != user.String() {
		msg := "Only the project owner can remove treatment group assignments that have already been made."
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg,
			"/project_dashboard?pkey="+pkey)
		return
	}

	if proj.StoreRawData == false {
		msg := "Subjects cannot be removed for a project in which the subject level data is not stored"
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg,
			"/project_dashboard?pkey="+pkey)
		return
	}

	type TV struct {
		User                 string
		LoggedIn             bool
		Pkey                 string
		ProjectName          string
		Any_removed_subjects bool
		RemovedSubjects      string
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.Pkey = pkey
	template_values.ProjectName = proj.Name

	if len(proj.RemovedSubjects) > 0 {
		template_values.Any_removed_subjects = true
		template_values.RemovedSubjects = strings.Join(proj.RemovedSubjects, ", ")
	} else {
		template_values.Any_removed_subjects = false
	}

	tmpl, err := template.ParseFiles("header.html",
		"remove_subject.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "remove_subject.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
// Remove_subject_completed
func Remove_subject_completed(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("pkey")

	if ok := Check_access(user, pkey, &c, &w, r); !ok {
		msg := "You do not have access to this page."
		return_msg := "Return"
		Message_page(w, r, user, msg, return_msg, "/")
		return
	}

	proj, err := Get_project_from_key(pkey, &c)
	if err != nil {
		msg := "Datastore error: unable to retrieve project."
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
		return
	}

	if proj.Owner != user.String() {
		msg := "Only the project owner can remove treatment group assignments that have already been made."
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
		return
	}

	if proj.StoreRawData == false {
		msg := "Subjects cannot be removed for a project in which the subject level data is not stored"
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
		return
	}

	subject_id := r.FormValue("subject_id")
	found := false
	var remove_rec *DataRecord
	for _, rec := range proj.RawData {
		if rec.SubjectId == subject_id {
			rec.Included = false
			remove_rec = rec
			found = true
		}
	}
	proj.RemovedSubjects = append(proj.RemovedSubjects, subject_id)

	comment := new(Comment)
	comment.Person = user.String()
	comment.DateTime = time.Now()
	comment.Comment = []string{fmt.Sprintf("Subject '%s' removed from the project.", subject_id)}
	proj.Comments = append(proj.Comments, comment)

	if found == false {
		msg := fmt.Sprintf("Unable to remove subject '%s' from the project.", subject_id)
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
		return
	}

	Remove_from_aggregate(remove_rec, proj)
	proj.NumAssignments -= 1
	Store_project(proj, pkey, &c)

	msg := fmt.Sprintf("Subject '%s' has been removed from the study.", subject_id)
	return_msg := "Return to project dashboard"
	Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
}
// Remove_subject_confirm
func Remove_subject_confirm(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("pkey")
	subject_id := r.FormValue("subject_id")

	type TV struct {
		User        string
		LoggedIn    bool
		Pkey        string
		SubjectId   string
		ProjectName string
	}

	proj, err := Get_project_from_key(pkey, &c)
	if err != nil {
		msg := "Datastore error: unable to retrieve project."
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
		return
	}

	if proj.Owner != user.String() {
		msg := "Only the project owner can remove treatment group assignments that have already been made."
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
		return
	}

	// Check if the subject has already been removed
	for _, s := range proj.RemovedSubjects {
		if s == subject_id {
			msg := fmt.Sprintf("Subject '%s' has already been removed from the study.", subject_id)
			return_msg := "Return to project"
			Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
			return
		}
	}

	// Check if the subject exists
	found := false
	for _, rec := range proj.RawData {
		if rec.SubjectId == subject_id {
			found = true
			break
		}
	}
	if found == false {
		msg := fmt.Sprintf("There is no subject with id '%s' in the project.", subject_id)
		return_msg := "Return to project"
		Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
		return
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.SubjectId = subject_id
	template_values.Pkey = pkey
	template_values.ProjectName = proj.Name

	tmpl, err := template.ParseFiles("header.html", "remove_subject_confirm.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "remove_subject_confirm.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}
// Delete_project_step3 deletes a project.
func Delete_project_step3(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "POST" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("Pkey")

	if err := r.ParseForm(); err != nil {
		c.Errorf("Delete_project_step3 [1]: %v", err)
		ServeError(&c, w, err)
		return
	}

	// Delete the SharingByProject object, but first read the
	// users list from it so we can delete the project from their
	// SharingByUsers records.
	key := datastore.NewKey(c, "SharingByProject", pkey, 0, nil)
	var sbproj SharingByProject
	Shared_with := make([]string, 0)
	err := datastore.Get(c, key, &sbproj)
	if err == datastore.ErrNoSuchEntity {
		c.Errorf("Delete_project_step3 [2]: %v", err)
	} else if err != nil {
		c.Errorf("Delete_project_step3 [3] %v", err)
	} else {
		Shared_with = Clean_split(sbproj.Users, ",")
		err = datastore.Delete(c, key)
		if err != nil {
			c.Errorf("Delete_project_step3 [4] %v", err)
		}
	}

	// Delete the project.
	key = datastore.NewKey(c, "EncodedProject", pkey, 0, nil)
	err = datastore.Delete(c, key)
	if err != nil {
		c.Errorf("Delete_project_step3 [5]: %v", err)
	}

	// Delete from each user's SharingByUser record.
	for _, user1 := range Shared_with {
		var sbuser SharingByUser
		key := datastore.NewKey(c, "SharingByUser", strings.ToLower(user1), 0, nil)
		err := datastore.Get(c, key, &sbuser)
		if err != nil {
			c.Errorf("Delete_project_step3 [6]: %v", err)
		}
		Projects := Clean_split(sbuser.Projects, ",")

		// Get the unique project keys, except for pkey.
		mp := make(map[string]bool)
		for _, x := range Projects {
			if x != pkey {
				mp[x] = true
			}
		}
		vec := make([]string, len(mp))
		jj := 0
		for k, _ := range mp {
			vec[jj] = k
			jj += 1
		}
		sbuser.Projects = strings.Join(vec, ",")

		_, err = datastore.Put(c, key, &sbuser)
		if err != nil {
			c.Errorf("Delete_project_step3 [7]: %v", err)
		}
	}

	type TV struct {
		User     string
		LoggedIn bool
		Success  bool
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.Success = err == nil
	template_values.LoggedIn = user != nil

	tmpl, err := template.ParseFiles("header.html",
		"delete_project_step3.html")
	if err != nil {
		c.Errorf("Delete_project_step3 [8]: %v", err)
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "delete_project_step3.html",
		template_values); err != nil {
		c.Errorf("Delete_project_step3 [9]: %v", err)
	}
}
// OpenClose_project
func OpenClose_project(w http.ResponseWriter,
	r *http.Request) {

	if r.Method != "GET" {
		Serve404(w)
		return
	}

	c := appengine.NewContext(r)
	user := user.Current(c)
	pkey := r.FormValue("pkey")

	if ok := Check_access(user, pkey, &c, &w, r); !ok {
		msg := "You do not have access to this page."
		return_msg := "Return"
		Message_page(w, r, user, msg, return_msg, "/")
		return
	}

	proj, err := Get_project_from_key(pkey, &c)
	if err != nil {
		msg := "Datastore error: unable to retrieve project."
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
		c.Errorf("OpenClose_project [1]: %v", err)
		return
	}

	if proj.Owner != user.String() {
		msg := "Only the project owner can open or close a project for enrollment."
		return_msg := "Return to project dashboard"
		Message_page(w, r, user, msg, return_msg, "/project_dashboard?pkey="+pkey)
		return
	}

	type TV struct {
		User        string
		LoggedIn    bool
		Pkey        string
		ProjectName string
		GroupNames  []string
		Open        bool
	}

	template_values := new(TV)
	template_values.User = user.String()
	template_values.LoggedIn = user != nil
	template_values.Pkey = pkey
	template_values.ProjectName = proj.Name
	template_values.GroupNames = proj.GroupNames
	template_values.Open = proj.Open

	tmpl, err := template.ParseFiles("header.html",
		"openclose_project.html")
	if err != nil {
		ServeError(&c, w, err)
		return
	}

	if err := tmpl.ExecuteTemplate(w, "openclose_project.html",
		template_values); err != nil {
		c.Errorf("Failed to execute template: %v", err)
	}
}