Beispiel #1
0
func ProcessIndexHandler(w http.ResponseWriter, r *http.Request) {
	session, _ := session.Get(r, "tiers")
	userid, _ := session.Values["user"]

	rows := model.GetAllUserQueues()
	defer rows.Close()

	var list []userQueue
	for rows.Next() {
		var entry userQueue
		rows.Scan(&entry.Id, &entry.Latest, &entry.Count)

		list = append(list, entry)
	}

	templates := loadTemplates(
		"header.html",
		"footer.html",
		"nav.html",
		"admin/processIndex.html",
	)

	templates.ExecuteTemplate(w, "processIndex", struct {
		User int
		List []userQueue
	}{
		User: userid.(int),
		List: list,
	})
}
Beispiel #2
0
func requireAdmin(fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		session, _ := session.Get(r, "tiers")
		userid, ok := session.Values["user"]

		if !ok || userid.(int) != 1 {
			http.Error(w, "Not found", http.StatusNotFound)
			return
		}

		fn(w, r)
	}
}
Beispiel #3
0
func ProcessQueueHandler(w http.ResponseWriter, r *http.Request) {
	session, _ := session.Get(r, "tiers")
	userid, _ := session.Values["user"]

	owner := mux.Vars(r)["owner"]
	ownerInt, _ := strconv.Atoi(owner)

	faulty := mux.Vars(r)["faulty"]
	faultyInt, _ := strconv.Atoi(faulty)
	row := model.GetQueueWithProfileById(faultyInt)
	defer row.Close()

	row.Next()
	faultyProfile := rowToQueueProfile(row)

	previous := mux.Vars(r)["previous"]
	previousInt, _ := strconv.Atoi(previous)
	row = model.GetQueueWithProfileById(previousInt)
	defer row.Close()

	row.Next()
	previousProfile := rowToQueueProfile(row)

	o := ocr.New(faultyProfile.File, 0)

	o.Split()
	o.Process()
	o.CleanUp()

	templates := loadTemplates(
		"header.html",
		"footer.html",
		"nav.html",
		"admin/processQueue.html",
	)

	templates.ExecuteTemplate(w, "processQueue", struct {
		User     int
		Owner    int
		File     string
		Faulty   userQueueEntry
		Previous userQueueEntry
		Dry      profile.Profile
	}{
		User:     userid.(int),
		Owner:    ownerInt,
		Faulty:   faultyProfile,
		Previous: previousProfile,
		Dry:      o.Profile,
	})
}
Beispiel #4
0
func UploadViewHandler(w http.ResponseWriter, r *http.Request) {
	templates := loadTemplates(
		"header.html",
		"footer.html",
		"nav.html",
		"upload.html",
	)

	session, _ := session.Get(r, "tiers")
	userid, ok := session.Values["user"]

	if !ok {
		http.Redirect(w, r, "/", 302)
		return
	}

	templates.ExecuteTemplate(w, "upload", UploadPage{
		User: userid.(int),
	})
}
Beispiel #5
0
func ProcessListHandler(w http.ResponseWriter, r *http.Request) {
	session, _ := session.Get(r, "tiers")
	userid, _ := session.Values["user"]

	owner := mux.Vars(r)["owner"]
	ownerInt, _ := strconv.Atoi(owner)
	rows := model.GetAllQueuesWithProfileByUser(ownerInt)
	defer rows.Close()

	var list []userQueueEntry
	for rows.Next() {
		e := rowToQueueProfile(rows)
		list = append(list, e)
	}

	// First entry is always seen as good.
	list[0].HasProblem = false
	for i := 1; i < len(list)-1; i++ {
		list[i].Previous = list[i-1].Id
		list[i].HasProblem = comparePrevious(list[i-1].Profile, list[i].Profile)
	}

	templates := loadTemplates(
		"header.html",
		"footer.html",
		"nav.html",
		"admin/processList.html",
	)

	templates.ExecuteTemplate(w, "processList", struct {
		User  int
		Owner int
		List  []userQueueEntry
	}{
		User:  userid.(int),
		Owner: ownerInt,
		List:  list,
	})
}
Beispiel #6
0
func LogoutHandle(w http.ResponseWriter, r *http.Request) {
	session, _ := session.Get(r, "tiers")
	userid, ok := session.Values["user"]

	if !ok {
		http.Redirect(w, r, "/", 302)
		return
	}

	u, _ := model.GetUserById(userid.(int))
	if u.GPlusId != "" {
		// Execute HTTP GET request to revoke current token
		url := "https://accounts.google.com/o/oauth2/revoke?token=" + u.AccessToken
		resp, _ := http.Get(url)
		defer resp.Body.Close()
	}

	delete(session.Values, "user")
	session.Save(r, w)

	http.Redirect(w, r, "/", 302)
}
Beispiel #7
0
func ProfileHandler(w http.ResponseWriter, r *http.Request) {
	session, _ := session.Get(r, "tiers")
	userid, ok := session.Values["user"]

	templates := loadTemplates(
		"header.html",
		"footer.html",
		"nav.html",
		"index-unauthed.html",
		"profile.html",
	)

	if ok {
		var profiles []profile.Profile

		period := mux.Vars(r)["period"]

		var p profile.Profile
		var diff profile.Profile

		queue := model.GetNumQueuedProfiles(userid.(int))

		switch period {
		case "daily":
			period = "Daily"
			p1 := model.GetNewestProfile(userid.(int))
			p2 := model.GetProfileByTimestamp(userid.(int), time.Now().AddDate(0, 0, -1).Unix())

			profiles = append(profiles, p1, p2)
		case "weekly":
			period = "Weekly"
			p1 := model.GetNewestProfile(userid.(int))
			p2 := model.GetProfileByTimestamp(userid.(int), time.Now().AddDate(0, 0, -7).Unix())

			profiles = append(profiles, p1, p2)
		case "monthly":
			period = "Monthly"
			p1 := model.GetNewestProfile(userid.(int))
			p2 := model.GetProfileByTimestamp(userid.(int), time.Now().AddDate(0, -1, 0).Unix())

			profiles = append(profiles, p1, p2)
		default:
			period = "Previous"
			profiles = model.GetNewestProfiles(userid.(int), 2)
		}

		switch len(profiles) {
		case 1:
			p = profiles[0]
		case 2:
			diff = profile.Diff(profiles[1], profiles[0])
			p = profiles[0]
		}

		templates.ExecuteTemplate(w, "profile", ProfilePage{
			User: userid.(int),
			Data: ProfilePageData{
				Period:  period,
				Profile: p,
				Diff:    diff,
				Queue:   queue,
			},
		})
	} else {
		templates.ExecuteTemplate(w, "index-unauthed", nil)
	}
}
Beispiel #8
0
func ProgressHandler(w http.ResponseWriter, r *http.Request) {
	templates := loadTemplates(
		"header.html",
		"footer.html",
		"nav.html",
		"progress.html",
	)

	session, _ := session.Get(r, "tiers")
	userid, ok := session.Values["user"]

	if !ok {
		http.Redirect(w, r, "/", 302)
		return
	}

	var view view
	view.User = userid.(int)

	limit := time.Now().Unix() - int64((time.Hour * 24 * 30).Seconds())
	profiles := model.GetAllProfiles(view.User, limit)

	if len(profiles) == 0 {
		view.Warning = "Not enough data to generate page. :("
		templates.ExecuteTemplate(w, "progress", &view)
		return
	}

	view.Queue = model.GetNumQueuedProfiles(userid.(int))

	var x = map[string][]int64{}
	var y = map[string][]int64{}

	for k := range profiles {
		p := &profiles[k]
		profile.HandleProfile(p)
		x["AP"] = append(x["AP"], p.Timestamp)
		y["AP"] = append(y["AP"], p.AP)
	}

	newestProfile := profiles[len(profiles)-1]
	if newestProfile.AP < newestProfile.NextLevel.AP {
		var ts int64

		if y["AP"][0] == y["AP"][len(y["AP"])-1] {
			ts = -1
		} else {
			slope, intercept, _ := lineaRegression(x["AP"], y["AP"])
			ts = int64(((float64(newestProfile.NextLevel.AP) - intercept) / slope)) + 1262304000
		}

		perc := (float64(int(float64(newestProfile.AP)/float64(newestProfile.NextLevel.AP)*1000)) / 10)
		view.AP = progress{
			Name: "AP",

			Tiers: []tier{
				{
					Name:       "info",
					Percentage: perc,
				},
			},

			Current:  newestProfile.AP,
			Required: newestProfile.NextLevel.AP,

			Expected: ts,
		}
	} else {
		view.AP = progress{
			Name: "AP",

			Tiers: []tier{
				{
					Name:       "info",
					Percentage: 100,
				},
			},

			Current:  newestProfile.AP,
			Required: newestProfile.NextLevel.AP,

			Expected: -2,
		}
	}

	var badges []progress

	for badgeName := range profile.BadgeRanks {
		if badgeName == "Innovator" {
			continue
		}

		badges = append(badges, progress{
			Name: badgeName,
		})
	}

	for _, badge := range badges {
		for _, p := range profiles {
			s := reflect.ValueOf(&p.Badges).Elem()
			typeOf := s.Type()

			for i := 0; i < s.NumField(); i++ {
				f := s.Field(i)
				name := typeOf.Field(i).Name
				current := f.FieldByName("Current").Int()

				if badge.Name == name && shouldIncludeBadge(badge.Name, p.Timestamp, current) {
					x[name] = append(x[name], p.Timestamp)
					y[name] = append(y[name], current)
				}
			}
		}

		if badge.Name == "Guardian" && len(x["Guardian"]) > 1 {
			var i int
			var n = len(x["Guardian"]) - 1

			xValue := x["Guardian"][n]
			yValue := y["Guardian"][n]

			for i = n - 1; i > 0; i-- {
				var curX = x["Guardian"][i]
				var curY = y["Guardian"][i]

				diff := xValue - curX
				if curY != yValue {
					if diff <= 86400 {
						xValue = curX
						yValue = curY
					}
				} else if diff > 86400 {
					i++
					break
				}
			}

			x["Guardian"] = x["Guardian"][i : n+1]
			y["Guardian"] = y["Guardian"][i : n+1]
		}

		s := reflect.ValueOf(&newestProfile.Badges).Elem()
		typeOf := s.Type()

		for i := 0; i < s.NumField(); i++ {
			f := s.Field(i)
			name := typeOf.Field(i).Name

			if badge.Name == name {
				badge.Rank = int(f.FieldByName("Rank").Int())
				badge.Current = f.FieldByName("Current").Int()
				badge.Required = f.FieldByName("Next").Int()

				if len(y[name]) > 0 && y[name][0] == y[name][len(y[name])-1] {
					badge.Expected = -2
				} else if badge.Current < badge.Required {
					slope, intercept, _ := lineaRegression(x[badge.Name], y[badge.Name])
					ts := int64(((float64(badge.Required) - intercept) / slope)) + 1262304000

					badge.Expected = ts
				} else {
					badge.Expected = -1
				}

				var total float64
				max := float64(badge.Required)
				for rank, value := range profile.BadgeRanks[name] {
					if rank <= badge.Rank {
						perc := (float64(int(float64(value)/max*1000)) / 10) - total

						badge.Tiers = append(badge.Tiers, tier{
							Name:       rankNames[rank],
							Percentage: perc,
						})

						total += perc
					}
				}

				if badge.Rank != 4 {
					badge.Tiers = append(badge.Tiers, tier{
						Name:       rankNames[badge.Rank+1],
						Percentage: (float64(int(float64(badge.Current)/max*1000)) / 10) - total,
					})
				}

				badge.Icon = fmt.Sprintf("images/badges/%s/%d.png", strings.ToLower(badge.Name), badge.Rank+1)
			}
		}

		view.NextLevel = newestProfile.NextLevel.Level
		view.Progress = append(view.Progress, badge)
	}

	var inprogress []progress
	var completed []progress
	for _, v := range view.Progress {
		switch v.Expected {
		case -1:
			completed = append(completed, v)
		default:
			inprogress = append(inprogress, v)
		}
	}

	sort.Sort(progressByExpected{inprogress})
	sort.Sort(progressByName{completed})

	view.Progress = inprogress
	view.Completed = completed

	templates.ExecuteTemplate(w, "progress", &view)
}
Beispiel #9
0
func UploadHandler(w http.ResponseWriter, r *http.Request) {
	session, _ := session.Get(r, "tiers")
	userid, ok := session.Values["user"]

	if !ok {
		return
	}

	reader, err := r.MultipartReader()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// XXX: Handle errors.
	var db, _ = sql.Open("mysql", conf.Config.Database)
	defer db.Close()

	for {
		part, err := reader.NextPart()
		if err != nil {
			break
		}

		// if part.FileName() is empty, skip this iteration.
		if part.FileName() == "" {
			continue
		}

		var fileName string
		var t time.Time
		// profile_20140815_135412_0.png
		r := regexp.MustCompile("^(ingress|profile)_(\\d+)_(\\d+)_\\d+\\.png$")
		if r.MatchString(part.FileName()) {
			m := r.FindStringSubmatch(part.FileName())
			t, _ = time.ParseInLocation("20060102150405", m[2]+m[3], time.Local)

			fileName = fmt.Sprintf("%d_%s", userid, part.FileName())
		} else {
			t = time.Now()
			fileName = fmt.Sprintf("%d_%s.png", userid, t.Format("20060102_150405"))
		}

		dst, err := os.Create(conf.Config.Cache + fileName)
		defer dst.Close()

		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		if _, err := io.Copy(dst, part); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		reader, err := os.Open(conf.Config.Cache + fileName)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		defer reader.Close()

		m, _, err := image.Decode(reader)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		width := m.Bounds().Dx()

		// XXX: Handle errors...
		db.Exec(`
			INSERT INTO tiers_queues(user_id, timestamp, file, ocr_profile)
			VALUES(?, ?, ?, ?)
		`, userid, t.Unix(), fileName, width)
	}

	var numQueue float32
	db.QueryRow(`SELECT count(id) FROM tiers_queues WHERE processed = 0`).Scan(&numQueue)

	var processTime float32
	db.QueryRow(`
		SELECT avg(processtime) AS processtime
		FROM (
			SELECT processtime
			FROM tiers_queues
			WHERE processed = 1
			ORDER BY id DESC
			LIMIT 10
		) T
	`).Scan(&processTime)

	queueText := fmt.Sprintf(
		"Your file has been added to the queue and should be processed within %.1f seconds.",
		numQueue*processTime/1000,
	)

	if r.Header.Get("X-Requested-With") == "XMLHttpRequest" {
		data, _ := json.Marshal(map[string]interface{}{
			"success": true,
			"message": queueText,
		})
		fmt.Fprintf(w, "%s", data)
	} else {
		http.Redirect(w, r, "/", 302)
	}

	queue.Queue <- true
}