func Run(uni *context.Uni, commands string) (string, error) { if !scut.IsAdmin(uni.Dat["_user"]) { return "", fmt.Errorf("Currently only admins can use this.") } lines := strings.Split(commands, "\n") for i, v := range lines { // This hack... if len(v) > 0 && v[0] != '#' { lines[i] = "{{" + v + "}}" } } whole_file := strings.Join(lines, "\n") funcMap := template.FuncMap(builtins(uni)) t, err := template.New("shell").Funcs(funcMap).Parse(string(whole_file)) if err != nil { return "", strip(err) } context := map[string]interface{}{"dat": uni.Dat, "opt": uni.Opt} var buffer bytes.Buffer err = t.Execute(&buffer, context) // TODO: watch for errors in execution. if err != nil { return "", strip(err) } output_lines := strings.Split(buffer.String(), "\n") output_lines = stripComments(output_lines) return strings.Join(output_lines, "\n"), nil }
func Terminal(uni *context.Uni) error { if !scut.IsAdmin(uni.Dat["_user"]) { return fmt.Errorf("Currently only admins can use this.") } uni.Dat["_points"] = []string{"admin/terminal"} // This is inconsequential with other parts of the system, probably there is a better place for this. return nil }
// We must recreate this map each time because map write is not threadsafe. // Write will happen when a hook modifies the map (hook call is not implemented yet). func builtins(uni *context.Uni) map[string]interface{} { dat := uni.Dat user := uni.Dat["_user"] ret := map[string]interface{}{ "get": func(s ...string) interface{} { return get(dat, s...) }, "date": date, "solved_puzzles": func() bool { return scut.SolvedPuzzles(user) }, "is_stranger": func() bool { return scut.IsStranger(user) }, "is_guest": func() bool { return scut.IsGuest(user) }, "is_registered": func() bool { return scut.IsRegistered(user) }, "is_moderator": func() bool { return scut.IsModerator(user) }, "is_admin": func() bool { return scut.IsAdmin(user) }, "is_map": isMap, "eq": eq, "show_puzzles": func(a, b string) string { return showPuzzles(uni, a, b) }, "html": html, "format_float": formatFloat, "fallback": fallback, "type_of": typeOf, "same_kind": sameKind, } return ret }