예제 #1
0
func handleViewFormalRecomm(resp http.ResponseWriter, req *http.Request) {
	user_id, _ := public.GetSessionUserId(req)

	appDb := public.GetNewApplicationDatabase()
	defer appDb.Session.Close()

	recomms := appDb.C(public.APPLICATION_DB_RECOMM_COLLECTION)
	q := recomms.Find(bson.M{
		"recommender": user_id,
	})
	var result []public.RecommView
	recomm_item := db.RecommEntity{}
	it := q.Iter()
	for it.Next(&recomm_item) {

		signed_url := ""
		if client, err := storage.GetNewStorageClient(); err == nil {
			expireTime := time.Now().Add(time.Duration(1) * time.Hour) //an hour
			signed_url, _ = client.GetNewSignedURL(string(recomm_item.Attachment), expireTime)
		}

		result = append(result, public.RecommView{
			Hash:         recomm_item.Hash,
			ApplyUser:    recomm_item.ApplyUser,
			Topic:        recomm_item.Topic,
			LastModified: recomm_item.LastModified,
			Content:      recomm_item.Content,
			Attachment:   signed_url,
		})
	}

	public.ResponseOkAsJson(resp, &result)
}
예제 #2
0
func handleGMRecommsResend(resp http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	hash := vars["recommHash"]

	appDb := public.GetNewApplicationDatabase()
	defer appDb.Session.Close()

	recomm := appDb.C(public.APPLICATION_DB_RECOMM_COLLECTION)
	q := recomm.Find(bson.M{
		"hash": hash,
	})
	recommObj := db.Recomm{}
	if err := q.One(&recommObj); err != nil || len(hash) <= 0 {
		public.ResponseStatusAsJson(resp, 404, &public.SimpleResult{
			Message:     "Error",
			Description: "No Such page",
		})
		return
	}

	url := "https://application.nthuaplus.org/recomm.html?hash=" + hash
	if e := public.SendMail(recommObj.Recommender.Email, recommObj.ApplyUser, url); e != nil {
		public.LogE.Printf("Error sending email: %s\n", e.Error())
		public.ResponseStatusAsJson(resp, 500, &public.SimpleResult{
			Message: "Error",
		})
	} else {
		public.ResponseOkAsJson(resp, nil)
	}
}
예제 #3
0
func handleSubmitRecomm(resp http.ResponseWriter, req *http.Request) {

	user_id, _ := public.GetSessionUserId(req)
	user_perm, _ := public.GetSessionUserPermission(req)

	vars := mux.Vars(req)
	hash_str := vars["hash"]

	stagingDb := public.GetNewStagingDatabase()
	defer stagingDb.Session.Close()

	staging_recomm := stagingDb.C(public.APPLICATION_DB_RECOMM_COLLECTION)

	q := staging_recomm.Find(bson.M{
		"hash": hash_str,
	})

	recomm_result := db.RecommEntity{}
	if e := q.One(&recomm_result); e != nil {
		public.ResponseStatusAsJson(resp, 404, &public.SimpleResult{
			Message: "No such recomm entity",
		})
		return
	}

	// Permission check
	if recomm_result.Recommender != user_id && user_perm != public.USER_PERMISSION_GM {
		public.ResponseStatusAsJson(resp, 403, nil)
		return
	}

	// Migrate from staging db to application db
	staging_recomm.RemoveId(recomm_result.Id)

	appDb := public.GetNewApplicationDatabase()
	defer appDb.Session.Close()

	recomm := appDb.C(public.APPLICATION_DB_RECOMM_COLLECTION)
	new_recomm := recomm_result
	new_recomm.Id = bson.NewObjectId()
	new_recomm.LastModified = time.Now()

	if e := recomm.Insert(new_recomm); e != nil {
		public.LogE.Printf("Error migrating recomm from staging db to application db: %s\n", e.Error())
		public.ResponseStatusAsJson(resp, 500, &public.SimpleResult{
			Message: "Submit failed",
		})
	}
}
예제 #4
0
func getUserRecomms(resp http.ResponseWriter, req *http.Request) {
	user_id, _ := public.GetSessionUserId(req)

	appDb := public.GetNewApplicationDatabase()
	defer appDb.Session.Close()

	forms := appDb.C(public.APPLICATION_DB_FORM_COLLECTION)
	q := forms.Find(bson.M{"ownerid": user_id}).Sort("-timestamp")
	it := q.Iter()

	form := db.ApplicationForm{}
	var recommList []public.RecommResult
	topicMap := make(map[public.TopicId]bool)
	for it.Next(&form) {
		if _, exist := topicMap[form.Topic]; exist {
			//Skip
			continue
		}

		recomm := appDb.C(public.APPLICATION_DB_RECOMM_COLLECTION)

		for _, h := range form.Recommendations {
			//Transform recommendation from hash to structures
			q := recomm.Find(bson.M{
				"hash": h,
			})

			if n, e := q.Count(); e == nil && n > 0 {
				r := db.Recomm{}
				if e := q.One(&r); e == nil {
					r := public.RecommResult{
						Recommender: r.Recommender,
						ApplyUser:   r.ApplyUser,
						Done:        r.Submitted,
						Hash:        h,
					}
					recommList = append(recommList, r)
				}
			}
		}

		topicMap[form.Topic] = true
	}

	public.ResponseOkAsJson(resp, &recommList)
}
예제 #5
0
func handleViewRecomm(resp http.ResponseWriter, req *http.Request) {
	user_id, _ := public.GetSessionUserId(req)
	user_perm, _ := public.GetSessionUserPermission(req)

	vars := mux.Vars(req)
	hash_str := vars["hash"]

	appDb := public.GetNewApplicationDatabase()
	defer appDb.Session.Close()

	recomm := appDb.C(public.APPLICATION_DB_RECOMM_COLLECTION)
	q := recomm.Find(bson.M{
		"hash": hash_str,
	})

	recomm_result := db.RecommEntity{}
	if e := q.One(&recomm_result); e != nil {
		public.ResponseStatusAsJson(resp, 404, &public.SimpleResult{
			Message: "No such recomm entity",
		})
		return
	}

	// Permission check
	if recomm_result.Recommender != user_id && user_perm != public.USER_PERMISSION_GM {
		public.ResponseStatusAsJson(resp, 403, nil)
		return
	}

	signed_url := ""
	if client, err := storage.GetNewStorageClient(); err == nil {
		expireTime := time.Now().Add(time.Duration(1) * time.Hour) //an hour
		signed_url, _ = client.GetNewSignedURL(string(recomm_result.Attachment), expireTime)
	}

	public.ResponseOkAsJson(resp, &public.RecommView{
		Hash:         recomm_result.Hash,
		ApplyUser:    recomm_result.ApplyUser,
		Topic:        recomm_result.Topic,
		LastModified: recomm_result.LastModified,
		Content:      recomm_result.Content,
		Attachment:   signed_url,
	})
}
예제 #6
0
func handleRecommendationUpload(resp http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	hash := vars["hash"]

	appDb := public.GetNewApplicationDatabase()
	defer appDb.Session.Close()

	recomm := appDb.C(public.APPLICATION_DB_RECOMM_COLLECTION)
	q := recomm.Find(bson.M{
		"hash": hash,
	})
	if n, err := q.Count(); err != nil || n <= 0 || len(hash) <= 0 {
		public.ResponseStatusAsJson(resp, 404, &public.SimpleResult{
			Message:     "Error",
			Description: "No Such page",
		})
		return
	}

	handleFormFileUpload(resp, req)
}
예제 #7
0
func handleRecommendationLetters(letters []public.BasicUser, name, email string) []string {
	var hashList []string

	appDb := public.GetNewApplicationDatabase()
	defer appDb.Session.Close()

	recomm := appDb.C(public.APPLICATION_DB_RECOMM_COLLECTION)
	for _, l := range letters {
		r := db.Recomm{

			Hash: public.NewSecureHashString(),

			Submitted: false,

			ApplyUser: public.BasicUser{
				Name:  name,
				Email: email,
			},
			Recommender: public.BasicUser{
				Name:  l.Name,
				Email: l.Email,
			},
		}
		if e := recomm.Insert(&r); e != nil {
			public.LogE.Printf("Failed inserting recommendation entity for applyer %s", name)
		} else {
			hashList = append(hashList, r.Hash)

			url := "https://application.nthuaplus.org/recomm.html?hash=" + r.Hash

			applier := r.ApplyUser
			applier.Name = public.ConvertName(applier.Name)
			if e := public.SendMail(l.Email, applier, url); e != nil {
				public.LogE.Println("Error sending email to " + l.Email + ": " + e.Error())
			}
		}
	}

	return hashList
}
예제 #8
0
func handleReviewerRecommView(resp http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	hashStr := vars["recommHash"]

	appDb := public.GetNewApplicationDatabase()
	defer appDb.Session.Close()

	recomm := appDb.C(public.APPLICATION_DB_RECOMM_COLLECTION)

	q := recomm.Find(bson.M{
		"hash": hashStr,
	})
	recommInstance := db.Recomm{}
	if err := q.One(&recommInstance); err != nil {
		public.ResponseStatusAsJson(resp, 404, &public.SimpleResult{
			Message:     "Error",
			Description: "Hash not found",
		})
		return
	}

	recommResult := reviewerRecommResult{
		Content: recommInstance.Content,
	}

	if len(recommInstance.Attachment) > 0 {
		//Create temp url
		if client, err := storage.GetNewStorageClient(); err == nil {
			expireTime := time.Now().Add(time.Duration(1) * time.Hour) //an hour
			if obj, e := client.GetNewSignedURL(recommInstance.Attachment, expireTime); e == nil {
				recommResult.AttachmentUrl = obj
			} else {
				public.LogE.Println("Get object error: " + e.Error())
			}
		}
	}

	public.ResponseOkAsJson(resp, &recommResult)
}
예제 #9
0
/**
	POST/PUT:	submit
	GET(or else):	Get info
**/
func handleRecommendation(resp http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	hash := vars["hash"]

	appDb := public.GetNewApplicationDatabase()
	defer appDb.Session.Close()

	recomm := appDb.C(public.APPLICATION_DB_RECOMM_COLLECTION)
	q := recomm.Find(bson.M{
		"hash": hash,
	})
	if n, err := q.Count(); err != nil || n <= 0 || len(hash) <= 0 {
		public.ResponseStatusAsJson(resp, 404, &public.SimpleResult{
			Message:     "Error",
			Description: "No Such page",
		})
		return
	}

	result := db.Recomm{}
	if err := q.One(&result); err != nil {
		public.LogE.Printf("Error fetching recommendation data for %s\n", hash)
		public.ResponseStatusAsJson(resp, 500, &public.SimpleResult{
			Message: "Error",
		})
		return
	}

	if req.Method == "POST" || req.Method == "PUT" {
		//Submit
		if result.Submitted { //Already submitted
			public.ResponseStatusAsJson(resp, 400, &public.SimpleResult{
				Message: "Error",
			})
			return
		}

		textContent := req.FormValue("textContent")
		fileObj := req.FormValue("fileObj")

		result.Content = textContent
		result.Attachment = fileObj
		result.Submitted = true
		err := recomm.UpdateId(result.Id, &result)
		if err != nil {
			public.LogE.Println("Update recommendation fields error: " + err.Error())
			public.ResponseStatusAsJson(resp, 500, &public.SimpleResult{
				Message: "Error",
			})
		} else {
			public.ResponseOkAsJson(resp, &public.SimpleResult{
				Message: "Success",
			})
		}
	} else {
		//Get info
		displayResult := public.RecommResult{
			Recommender: result.Recommender,
			ApplyUser:   result.ApplyUser,
			Done:        result.Submitted,
		}
		public.ResponseOkAsJson(resp, &displayResult)
	}
}
예제 #10
0
func handleFormView(resp http.ResponseWriter, req *http.Request) {
	userId, _ := public.GetSessionUserId(req)

	appDb := public.GetNewApplicationDatabase()
	defer appDb.Session.Close()

	forms := appDb.C(public.APPLICATION_DB_FORM_COLLECTION)
	q := forms.Find(bson.M{
		"ownerid": userId,
	})
	if _, e := q.Count(); e != nil {
		public.LogE.Println("Query user form error: " + e.Error())
		public.ResponseStatusAsJson(resp, 500, &public.SimpleResult{
			Message: "Error",
		})
	} else {

		var formResults []exportApplication
		form := db.ApplicationForm{}
		it := q.Iter()

		for it.Next(&form) {
			exportForm := exportApplication{}
			(&exportForm).fromDbApplication(&form, false)
			formResults = append(formResults, exportForm)
		}

		public.ResponseOkAsJson(resp, formResults)

		/*
			if client, err := storage.GetNewStorageClient(); err == nil {
				defer client.Close()
				var formResults []db.ApplicationForm
				form := db.ApplicationForm{}

				it := q.Iter()
				expireTime := time.Now().Add(time.Duration(1) * time.Hour) //an hour
				for it.Next(&form) {
					form.Id = bson.ObjectId("")
					form.OwnerId = bson.ObjectId("")

					//Handle the file objects
					if obj,e := client.GetNewSignedURL(form.ResearchPlan, expireTime); e == nil {
						form.ResearchPlan = obj
					}else{
						public.LogE.Println("Get object error: " + e.Error())
					}
					if obj,e := client.GetNewSignedURL(form.Transcript, expireTime); e == nil {
						form.Transcript = obj
					}else{
						public.LogE.Println("Get object error: " + e.Error())
					}
					if len(form.Others) > 0 {
						if obj,e := client.GetNewSignedURL(form.Others, expireTime); e == nil {
							form.Others = obj
						}else{
							public.LogE.Println("Get object error: " + e.Error())
						}
					}

					formResults = append(formResults, form)
				}

				public.ResponseOkAsJson(resp, formResults)
			}else{
				public.LogE.Println("Error getting storage client: " + err.Error())
				public.ResponseStatusAsJson(resp, 500, &public.SimpleResult{
					Message: "Error",
				})
			}
		*/
	}
}
예제 #11
0
func (this *exportApplication) fromDbApplication(form *db.ApplicationForm, isReviewer bool) {
	this.Timestamp = form.Timestamp

	this.Name = form.Name
	this.School = form.School
	this.Department = form.Department
	this.SchoolGrade = form.SchoolGrade
	this.Birthday = form.Birthday
	this.FormalId = form.FormalId
	this.Phone = form.Phone
	this.Email = form.Email
	this.Address = form.Address

	this.Topic = form.Topic
	this.Teacher = form.Teacher
	this.ResearchArea = form.ResearchArea
	this.ClassHistories = form.ClassHistories
	this.RelatedSkills = form.RelatedSkills
	this.AcademicGrade = form.AcademicGrade
	this.LangAbilities = form.LangAbilities

	//Hash
	this.Hash = public.NewSecureHashString()

	//Extras
	//Transform file id to url
	if client, err := storage.GetNewStorageClient(); err == nil {

		expireTime := time.Now().Add(time.Duration(1) * time.Hour) //an hour
		if obj, e := client.GetNewSignedURL(form.ResearchPlan, expireTime); e == nil {
			this.ResearchPlan = obj
		} else {
			public.LogE.Println("Get object error: " + e.Error())
		}
		if obj, e := client.GetNewSignedURL(form.Transcript, expireTime); e == nil {
			this.Transcript = obj
		} else {
			public.LogE.Println("Get object error: " + e.Error())
		}
		if len(form.Others) > 0 {
			if obj, e := client.GetNewSignedURL(form.Others, expireTime); e == nil {
				this.Others = obj
			} else {
				public.LogE.Println("Get object error: " + e.Error())
			}
		}
	} else {
		public.LogE.Printf("Error getting storage client")
	}

	appDb := public.GetNewApplicationDatabase()
	defer appDb.Session.Close()
	recomm := appDb.C(public.APPLICATION_DB_RECOMM_COLLECTION)
	var recommList []public.RecommResult

	for _, h := range form.Recommendations {
		//Transform recommendation from hash to structures
		q := recomm.Find(bson.M{
			"hash": h,
		})

		if n, e := q.Count(); e == nil && n > 0 {
			r := db.Recomm{}
			if e := q.One(&r); e == nil {
				r := public.RecommResult{
					Recommender: r.Recommender,
					ApplyUser:   r.ApplyUser,
					Done:        r.Submitted,
				}
				if isReviewer {
					r.Hash = h
				} else {
					r.Hash = ""
				}
				recommList = append(recommList, r)
			}
		}
	}
	this.Recommendations = recommList
}
예제 #12
0
func handleFormSubmit(resp http.ResponseWriter, req *http.Request) {
	ownerId, _ := public.GetSessionUserId(req)

	form := db.ApplicationForm{
		OwnerId:   ownerId,
		Timestamp: time.Now(),

		Name:       req.FormValue("name"),
		School:     req.FormValue("school"),
		Department: req.FormValue("department"),
		Email:      req.FormValue("email"),
		Phone:      req.FormValue("phoneNumber"),
		Address:    req.FormValue("address"),
		FormalId:   req.FormValue("formalId"), //TODO: Verify

		Teacher:       req.FormValue("teacher"),
		ResearchArea:  req.FormValue("researchArea"),
		RelatedSkills: req.FormValue("relatedSkills"),

		ResearchPlan: req.FormValue("researchPlan"),
		Transcript:   req.FormValue("transcript"),
		Others:       req.FormValue("others"),
	}

	if topic, err := parseTopic(req); err != nil {
		public.LogE.Println(err.Error())
		public.ResponseStatusAsJson(resp, 400, &public.SimpleResult{
			Message:     "Error",
			Description: "Wrong form format",
		})
		return
	} else {
		form.Topic = public.TopicId(topic)
	}

	if grade, err := parseSchoolGrade(req); err != nil {
		public.LogE.Println(err.Error())
		public.ResponseStatusAsJson(resp, 400, &public.SimpleResult{
			Message:     "Error",
			Description: "Wrong form format",
		})
		return
	} else {
		form.SchoolGrade = grade
	}

	if birthday, err := parseBirthday(req); err != nil {
		public.LogE.Println(err.Error())
		public.ResponseStatusAsJson(resp, 400, &public.SimpleResult{
			Message:     "Error",
			Description: "Wrong form format",
		})
		return
	} else {
		form.Birthday = birthday
	}

	if classes, err := parseStudiedClasses(req); err != nil {
		public.LogE.Println(err.Error())
		public.ResponseStatusAsJson(resp, 400, &public.SimpleResult{
			Message:     "Error",
			Description: "Wrong form format",
		})
		return
	} else {
		form.ClassHistories = classes
	}

	if languages, err := parseLanguageAbility(req); err != nil {
		public.LogE.Println(err.Error())
		public.ResponseStatusAsJson(resp, 400, &public.SimpleResult{
			Message:     "Error",
			Description: "Wrong form format",
		})
		return
	} else {
		form.LangAbilities = languages
	}

	if average, ranking, err := parseAcademicGrades(req); err != nil {
		public.LogE.Println(err.Error())
		public.ResponseStatusAsJson(resp, 400, &public.SimpleResult{
			Message:     "Error",
			Description: "Wrong form format",
		})
		return
	} else {
		form.AcademicGrade = db.AcademicGrade{
			Average: average,
			Rank:    ranking,
		}
	}

	if letters, err := parseRecommendationLetters(req); err != nil {
		public.LogE.Println(err.Error())
		public.ResponseStatusAsJson(resp, 400, &public.SimpleResult{
			Message:     "Error",
			Description: "Wrong form format",
		})
		return
	} else {
		form.Recommendations = handleRecommendationLetters(letters, form.Name, form.Email)
	}

	appDb := public.GetNewApplicationDatabase()
	defer appDb.Session.Close()

	forms := appDb.C(public.APPLICATION_DB_FORM_COLLECTION)
	if err := forms.Insert(&form); err != nil {
		public.LogE.Printf("Insert new form error: " + err.Error())
		public.ResponseStatusAsJson(resp, 500, &public.SimpleResult{
			Message:     "Error",
			Description: "Add Form Error",
		})
	} else {
		public.ResponseOkAsJson(resp, &public.SimpleResult{
			Message: "Success",
		})
	}
}
예제 #13
0
func handleGetReviewApplications(resp http.ResponseWriter, req *http.Request) {
	userId, _ := public.GetSessionReviewerId(req)

	reviewerDb := public.GetNewReviewerDatabase()
	defer reviewerDb.Session.Close()

	profile := reviewerDb.C(REVIEWER_DB_PROFILE_COLLECTION)

	q := profile.FindId(userId)
	if c, err := q.Count(); c == 0 || err != nil {
		r := public.SimpleResult{
			Message:     "Error",
			Description: "User Not Found",
		}
		public.ResponseStatusAsJson(resp, 500, &r)
	} else {
		reviewer := db.Reviewer{}
		q.One(&reviewer)

		appDb := public.GetNewApplicationDatabase()
		defer appDb.Session.Close()

		forms := appDb.C(public.APPLICATION_DB_FORM_COLLECTION)
		results := reviewerDb.C(REVIEWER_DB_RESULT_COLLECTION)

		var exportApps []exportApplication
		for _, t := range reviewer.Topics {
			q := forms.Find(bson.M{
				"topic": t,
			}).Sort("-timestamp") //From new to old

			//Remove the duplicate application
			//Keep the latest one
			ownerSet := make(map[bson.ObjectId]bool)

			it := q.Iter()
			appData := db.ApplicationForm{}
			for it.Next(&appData) {

				if _, ok := ownerSet[appData.OwnerId]; ok {
					//Exist duplicate application
					continue
				}

				//Check if reviewed
				q_r := results.Find(bson.M{
					"applicationid": appData.Id,
				})
				if n, _ := q_r.Count(); n > 0 {
					//Has reviewed
					continue
				}

				exportApp := exportApplication{}
				(&exportApp).fromDbApplication(&appData, true)
				exportApps = append(exportApps, exportApp)

				exportAppHashMap[exportApp.Hash] = appData.Id

				ownerSet[appData.OwnerId] = true
			}
		}

		//Output reviewed topics
		public.ResponseOkAsJson(resp, &exportApps)
	}
}
예제 #14
0
func handleApplicationStatus(resp http.ResponseWriter, req *http.Request) {
	appDb := public.GetNewApplicationDatabase()
	defer appDb.Session.Close()

	appC := appDb.C(public.APPLICATION_DB_FORM_COLLECTION)
	q := appC.Find(bson.M{})

	result := resultAppStatus{
		TotalApplicationNum: 0,
		TopicsNum:           make([]int, len(TOPICS), len(TOPICS)),

		AccountNum:         0,
		AccountNotApplyNum: 0,
	}
	form := db.ApplicationForm{}
	it := q.Iter()
	for it.Next(&form) {
		result.TotalApplicationNum++

		switch uint(form.Topic) {
		case 0:
			result.TopicsNum[0] += 1
			break

		case 1:
			result.TopicsNum[1] += 1
			break

		case 2:
			result.TopicsNum[2] += 1
			break

		case 3:
			result.TopicsNum[3] += 1
			break

		case 4:
			result.TopicsNum[4] += 1
			break
		}
	}

	userDb := public.GetNewUserDatabase()
	defer userDb.Session.Close()

	profileC := userDb.C(USER_DB_PROFILE_COLLECTION)
	q = profileC.Find(bson.M{})
	it = q.Iter()

	userResult := db.User{}
	for it.Next(&userResult) {
		result.AccountNum += 1

		appQ := appC.Find(bson.M{
			"ownerid": userResult.Id,
		})
		if n, _ := appQ.Count(); n < 1 {
			result.AccountNotApplyNum += 1
		}
	}

	public.ResponseOkAsJson(resp, &result)
}