Notification for Users (WIP)
Cette révision appartient à :
Parent
b3ade9f273
révision
4cbbb95e4f
9 fichiers modifiés avec 92 ajouts et 7 suppressions
|
@ -18,6 +18,7 @@ const (
|
|||
CommentsTableName = "comments"
|
||||
UploadsOldTableName = "user_uploads_old"
|
||||
FilesTableName = "files"
|
||||
NotificationTableName = "notifications"
|
||||
|
||||
// for sukebei:
|
||||
//LastOldTorrentID = 2303945
|
||||
|
|
|
@ -54,7 +54,7 @@ func GormInit(conf *config.Config, logger Logger) (*gorm.DB, error) {
|
|||
db.SetLogger(logger)
|
||||
}
|
||||
|
||||
db.AutoMigrate(&model.User{}, &model.UserFollows{}, &model.UserUploadsOld{})
|
||||
db.AutoMigrate(&model.User{}, &model.UserFollows{}, &model.UserUploadsOld{}, &model.Notification{})
|
||||
if db.Error != nil {
|
||||
return db, db.Error
|
||||
}
|
||||
|
|
23
model/notification.go
Fichier normal
23
model/notification.go
Fichier normal
|
@ -0,0 +1,23 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"github.com/NyaaPantsu/nyaa/config"
|
||||
)
|
||||
|
||||
type Notification struct {
|
||||
ID uint
|
||||
Content string
|
||||
Read bool
|
||||
Identifier string
|
||||
UserID uint
|
||||
// User *User `gorm:"AssociationForeignKey:UserID;ForeignKey:user_id"` // Don't think that we need it here
|
||||
}
|
||||
|
||||
func NewNotification(identifier string, c string) Notification {
|
||||
return Notification{Identifier: identifier, Content: c}
|
||||
}
|
||||
|
||||
func (n *Notification) TableName() string {
|
||||
return config.NotificationTableName
|
||||
}
|
||||
|
|
@ -86,6 +86,10 @@ func (t Torrent) TableName() string {
|
|||
return config.TorrentsTableName
|
||||
}
|
||||
|
||||
func (t Torrent) Identifier() string {
|
||||
return "torrent_"+strconv.Itoa(int(t.ID))
|
||||
}
|
||||
|
||||
func (t Torrent) IsNormal() bool {
|
||||
return t.Status == TorrentStatusNormal
|
||||
}
|
||||
|
|
|
@ -26,13 +26,14 @@ type User struct {
|
|||
Language string `gorm:"column:language"`
|
||||
|
||||
// TODO: move this to PublicUser
|
||||
LikingCount int `json:"likingCount" gorm:"-"`
|
||||
LikedCount int `json:"likedCount" gorm:"-"`
|
||||
Likings []User // Don't work `gorm:"foreignkey:user_id;associationforeignkey:follower_id;many2many:user_follows"`
|
||||
Liked []User // Don't work `gorm:"foreignkey:follower_id;associationforeignkey:user_id;many2many:user_follows"`
|
||||
|
||||
MD5 string `json:"md5" gorm:"column:md5"` // Hash of email address, used for Gravatar
|
||||
Torrents []Torrent `gorm:"ForeignKey:UploaderID"`
|
||||
|
||||
UnreadNotifications int // We don't want to loop every notifications when accessing user unread notif
|
||||
Notifications []Notification `gorm:"ForeignKey:UserID"`
|
||||
}
|
||||
|
||||
type UserJSON struct {
|
||||
|
@ -72,6 +73,17 @@ func (u User) IsModerator() bool {
|
|||
return u.Status == UserStatusModerator
|
||||
}
|
||||
|
||||
func (u User) GetUnreadNotifications() int {
|
||||
if u.UnreadNotifications == 0 {
|
||||
for _, notif := range u.Notifications {
|
||||
if !notif.Read {
|
||||
u.UnreadNotifications++
|
||||
}
|
||||
}
|
||||
}
|
||||
return u.UnreadNotifications
|
||||
}
|
||||
|
||||
type PublicUser struct {
|
||||
User *User
|
||||
}
|
||||
|
@ -98,8 +110,8 @@ func (u *User) ToJSON() UserJSON {
|
|||
Username: u.Username,
|
||||
Status: u.Status,
|
||||
CreatedAt: u.CreatedAt.Format(time.RFC3339),
|
||||
LikingCount: u.LikingCount,
|
||||
LikedCount: u.LikedCount,
|
||||
LikingCount: len(u.Likings),
|
||||
LikedCount: len(u.Liked),
|
||||
}
|
||||
return json
|
||||
}
|
||||
|
|
|
@ -8,7 +8,9 @@ import (
|
|||
"github.com/NyaaPantsu/nyaa/db"
|
||||
"github.com/NyaaPantsu/nyaa/model"
|
||||
"github.com/NyaaPantsu/nyaa/service/captcha"
|
||||
"github.com/NyaaPantsu/nyaa/service/notifier"
|
||||
"github.com/NyaaPantsu/nyaa/service/upload"
|
||||
"github.com/NyaaPantsu/nyaa/service/user"
|
||||
"github.com/NyaaPantsu/nyaa/service/user/permission"
|
||||
"github.com/NyaaPantsu/nyaa/util/languages"
|
||||
msg "github.com/NyaaPantsu/nyaa/util/messages"
|
||||
|
@ -75,6 +77,18 @@ func UploadPostHandler(w http.ResponseWriter, r *http.Request) {
|
|||
UploaderID: user.ID}
|
||||
db.ORM.Create(&torrent)
|
||||
|
||||
if (user.ID > 0) { // If we are a member
|
||||
userService.GetLiked(user) // We populate the liked field for users
|
||||
if len(user.Liked) > 0 { // If we are followed by at least someone
|
||||
for _, follower := range user.Liked {
|
||||
T, _, _ := languages.TfuncAndLanguageWithFallback(user.Language, user.Language) // We need to send the notification to every user in their language
|
||||
|
||||
notifierService.NotifyUser(&follower, torrent.Identifier(), T("new_torrent_uploaded", torrent.Name, user.Username))
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add filelist to files db, if we have one
|
||||
if len(uploadForm.FileList) > 0 {
|
||||
for _, uploadedFile := range uploadForm.FileList {
|
||||
|
|
18
service/notifier/notifier.go
Fichier normal
18
service/notifier/notifier.go
Fichier normal
|
@ -0,0 +1,18 @@
|
|||
package notifierService
|
||||
|
||||
import (
|
||||
"github.com/NyaaPantsu/nyaa/db"
|
||||
"github.com/NyaaPantsu/nyaa/model"
|
||||
)
|
||||
|
||||
|
||||
func NotifyUser(user *model.User, name string, msg string) {
|
||||
if (user.ID > 0) {
|
||||
user.Notifications = append(user.Notifications, model.NewNotification(name, msg))
|
||||
// TODO: Email notification
|
||||
}
|
||||
}
|
||||
|
||||
func ToggleReadNotification(identifier string, id uint) { //
|
||||
db.ORM.Model(&model.Notification{}).Where("identifier = ? AND user_id = ?", identifier, id).Updates(model.Notification{Read: true})
|
||||
}
|
|
@ -141,7 +141,7 @@ func CurrentUser(r *http.Request) (model.User, error) {
|
|||
if userFromContext.ID > 0 && user_id == userFromContext.ID {
|
||||
user = userFromContext
|
||||
} else {
|
||||
if db.ORM.Where("user_id = ?", user_id).First(&user).RecordNotFound() {
|
||||
if db.ORM.Preload("Notifications").Where("user_id = ?", user_id).First(&user).RecordNotFound() { // We only load unread notifications
|
||||
return user, errors.New("User not found")
|
||||
} else {
|
||||
setUserToContext(r, user)
|
||||
|
|
|
@ -280,7 +280,7 @@ func RetrieveOldUploadsByUsername(username string) ([]uint, error) {
|
|||
// RetrieveUserForAdmin retrieves a user for an administrator.
|
||||
func RetrieveUserForAdmin(id string) (model.User, int, error) {
|
||||
var user model.User
|
||||
if db.ORM.Preload("Torrents").Last(&user, id).RecordNotFound() {
|
||||
if db.ORM.Preload("Notifications").Preload("Torrents").Last(&user, id).RecordNotFound() {
|
||||
return user, http.StatusNotFound, errors.New("user not found")
|
||||
}
|
||||
var liked, likings []model.User
|
||||
|
@ -300,6 +300,19 @@ func RetrieveUsersForAdmin(limit int, offset int) ([]model.User, int) {
|
|||
return users, nbUsers
|
||||
}
|
||||
|
||||
func GetLiked(user *model.User) *model.User {
|
||||
var liked []model.User
|
||||
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.Liked = liked
|
||||
return user
|
||||
}
|
||||
func GetLikings(user *model.User) *model.User {
|
||||
var 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)
|
||||
user.Likings = likings
|
||||
return user
|
||||
}
|
||||
|
||||
// CreateUserAuthentication creates user authentication.
|
||||
func CreateUserAuthentication(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
var form formStruct.LoginForm
|
||||
|
|
Référencer dans un nouveau ticket