Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions server/dbutil/dbutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import (
"regexp"
"strings"

// loads the driver
_ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3"

"github.com/pmezard/go-difflib/difflib"
)

Expand Down
4 changes: 4 additions & 0 deletions server/handler/assignments.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import (
"github.com/src-d/code-annotation/server/serializer"
)

// GetAssignmentsForUserExperiment returns a function that returns a *serializer.Response
// with the assignments for the logged user and a passed experiment
// if these assignments do not already exist, they are created in advance
func GetAssignmentsForUserExperiment() RequestProcessFunc {
return func(r *http.Request) (*serializer.Response, error) {
return nil, serializer.NewHTTPError(http.StatusNotImplemented)
Expand All @@ -17,6 +20,7 @@ type assignmentRequest struct {
Duration int `json:"duration"`
}

// SaveAssignment returns a function that saves the user answers as passed in the body request
func SaveAssignment() RequestProcessFunc {
return func(r *http.Request) (*serializer.Response, error) {
return nil, serializer.NewHTTPError(http.StatusNotImplemented)
Expand Down
2 changes: 2 additions & 0 deletions server/handler/experiments.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"github.com/src-d/code-annotation/server/serializer"
)

// GetExperimentDetails returns a function that returns a *serializer.Response
// with the details of a requested experiment
func GetExperimentDetails() RequestProcessFunc {
return func(r *http.Request) (*serializer.Response, error) {
return nil, serializer.NewHTTPError(http.StatusNotImplemented)
Expand Down
2 changes: 2 additions & 0 deletions server/handler/file_pairs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"github.com/src-d/code-annotation/server/serializer"
)

// GetFilePairDetails returns a function that returns a *serializer.Response
// with the details of the requested FilePair
func GetFilePairDetails() RequestProcessFunc {
return func(r *http.Request) (*serializer.Response, error) {
return nil, serializer.NewHTTPError(http.StatusNotImplemented)
Expand Down
8 changes: 5 additions & 3 deletions server/handler/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import (
"github.com/src-d/code-annotation/server/service"
)

// RequestProcessFunc is a function that takes an http.Request, and returns a serializer.Response and an error
type RequestProcessFunc func(*http.Request) (*serializer.Response, error)

// Get returns an http.HandlerFunc that will serve the user request taking the serializer.Response and errors
// from the passed RequestProcessFunc
func Get(rp RequestProcessFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
response, err := rp(r)
Expand Down Expand Up @@ -59,6 +64,3 @@ func write(w http.ResponseWriter, r *http.Request, response *serializer.Response
w.WriteHeader(statusCode)
w.Write(content)
}

// RequestProcessFunc is the function that takes a http.Request, and returns a serializer.Response and an error
type RequestProcessFunc func(*http.Request) (*serializer.Response, error)
3 changes: 2 additions & 1 deletion server/handler/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import (
"github.com/src-d/code-annotation/server/service"
)

// Me handler returns information about current user
// Me handler returns a function that returns a *serializer.Response
// with the information about the current user
func Me(usersRepo *repository.Users) RequestProcessFunc {
return func(r *http.Request) (*serializer.Response, error) {
uID := service.GetUserID(r.Context())
Expand Down
11 changes: 10 additions & 1 deletion server/model/models.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package model

// User of the application; can be Requester or Workers
type User struct {
ID int
Login string
Expand All @@ -8,12 +9,14 @@ type User struct {
Role Role
}

// Experiment groups a certain amount of FilePairs
type Experiment struct {
ID int
Name string
Description string
}

// Assignment tracks the answer of a worker to a given FilePairs of an Experiment
type Assignment struct {
ID int
UserID int
Expand All @@ -23,6 +26,7 @@ type Assignment struct {
Duration int
}

// FilePairs are the answers that needs to be responsed
type FilePairs struct {
ID int
ExperimentID int
Expand All @@ -31,19 +35,24 @@ type FilePairs struct {
Right File
}

// File contains the info of a File
type File struct {
Name string
Hash string
Content string
}

// Role represents the position of a app User
type Role string

const (
// Requester is the role of a user that can review assignments, users, stats of experiments...
Requester Role = "requester"
Worker Role = "worker"
// Worker is the role of a user that can answer assignments
Worker Role = "worker"
)

// Answers lists the accepted answers
var Answers = map[string]string{
"yes": "yes",
"maybe": "maybe",
Expand Down
11 changes: 10 additions & 1 deletion server/repository/repositories.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//TODO: use "user.go" as a example, not this one ;)
package repository

//TODO: use "user.go" as a example, not this one ;)

import (
"fmt"

Expand All @@ -9,8 +10,11 @@ import (

var assignments []*model.Assignment

// ErrNoAssignmentsInitialized is the error returned when the Assignments of a User are requested
// for a given Experiment, but they have not been yet created
var ErrNoAssignmentsInitialized = fmt.Errorf("No assignments initialized")

// GetExperimentByID returns the Experiment identified by the passed ID
func GetExperimentByID(id int) (*model.Experiment, error) {
return &model.Experiment{
ID: id,
Expand All @@ -19,6 +23,8 @@ func GetExperimentByID(id int) (*model.Experiment, error) {
}, nil
}

// GetAssignmentsFor returns the Assignments of a given user for a certain experiment,
// and returns an ErrNoAssignmentsInitialized if they does not yet exist
func GetAssignmentsFor(userID int, experimentID int) ([]*model.Assignment, error) {
if len(assignments) == 0 {
return []*model.Assignment{}, ErrNoAssignmentsInitialized
Expand All @@ -27,6 +33,7 @@ func GetAssignmentsFor(userID int, experimentID int) ([]*model.Assignment, error
return assignments, nil
}

// CreateAssignmentsFor creates the assignments for the Experiment and User identified by the passed IDs
func CreateAssignmentsFor(userID int, experimentID int) ([]*model.Assignment, error) {
assignments = []*model.Assignment{
&model.Assignment{ID: 1, UserID: userID, PairID: 1, ExperimentID: experimentID},
Expand All @@ -42,6 +49,7 @@ func CreateAssignmentsFor(userID int, experimentID int) ([]*model.Assignment, er
return assignments, nil
}

// UpdateAssignment updates the Assignment identified by the passed ID, with the passed answer and duration
func UpdateAssignment(assignmentID int, answer string, duration int) error {
if _, ok := model.Answers[answer]; !ok {
return fmt.Errorf("Wrong answer provided: '%s'", answer)
Expand All @@ -56,6 +64,7 @@ func UpdateAssignment(assignmentID int, answer string, duration int) error {
return nil
}

// GetFilePairFor returns the FilePairs identified by the passed ID
func GetFilePairFor(pairID int) (*model.FilePairs, error) {
name := fmt.Sprintf("filePair-%d", pairID)
return &model.FilePairs{
Expand Down
4 changes: 4 additions & 0 deletions server/repository/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import (
"github.com/src-d/code-annotation/server/model"
)

// Users is the User repository
type Users struct {
users []*model.User
}

// Create stores a user into the DB
func (r *Users) Create(m *model.User) error {
for _, u := range r.users {
if u.ID == m.ID {
Expand All @@ -20,6 +22,8 @@ func (r *Users) Create(m *model.User) error {
return nil
}

// Get returns the User identified by the passed ID.
// If the user does not exist, if returns no user nor error
func (r *Users) Get(id int) (*model.User, error) {
for _, u := range r.users {
if u.ID == id {
Expand Down
1 change: 1 addition & 0 deletions server/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/sirupsen/logrus"
)

// Router returns a Handler to serve the code-anotation backend
func Router(
logger logrus.FieldLogger,
jwt *service.JWT,
Expand Down
5 changes: 5 additions & 0 deletions server/serializer/serializers.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ type experimentResponse struct {
Description string `json:"description"`
}

// NewExperimentResponse returns a Response for the passed Experiment
func NewExperimentResponse(e *model.Experiment) *Response {
return newResponse(experimentResponse{
ID: e.ID,
Expand All @@ -88,6 +89,7 @@ type assignmentResponse struct {
Duration int `json:"duration"`
}

// NewAssignmentsResponse returns a Response for the passed Assignment
func NewAssignmentsResponse(as []*model.Assignment) *Response {
assignments := make([]assignmentResponse, len(as))
for i, a := range as {
Expand All @@ -102,6 +104,7 @@ type filePairsResponse struct {
Diff string `json:"diff"`
}

// NewFilePairsResponse returns a Response for the passed FilePairs
func NewFilePairsResponse(fp *model.FilePairs) *Response {
return newResponse(filePairsResponse{fp.ID, fp.Diff})
}
Expand All @@ -113,6 +116,7 @@ type userResponse struct {
AvatarURL string `json:"avatarURL"`
}

// NewUserResponse returns a Response for the passed User
func NewUserResponse(u *model.User) *Response {
return newResponse(userResponse{u.ID, u.Login, u.Username, u.AvatarURL})
}
Expand All @@ -121,6 +125,7 @@ type countResponse struct {
Count int `json:"count"`
}

// NewCountResponse returns a Response for the total of a count
func NewCountResponse(c int) *Response {
return newResponse(countResponse{c})
}
1 change: 1 addition & 0 deletions server/service/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/sirupsen/logrus"
)

// NewLogger returns a logrus Logger
func NewLogger() logrus.FieldLogger {
logger := logrus.New()
logger.Formatter = &logrus.TextFormatter{
Expand Down