<commit_before>package controllers

import (
	"encoding/json"
	"errors"
	"net/http"
	"time"

	"github.com/coduno/api/model"
	"github.com/coduno/api/util"
	"github.com/coduno/api/util/passenger"
	"github.com/gorilla/mux"
	"golang.org/x/net/context"
	"google.golang.org/appengine/datastore"
)

// TaskByKey loads a task by key.
func TaskByKey(ctx context.Context, w http.ResponseWriter, r *http.Request) (status int, err error) {
	p, ok := passenger.FromContext(ctx)
	if !ok {
		return http.StatusUnauthorized, nil
	}

	if r.Method != "GET" {
		return http.StatusMethodNotAllowed, nil
	}

	taskKey, err := datastore.DecodeKey(mux.Vars(r)["key"])
	if err != nil {
		return http.StatusInternalServerError, err
	}

	// User is a coder
	if p.UserKey.Parent() == nil {
		rk, err := datastore.DecodeKey(r.URL.Query()["result"][0])
		if err != nil {
			return http.StatusInternalServerError, err
		}

		if !util.HasParent(p.UserKey, rk) {
			return http.StatusUnauthorized, nil
		}

		var result model.Result
		if err = datastore.Get(ctx, rk, &result); err != nil {
			return http.StatusInternalServerError, err
		}

		var challenge model.Challenge
		if err = datastore.Get(ctx, result.Challenge, &challenge); err != nil {
			return http.StatusInternalServerError, err
		}

		emptyTime := time.Time{}
		updateResult := false
		for i, val := range challenge.Tasks {
			if taskKey.Equal(val) && result.StartTimes[i] == emptyTime {
				result.StartTimes[i] = time.Now()
				updateResult = true
				break
			}
		}
		if updateResult {
			if _, err = result.Save(ctx, rk); err != nil {
				return http.StatusInternalServerError, err
			}
		}
	}

	switch taskKey.Kind() {
	case model.CodeTaskKind:
		var task model.CodeTask
		if err = datastore.Get(ctx, taskKey, &task); err != nil {
			return http.StatusInternalServerError, err
		}
		json.NewEncoder(w).Encode(task.Key(taskKey))
		return http.StatusOK, nil
	default:
		return http.StatusInternalServerError, errors.New("Not implemented")
	}
}

func Tasks(ctx context.Context, w http.ResponseWriter, r *http.Request) (status int, err error) {
	p, ok := passenger.FromContext(ctx)
	if !ok {
		return http.StatusUnauthorized, nil
	}

	if r.Method != "GET" {
		return http.StatusMethodNotAllowed, nil
	}

	// User is a coder
	if p.UserKey.Parent() == nil {
		return http.StatusUnauthorized, nil
	}

	var tasks model.Tasks
	keys, err := model.NewQueryForTask().
		GetAll(ctx, &tasks)

	if err != nil {
		return http.StatusInternalServerError, err
	}

	json.NewEncoder(w).Encode(tasks.Key(keys))
	return http.StatusOK, nil
}<commit_msg>ctrl: Make GET /tasks return all tasks<commit_after>package controllers

import (
	"encoding/json"
	"errors"
	"net/http"
	"time"

	"github.com/coduno/api/model"
	"github.com/coduno/api/util"
	"github.com/coduno/api/util/passenger"
	"github.com/gorilla/mux"
	"golang.org/x/net/context"
	"google.golang.org/appengine/datastore"
)

// TaskByKey loads a task by key.
func TaskByKey(ctx context.Context, w http.ResponseWriter, r *http.Request) (status int, err error) {
	p, ok := passenger.FromContext(ctx)
	if !ok {
		return http.StatusUnauthorized, nil
	}

	if r.Method != "GET" {
		return http.StatusMethodNotAllowed, nil
	}

	taskKey, err := datastore.DecodeKey(mux.Vars(r)["key"])
	if err != nil {
		return http.StatusInternalServerError, err
	}

	// User is a coder
	if p.UserKey.Parent() == nil {
		rk, err := datastore.DecodeKey(r.URL.Query()["result"][0])
		if err != nil {
			return http.StatusInternalServerError, err
		}

		if !util.HasParent(p.UserKey, rk) {
			return http.StatusUnauthorized, nil
		}

		var result model.Result
		if err = datastore.Get(ctx, rk, &result); err != nil {
			return http.StatusInternalServerError, err
		}

		var challenge model.Challenge
		if err = datastore.Get(ctx, result.Challenge, &challenge); err != nil {
			return http.StatusInternalServerError, err
		}

		emptyTime := time.Time{}
		updateResult := false
		for i, val := range challenge.Tasks {
			if taskKey.Equal(val) && result.StartTimes[i] == emptyTime {
				result.StartTimes[i] = time.Now()
				updateResult = true
				break
			}
		}
		if updateResult {
			if _, err = result.Save(ctx, rk); err != nil {
				return http.StatusInternalServerError, err
			}
		}
	}

	switch taskKey.Kind() {
	case model.CodeTaskKind:
		var task model.CodeTask
		if err = datastore.Get(ctx, taskKey, &task); err != nil {
			return http.StatusInternalServerError, err
		}
		json.NewEncoder(w).Encode(task.Key(taskKey))
		return http.StatusOK, nil
	default:
		return http.StatusInternalServerError, errors.New("Not implemented")
	}
}

func Tasks(ctx context.Context, w http.ResponseWriter, r *http.Request) (status int, err error) {
	p, ok := passenger.FromContext(ctx)
	if !ok {
		return http.StatusUnauthorized, nil
	}

	if r.Method != "GET" {
		return http.StatusMethodNotAllowed, nil
	}

	// User is a coder
	if p.UserKey.Parent() == nil {
		return http.StatusUnauthorized, nil
	}

	var codeTasks model.CodeTasks
	codeTaskKeys, err := model.NewQueryForCodeTask().
		GetAll(ctx, &codeTasks)

	if err != nil {
		return http.StatusInternalServerError, err
	}

	tasks := make([]model.KeyedTask, len(codeTasks))
	for i := range codeTasks {
		tasks[i] = model.KeyedTask{
			Task: &codeTasks[i].Task,
			Key:  codeTaskKeys[i],
		}
	}

	json.NewEncoder(w).Encode(tasks)
	return http.StatusOK, nil
}
{'fraction_non_alphanumeric': 0.1334706102583302, 'fraction_numerical': 0.00037439161362785476, 'mean_word_length': 3.7705357142857143, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7087198', 'n_tokens_mistral': 2054, 'n_tokens_neox': 1881, 'n_words': 437}