Albirew/nyaa-pantsu
Archivé
1
0
Bifurcation 0

Added Follow&Unfollow

Cette révision appartient à :
akuma06 2017-05-10 03:15:29 +02:00
Parent 8277143dfa
révision 9bbd544a20
10 fichiers modifiés avec 98 ajouts et 9 suppressions

Voir le fichier

@ -19,8 +19,8 @@ type User struct {
// TODO: move this to PublicUser // TODO: move this to PublicUser
LikingCount int `json:"likingCount" gorm:"-"` LikingCount int `json:"likingCount" gorm:"-"`
LikedCount int `json:"likedCount" gorm:"-"` LikedCount int `json:"likedCount" gorm:"-"`
Likings []User `gorm:"foreignkey:userId;associationforeignkey:follower_id;many2many:user_follows"` Likings []User // Don't work `gorm:"foreignkey:user_id;associationforeignkey:follower_id;many2many:user_follows"`
Liked []User `gorm:"foreignkey:follower_id;associationforeignkey:userId;many2many:user_follows"` Liked []User // Don't work `gorm:"foreignkey:follower_id;associationforeignkey:user_id;many2many:user_follows"`
Md5 string `json:"md5"` // Used for gravatar Md5 string `json:"md5"` // Used for gravatar
Torrents []Torrents `gorm:"ForeignKey:UploaderId"` Torrents []Torrents `gorm:"ForeignKey:UploaderId"`

Voir le fichier

@ -36,6 +36,7 @@ func init() {
gzipUserLoginPostHandler := handlers.CompressHandler(http.HandlerFunc(UserLoginPostHandler)) gzipUserLoginPostHandler := handlers.CompressHandler(http.HandlerFunc(UserLoginPostHandler))
gzipUserLogoutHandler := handlers.CompressHandler(http.HandlerFunc(UserLogoutHandler)) gzipUserLogoutHandler := handlers.CompressHandler(http.HandlerFunc(UserLogoutHandler))
gzipUserProfileHandler := handlers.CompressHandler(http.HandlerFunc(UserProfileHandler)) gzipUserProfileHandler := handlers.CompressHandler(http.HandlerFunc(UserProfileHandler))
gzipUserFollowHandler := handlers.CompressHandler(http.HandlerFunc(UserFollowHandler))
gzipUserProfileFormHandler := handlers.CompressHandler(http.HandlerFunc(UserProfileFormHandler)) gzipUserProfileFormHandler := handlers.CompressHandler(http.HandlerFunc(UserProfileFormHandler))
Router = mux.NewRouter() Router = mux.NewRouter()
@ -65,6 +66,7 @@ func init() {
Router.Handle("/user/login", gzipUserLoginPostHandler).Name("user_login").Methods("POST") Router.Handle("/user/login", gzipUserLoginPostHandler).Name("user_login").Methods("POST")
Router.Handle("/user/logout", gzipUserLogoutHandler).Name("user_logout") Router.Handle("/user/logout", gzipUserLogoutHandler).Name("user_logout")
Router.Handle("/user/{id}/{username}", gzipUserProfileHandler).Name("user_profile").Methods("GET") Router.Handle("/user/{id}/{username}", gzipUserProfileHandler).Name("user_profile").Methods("GET")
Router.Handle("/user/{id}/{username}/follow", gzipUserFollowHandler).Name("user_follow").Methods("GET")
Router.Handle("/user/{id}/{username}", gzipUserProfileFormHandler).Name("user_profile").Methods("POST") Router.Handle("/user/{id}/{username}", gzipUserProfileFormHandler).Name("user_profile").Methods("POST")
Router.PathPrefix("/captcha").Methods("GET").HandlerFunc(captcha.ServeFiles) Router.PathPrefix("/captcha").Methods("GET").HandlerFunc(captcha.ServeFiles)

Voir le fichier

@ -35,10 +35,10 @@ var FuncMap = template.FuncMap{
ret = ret + "<li><a id=\"page-prev\" href=\"" + url.String() + "?" + currentUrl.RawQuery + "\" aria-label=\"Previous\"><span aria-hidden=\"true\">&laquo;</span></a></li>" ret = ret + "<li><a id=\"page-prev\" href=\"" + url.String() + "?" + currentUrl.RawQuery + "\" aria-label=\"Previous\"><span aria-hidden=\"true\">&laquo;</span></a></li>"
} }
startValue := 1 startValue := 1
if nav.CurrentPage > pagesSelectable { if nav.CurrentPage > pagesSelectable/2 {
startValue = (int(math.Min((float64(nav.CurrentPage)+math.Floor(float64(pagesSelectable)/2)), maxPages)) - pagesSelectable + 1) startValue = (int(math.Min((float64(nav.CurrentPage)+math.Floor(float64(pagesSelectable)/2)), maxPages)) - pagesSelectable + 1)
} }
endValue := (startValue + pagesSelectable - 1) endValue := (startValue + pagesSelectable -1)
if endValue > int(maxPages) { if endValue > int(maxPages) {
endValue = int(maxPages) endValue = int(maxPages)
} }
@ -67,4 +67,5 @@ var FuncMap = template.FuncMap{
"CurrentUserIdentical": userPermission.CurrentUserIdentical, "CurrentUserIdentical": userPermission.CurrentUserIdentical,
"HasAdmin": userPermission.HasAdmin, "HasAdmin": userPermission.HasAdmin,
"GetRole": userPermission.GetRole, "GetRole": userPermission.GetRole,
"IsFollower": userPermission.IsFollower,
} }

Voir le fichier

@ -87,6 +87,7 @@ type UserLoginFormVariables struct {
type UserProfileVariables struct { type UserProfileVariables struct {
UserProfile *model.User UserProfile *model.User
FormInfos map[string][]string
Search SearchForm Search SearchForm
Navigation Navigation Navigation Navigation
User *model.User User *model.User

Voir le fichier

@ -1,7 +1,10 @@
package router package router
import ( import (
"fmt"
"net/http" "net/http"
"strconv"
"github.com/ewhal/nyaa/model" "github.com/ewhal/nyaa/model"
"github.com/ewhal/nyaa/service/captcha" "github.com/ewhal/nyaa/service/captcha"
@ -56,6 +59,10 @@ func UserProfileHandler(w http.ResponseWriter, r *http.Request) {
if (errorUser == nil) { if (errorUser == nil) {
currentUser := GetUser(r) currentUser := GetUser(r)
view := r.URL.Query()["edit"] view := r.URL.Query()["edit"]
follow := r.URL.Query()["followed"]
unfollow := r.URL.Query()["unfollowed"]
infosForm := form.NewInfos()
deleteVar := r.URL.Query()["delete"] deleteVar := r.URL.Query()["delete"]
if ((view != nil)&&(userPermission.CurrentOrAdmin(currentUser, userProfile.Id))) { if ((view != nil)&&(userPermission.CurrentOrAdmin(currentUser, userProfile.Id))) {
b := form.UserForm{} b := form.UserForm{}
@ -80,8 +87,14 @@ func UserProfileHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, errorTmpl.Error(), http.StatusInternalServerError) http.Error(w, errorTmpl.Error(), http.StatusInternalServerError)
} }
} else { } else {
languages.SetTranslationFromRequest(viewProfileTemplate, r, "en-us") T := languages.SetTranslationFromRequest(viewProfileTemplate, r, "en-us")
htv := UserProfileVariables{&userProfile, NewSearchForm(), Navigation{}, currentUser, r.URL, mux.CurrentRoute(r)} if (follow != nil) {
infosForm["infos"] = append(infosForm["infos"], fmt.Sprintf(T("user_followed_msg"), userProfile.Username))
}
if (unfollow != nil) {
infosForm["infos"] = append(infosForm["infos"], fmt.Sprintf(T("user_unfollowed_msg"), userProfile.Username))
}
htv := UserProfileVariables{&userProfile, infosForm, NewSearchForm(), Navigation{}, currentUser, r.URL, mux.CurrentRoute(r)}
err := viewProfileTemplate.ExecuteTemplate(w, "index.html", htv) err := viewProfileTemplate.ExecuteTemplate(w, "index.html", htv)
if err != nil { if err != nil {
@ -251,3 +264,23 @@ func UserLogoutHandler(w http.ResponseWriter, r *http.Request) {
url, _ := Router.Get("home").URL() url, _ := Router.Get("home").URL()
http.Redirect(w, r, url.String(), http.StatusSeeOther) http.Redirect(w, r, url.String(), http.StatusSeeOther)
} }
func UserFollowHandler(w http.ResponseWriter, r *http.Request) {
var followAction string
vars := mux.Vars(r)
id := vars["id"]
currentUser := GetUser(r)
user, _, errorUser := userService.RetrieveUserForAdmin(id)
if (errorUser == nil) {
if (!userPermission.IsFollower(&user, currentUser)) {
followAction = "followed"
userService.SetFollow(&user, currentUser)
} else {
followAction = "unfollowed"
userService.RemoveFollow(&user, currentUser)
}
}
url, _ := Router.Get("user_profile").URL("id", strconv.Itoa(int(user.Id)), "username", user.Username)
http.Redirect(w, r, url.String()+"?"+followAction, http.StatusSeeOther)
}

Voir le fichier

@ -3,6 +3,7 @@ package userPermission
import ( import (
"github.com/ewhal/nyaa/model" "github.com/ewhal/nyaa/model"
"github.com/ewhal/nyaa/util/log" "github.com/ewhal/nyaa/util/log"
"github.com/ewhal/nyaa/db"
) )
// HasAdmin checks that user has an admin permission. // HasAdmin checks that user has an admin permission.
@ -38,3 +39,12 @@ func GetRole(user *model.User) string {
} }
return "Member" return "Member"
} }
func IsFollower(user *model.User, currentUser *model.User) bool {
var likingUserCount int
db.ORM.Model(&model.UserFollows{}).Where("user_id = ? and following = ?", user.Id, currentUser.Id).Count(&likingUserCount)
if likingUserCount != 0 {
return true
}
return false
}

Voir le fichier

@ -262,6 +262,11 @@ func RetrieveUserForAdmin(id string) (model.User, int, error) {
if db.ORM.Preload("Torrents").First(&user, id).RecordNotFound() { if db.ORM.Preload("Torrents").First(&user, id).RecordNotFound() {
return user, http.StatusNotFound, errors.New("User is not found.") return user, http.StatusNotFound, errors.New("User is not found.")
} }
var liked,likings []model.User
db.ORM.Joins("JOIN user_follows on user_follows.user_id=?", user.Id).Where("users.user_id = user_follows.following").Group("users.user_id").Find(&likings)
db.ORM.Joins("JOIN user_follows on user_follows.following=?", user.Id).Where("users.user_id = user_follows.user_id").Group("users.user_id").Find(&liked)
user.Likings = likings
user.Liked = liked
return user, http.StatusOK, nil return user, http.StatusOK, nil
} }
@ -272,7 +277,7 @@ func RetrieveUsersForAdmin() []model.User {
db.ORM.Find(&users) db.ORM.Find(&users)
for _, user := range users { for _, user := range users {
db.ORM.Model(&user) db.ORM.Model(&user)
db.ORM.Model(&user).Related("Torrents").Find(&model.Torrents{}) db.ORM.Model(&user).Related("Torrents").Related("Likings").Related("Liked").Find(&model.Torrents{})
userArr = append(userArr, user) userArr = append(userArr, user)
} }
return userArr return userArr
@ -287,3 +292,17 @@ func CreateUserAuthentication(w http.ResponseWriter, r *http.Request) (int, erro
status, err := SetCookieHandler(w, username, pass) status, err := SetCookieHandler(w, username, pass)
return status, err return status, err
} }
func SetFollow(user *model.User, follower *model.User) {
if (follower.Id > 0 && user.Id > 0) {
var userFollows = model.UserFollows{UserID: user.Id, FollowerID: follower.Id}
db.ORM.Create(&userFollows)
}
}
func RemoveFollow(user *model.User, follower *model.User) {
if (follower.Id > 0 && user.Id > 0) {
var userFollows = model.UserFollows{UserID: user.Id, FollowerID: follower.Id}
db.ORM.Delete(&userFollows)
}
}

Voir le fichier

@ -1,6 +1,9 @@
{{define "title"}}{{ T "profile_page" .UserProfile.Username }}{{end}} {{define "title"}}{{ T "profile_page" .UserProfile.Username }}{{end}}
{{define "contclass"}}cont-view{{end}} {{define "contclass"}}cont-view{{end}}
{{define "content"}} {{define "content"}}
{{ range (index $.FormInfos "infos")}}
<div class="alert alert-info"><a class="panel-close close" data-dismiss="alert">×</a><i class="glyphicon glyphicon-info-sign"></i> {{ . }}</div>
{{end}}
<div class="row profile"> <div class="row profile">
{{with .UserProfile}} {{with .UserProfile}}
<div class="col-md-3"> <div class="col-md-3">
@ -24,7 +27,11 @@
<div class="profile-userbuttons"> <div class="profile-userbuttons">
{{if gt $.User.Id 0 }} {{if gt $.User.Id 0 }}
{{if not (CurrentUserIdentical $.User .Id) }} {{if not (CurrentUserIdentical $.User .Id) }}
<button type="button" class="btn btn-success btn-sm">{{ T "follow"}}</button> {{if not (IsFollower . $.User)}}
<a href="{{ genRoute "user_follow" "id" ( print .Id ) "username" .Username }}" class="btn btn-success btn-sm">{{ T "follow"}}</a>
{{else}}
<a href="{{ genRoute "user_follow" "id" ( print .Id ) "username" .Username }}" class="btn btn-danger btn-sm">{{ T "unfollow"}}</a>
{{end}}
{{end}} {{end}}
{{end}} {{end}}
<!-- <button type="button" class="btn btn-danger btn-sm">Message</button> --> <!-- <button type="button" class="btn btn-danger btn-sm">Message</button> -->

Voir le fichier

@ -24,7 +24,11 @@
<div class="profile-userbuttons"> <div class="profile-userbuttons">
{{if gt $.User.Id 0 }} {{if gt $.User.Id 0 }}
{{if not (CurrentUserIdentical $.User .Id) }} {{if not (CurrentUserIdentical $.User .Id) }}
<button type="button" class="btn btn-success btn-sm">{{ T "follow"}}</button> {{if not (IsFollower . $.User)}}
<a href="{{ genRoute "user_follow" "id" .Id }}" class="btn btn-success btn-sm">{{ T "follow"}}</a>
{{else}}
<a href="{{ genRoute "user_follow" "id" .Id }}" class="btn btn-danger btn-sm">{{ T "unfollow"}}</a>
{{end}}
{{end}} {{end}}
{{end}} {{end}}
<!-- <button type="button" class="btn btn-danger btn-sm">Message</button> --> <!-- <button type="button" class="btn btn-danger btn-sm">Message</button> -->

Voir le fichier

@ -119,6 +119,18 @@
"id":"follow", "id":"follow",
"translation": "Follow" "translation": "Follow"
}, },
{
"id":"unfollow",
"translation": "Unfollow"
},
{
"id":"user_followed_msg",
"translation": "You have followed %s!"
},
{
"id":"user_unfollowed_msg",
"translation": "You have unfollowed %s!"
},
{ {
"id":"profile_page", "id":"profile_page",
"translation": "%s Profile Page" "translation": "%s Profile Page"