Albirew/nyaa-pantsu
Albirew
/
nyaa-pantsu
Archivé
1
0
Bifurcation 0

Notification for Users (WIP)

Cette révision appartient à :
akuma06 2017-05-20 20:53:05 +02:00
Parent b3ade9f273
révision 4cbbb95e4f
9 fichiers modifiés avec 92 ajouts et 7 suppressions

Voir le fichier

@ -18,6 +18,7 @@ const (
CommentsTableName = "comments"
UploadsOldTableName = "user_uploads_old"
FilesTableName = "files"
NotificationTableName = "notifications"
// for sukebei:
//LastOldTorrentID = 2303945

Voir le fichier

@ -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
Voir le fichier

@ -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
}

Voir le fichier

@ -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
}

Voir le fichier

@ -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
}

Voir le fichier

@ -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
Voir le fichier

@ -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})
}

Voir le fichier

@ -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)

Voir le fichier

@ -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