// 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) } }
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) } }
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) } }
// 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) } }
// 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) }
// 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) } }
// 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) } }
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) } }