Fix conflicts
Cette révision appartient à :
révision
108558dfdf
|
@ -1,6 +0,0 @@
|
|||
package config
|
||||
|
||||
// Constants for public models.
|
||||
const (
|
||||
UserPublicFields = "id, username, md5, description, created_at, liking_count, liked_count"
|
||||
)
|
|
@ -30,9 +30,8 @@ func GormInit(conf *config.Config) (*gorm.DB, error) {
|
|||
// db.SingularTable(true)
|
||||
if config.Environment == "DEVELOPMENT" {
|
||||
db.LogMode(true)
|
||||
// db.DropTable(&model.User{}, "UserFollower")
|
||||
db.AutoMigrate(&model.Torrents{}, &model.UsersFollowers{}, &model.User{}, &model.Role{}, &model.Language{}, &model.Comment{})
|
||||
// db.AutoMigrate(&model.Comment{})
|
||||
db.AutoMigrate(&model.User{}, &model.UserFollows{})
|
||||
db.AutoMigrate(&model.User{}, &model.Torrents{}, &model.Comment{}, &model.OldComment{})
|
||||
// db.Model(&model.User{}).AddIndex("idx_user_token", "token")
|
||||
|
||||
}
|
||||
|
|
|
@ -4,16 +4,28 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// Comment is a comment model.
|
||||
type Comment struct {
|
||||
Id int `json:"id"`
|
||||
Content string `json:"content"`
|
||||
UserId int `json:"userId"`
|
||||
Username string `json:"username"` // this is duplicate but it'll be faster rite?
|
||||
TorrentId int
|
||||
// LikingCount int `json:"likingCount"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
DeletedAt *time.Time `json:"deletedAt""`
|
||||
User User `json:"user"`
|
||||
Id uint `gorm:"column:comment_id;primary_key"`
|
||||
TorrentId uint `gorm:"column:torrent_id"`
|
||||
UserId uint `gorm:"column:user_id"`
|
||||
Content string `gorm:"column:content"`
|
||||
CreatedAt time.Time `gorm:"column:created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at"`
|
||||
|
||||
Torrent *Torrents `gorm:"ForeignKey:torrent_id"`
|
||||
User *User `gorm:"ForeignKey:user_id"`
|
||||
}
|
||||
|
||||
type OldComment struct {
|
||||
TorrentId uint `gorm:"column:torrent_id"`
|
||||
Username string `gorm:"column:username"`
|
||||
Content string `gorm:"column:content"`
|
||||
Date time.Time `gorm:"column:date"`
|
||||
|
||||
Torrent *Torrents `gorm:"ForeignKey:torrent_id"`
|
||||
}
|
||||
|
||||
func (c OldComment) TableName() string {
|
||||
// cba to rename this in the db
|
||||
return "comments_old"
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
package model
|
||||
|
||||
// Role is a role model for user permission.
|
||||
type Role struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name",sql:"size:255"`
|
||||
Description string `json:"description",sql:"size:255"`
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package model
|
||||
|
||||
//user status e.g. verified, filtered, etc
|
||||
type Status struct {
|
||||
Id int `json:"id"`
|
||||
Name string `json:"name",sql:"size:255"`
|
||||
}
|
|
@ -4,7 +4,6 @@ import (
|
|||
"github.com/ewhal/nyaa/config"
|
||||
"github.com/ewhal/nyaa/util"
|
||||
|
||||
"encoding/json"
|
||||
"html"
|
||||
"html/template"
|
||||
"strconv"
|
||||
|
@ -21,26 +20,26 @@ type Feed struct {
|
|||
}
|
||||
|
||||
type Torrents struct {
|
||||
Id int `gorm:"column:torrent_id;primary_key"`
|
||||
Name string `gorm:"column:torrent_name"`
|
||||
Category int `gorm:"column:category_id"`
|
||||
Sub_Category int `gorm:"column:sub_category_id"`
|
||||
Status int `gorm:"column:status_id"`
|
||||
Hash string `gorm:"column:torrent_hash"`
|
||||
Date int64 `gorm:"column:date"`
|
||||
Downloads int `gorm:"column:downloads"`
|
||||
Filesize int64 `gorm:"column:filesize"`
|
||||
Description string `gorm:"column:description"`
|
||||
OwnerId int `gorm:"column:owner_id"`
|
||||
OldComments []byte `gorm:"column:comments"`
|
||||
Comments []Comment `gorm:"ForeignKey:TorrentId"`
|
||||
Id uint `gorm:"column:torrent_id;primary_key"`
|
||||
Name string `gorm:"column:torrent_name"`
|
||||
Hash string `gorm:"column:torrent_hash"`
|
||||
Category int `gorm:"column:category"`
|
||||
Sub_Category int `gorm:"column:sub_category"`
|
||||
Status int `gorm:"column:status"`
|
||||
Date time.Time `gorm:"column:date"`
|
||||
UploaderId uint `gorm:"column:uploader"`
|
||||
Downloads int `gorm:"column:downloads"`
|
||||
Stardom int `gorm:"column:stardom"`
|
||||
Filesize int64 `gorm:"column:filesize"`
|
||||
Description string `gorm:"column:description"`
|
||||
WebsiteLink string `gorm:"column:website_link"`
|
||||
|
||||
Uploader *User `gorm:"ForeignKey:uploader"`
|
||||
OldComments []OldComment `gorm:"ForeignKey:torrent_id"`
|
||||
Comments []Comment `gorm:"ForeignKey:torrent_id"`
|
||||
}
|
||||
|
||||
/* We need JSON Object instead because of Magnet URL that is not in the database but generated dynamically
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
JSON Models Oject
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
/* We need JSON Object instead because of Magnet URL that is not in the database but generated dynamically */
|
||||
|
||||
type ApiResultJson struct {
|
||||
Torrents []TorrentsJson `json:"torrents"`
|
||||
|
@ -48,19 +47,10 @@ type ApiResultJson struct {
|
|||
TotalRecordCount int `json:"totalRecordCount"`
|
||||
}
|
||||
|
||||
type OldCommentsJson struct {
|
||||
C template.HTML `json:"c"`
|
||||
Us string `json:"us"`
|
||||
Un string `json:"un"`
|
||||
UI int `json:"ui"`
|
||||
T int `json:"t"`
|
||||
Av string `json:"av"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
type CommentsJson struct {
|
||||
Content template.HTML `json:"content"`
|
||||
Username string `json:"username"`
|
||||
Content template.HTML `json:"content"`
|
||||
Date time.Time `json:"date"`
|
||||
}
|
||||
|
||||
type TorrentsJson struct {
|
||||
|
@ -81,33 +71,19 @@ type TorrentsJson struct {
|
|||
|
||||
func (t *Torrents) ToJson() TorrentsJson {
|
||||
magnet := util.InfoHashToMagnet(strings.TrimSpace(t.Hash), t.Name, config.Trackers...)
|
||||
offset := 0
|
||||
var commentsJson []CommentsJson
|
||||
if len(t.OldComments) != 0 {
|
||||
b := []OldCommentsJson{}
|
||||
err := json.Unmarshal([]byte(t.OldComments), &b)
|
||||
if err == nil {
|
||||
commentsJson = make([]CommentsJson, len(t.Comments)+len(b))
|
||||
offset = len(b)
|
||||
for i, commentJson := range b {
|
||||
commentsJson[i] = CommentsJson{Content: commentJson.C,
|
||||
Username: commentJson.Un}
|
||||
}
|
||||
} else {
|
||||
commentsJson = make([]CommentsJson, len(t.Comments))
|
||||
}
|
||||
} else {
|
||||
commentsJson = make([]CommentsJson, len(t.Comments))
|
||||
for _, c := range t.OldComments {
|
||||
commentsJson = append(commentsJson, CommentsJson{Username: c.Username, Content: template.HTML(c.Content), Date: c.Date})
|
||||
}
|
||||
for i, comment := range t.Comments {
|
||||
commentsJson[i+offset] = CommentsJson{Content: template.HTML(comment.Content), Username: comment.Username}
|
||||
for _, c := range t.Comments {
|
||||
commentsJson = append(commentsJson, CommentsJson{Username: c.User.Username, Content: template.HTML(c.Content), Date: c.CreatedAt})
|
||||
}
|
||||
res := TorrentsJson{
|
||||
Id: strconv.Itoa(t.Id),
|
||||
Id: strconv.FormatUint(uint64(t.Id), 10),
|
||||
Name: html.UnescapeString(t.Name),
|
||||
Status: t.Status,
|
||||
Hash: t.Hash,
|
||||
Date: time.Unix(t.Date, 0).Format(time.RFC3339),
|
||||
Date: t.Date.Format(time.RFC3339),
|
||||
Filesize: util.FormatFilesize2(t.Filesize),
|
||||
Description: template.HTML(t.Description),
|
||||
Comments: commentsJson,
|
||||
|
|
|
@ -7,78 +7,27 @@ import (
|
|||
// omit is the bool type for omitting a field of struct.
|
||||
type omit bool
|
||||
|
||||
// User is a user model
|
||||
type User struct {
|
||||
Id uint `json:"id"`
|
||||
|
||||
Email string `json:"email" sql:"size:255;unique"`
|
||||
Password string `json:"password" sql:"size:255"`
|
||||
Username string `json:"username" sql:"size:255;unique"`
|
||||
Description string `json:"description" sql:"size:100"`
|
||||
Token string `json:"token"`
|
||||
TokenExpiration time.Time `json:"tokenExperiation"`
|
||||
|
||||
// email md5 for gravatar
|
||||
Md5 string `json:"md5"`
|
||||
|
||||
// admin
|
||||
Activation bool `json:"activation"`
|
||||
PasswordResetToken string `json:"passwordResetToken"`
|
||||
ActivationToken string `json:"activationToken"`
|
||||
PasswordResetUntil time.Time `json:"passwordResetUntil"`
|
||||
ActivateUntil time.Time `json:"activateUntil"`
|
||||
ActivatedAt time.Time `json:"activatedAt"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
DeletedAt *time.Time `json:"deletedAt"`
|
||||
LastLoginAt time.Time `json:"lastLoginAt"`
|
||||
CurrentLoginAt time.Time `json:"currentLoginAt"`
|
||||
LastLoginIp string `json:"lastLoginIp" sql:"size:100"`
|
||||
CurrentLoginIp string `json:"currentLoginIp" sql:"size:100"`
|
||||
|
||||
// Liking
|
||||
LikingCount int `json:"likingCount"`
|
||||
LikedCount int `json:"likedCount"`
|
||||
Likings []User `gorm:"foreignkey:userId;associationforeignkey:follower_id;many2many:users_followers;"`
|
||||
Liked []User `gorm:"foreignkey:follower_id;associationforeignkey:userId;many2many:users_followers;"`
|
||||
|
||||
//Connections []Connection
|
||||
|
||||
Languages string
|
||||
Roles []Role `gorm:"many2many:users_roles;"` // Many To Many, users_roles
|
||||
Torrents []Torrents `gorm:"ForeignKey:owner_id"`
|
||||
Id uint `gorm:"column:user_id;primary_key"`
|
||||
Username string `gorm:"column:username"`
|
||||
Password string `gorm:"column:password"`
|
||||
Email string `gorm:"column:email"`
|
||||
Status int `gorm:"column:status"`
|
||||
CreatedAt time.Time `gorm:"column:created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at"`
|
||||
/*Api*/Token string `gorm:"column:api_token"`
|
||||
//ApiTokenExpiry
|
||||
TokenExpiration time.Time `gorm:"column:api_token_expiry"`
|
||||
Language string `gorm:"column:language"`
|
||||
}
|
||||
|
||||
// UsersFollowers is a relation table to relate users each other.
|
||||
type UsersFollowers struct {
|
||||
UserID uint `json:"user_id"`
|
||||
FollowerID uint `json:"follower_id"`
|
||||
}
|
||||
|
||||
// PublicUser is a public user model that contains only a few information for everyone.
|
||||
type PublicUser struct {
|
||||
*User
|
||||
Email omit `json:"email,omitempty" sql:"size:255;unique"`
|
||||
Password omit `json:"password,omitempty" sql:"size:255"`
|
||||
Token omit `json:"token,omitempty"`
|
||||
TokenExpiration omit `json:"tokenExperiation,omitempty"`
|
||||
|
||||
// admin
|
||||
Activation omit `json:"activation,omitempty"`
|
||||
PasswordResetToken omit `json:"passwordResetToken,omitempty"`
|
||||
ActivationToken omit `json:"activationToken,omitempty"`
|
||||
PasswordResetUntil omit `json:"passwordResetUntil,omitempty"`
|
||||
ActivateUntil omit `json:"activateUntil,omitempty"`
|
||||
ActivatedAt omit `json:"activatedAt,omitempty"`
|
||||
UpdatedAt omit `json:"updatedAt,omitempty"`
|
||||
DeletedAt omit `json:"deletedAt,omitempty"`
|
||||
LastLoginAt omit `json:"lastLoginAt,omitempty"`
|
||||
CurrentLoginAt omit `json:"currentLoginAt,omitempty"`
|
||||
LastLoginIp omit `json:"lastLoginIp,omitempty" sql:"size:100"`
|
||||
CurrentLoginIp omit `json:"currentLoginIp,omitempty" sql:"size:100"`
|
||||
|
||||
//Connections omit `json:"connections,omitempty"`
|
||||
Languages omit `json:"languages,omitempty"`
|
||||
Roles omit `json:"roles,omitempty"`
|
||||
Torrents omit `json:"articles,omitempty"` //should user torrents not be displayed?
|
||||
User *User
|
||||
}
|
||||
|
||||
type UserFollows struct {
|
||||
User User `gorm:"ForeignKey:user_id"`
|
||||
Following User `gorm:"ForeignKey:following"`
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -188,8 +188,25 @@ div.container div.blockBody:nth-of-type(2) table tr:first-of-type th:last-of-typ
|
|||
border-radius: 0px;
|
||||
}
|
||||
|
||||
|
||||
:target {
|
||||
background-color: #585b4f;
|
||||
}
|
||||
|
||||
#mainmenu button .search_text {
|
||||
display: none;
|
||||
}
|
||||
#mainmenu .navbar-form select.form-control
|
||||
{
|
||||
width: 12rem;
|
||||
}
|
||||
.special-img
|
||||
{
|
||||
position: relative;
|
||||
top: -5px;
|
||||
float: left;
|
||||
left: -5px;
|
||||
}
|
||||
|
||||
#mainmenu .badgemenu {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
|
|
@ -192,6 +192,7 @@ div.container div.blockBody:nth-of-type(2) table tr:first-of-type th:last-of-typ
|
|||
:target {
|
||||
background-color: #e5eecc;
|
||||
}
|
||||
|
||||
#mainmenu button .search_text {
|
||||
display: none;
|
||||
}
|
||||
|
@ -207,119 +208,6 @@ div.container div.blockBody:nth-of-type(2) table tr:first-of-type th:last-of-typ
|
|||
left: -5px;
|
||||
}
|
||||
|
||||
#mainmenu .badgemenu .profile-image {
|
||||
line-height: 35px;
|
||||
}
|
||||
|
||||
#mainmenu .navbar-header, #mainmenu .navbar-nav, #mainmenu .navbar-form {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
#mainmenu .badgemenu {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
/* PROFILE PAGE */
|
||||
/* Profile container */
|
||||
.profile {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
/* Profile sidebar */
|
||||
.profile-sidebar {
|
||||
padding: 20px 0 10px 0;
|
||||
background: #182430;
|
||||
}
|
||||
|
||||
.profile-userpic img {
|
||||
float: none;
|
||||
margin: 0 auto;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
-webkit-border-radius: 50% !important;
|
||||
-moz-border-radius: 50% !important;
|
||||
border-radius: 50% !important;
|
||||
}
|
||||
|
||||
.profile-usertitle {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.profile-usertitle-name {
|
||||
color: #5a7391;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
|
||||
.profile-usertitle-job {
|
||||
text-transform: uppercase;
|
||||
color: #5b9bd1;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.profile-userbuttons {
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.profile-userbuttons .btn {
|
||||
text-transform: uppercase;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
padding: 6px 15px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.profile-userbuttons .btn:last-child {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.profile-usermenu {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.profile-usermenu ul li {
|
||||
border-bottom: 1px solid #f0f4f7;
|
||||
}
|
||||
|
||||
.profile-usermenu ul li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.profile-usermenu ul li a {
|
||||
color: #93a3b5;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.profile-usermenu ul li a i {
|
||||
margin-right: 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.profile-usermenu ul li a:hover {
|
||||
background-color: #fafcfd;
|
||||
color: #5b9bd1;
|
||||
}
|
||||
|
||||
.profile-usermenu ul li.active {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.profile-usermenu ul li.active a {
|
||||
color: #5b9bd1;
|
||||
background-color: #f6f9fb;
|
||||
border-left: 2px solid #5b9bd1;
|
||||
margin-left: -2px;
|
||||
}
|
||||
|
||||
/* Profile Content */
|
||||
.profile-content {
|
||||
padding: 20px;
|
||||
background: #fff;
|
||||
min-height: 460px;
|
||||
}
|
|
@ -100,7 +100,7 @@ func ApiUploadHandler(w http.ResponseWriter, r *http.Request) {
|
|||
Sub_Category: sub_category,
|
||||
Status: 1,
|
||||
Hash: b.Hash,
|
||||
Date: time.Now().Unix(),
|
||||
Date: time.Now(),
|
||||
Filesize: 0,
|
||||
Description: string(b.Description)}
|
||||
db.ORM.Create(&torrent)
|
||||
|
|
|
@ -15,7 +15,7 @@ func RssHandler(w http.ResponseWriter, r *http.Request) {
|
|||
created_as_time := time.Now()
|
||||
|
||||
if len(torrents) > 0 {
|
||||
created_as_time = time.Unix(torrents[0].Date, 0)
|
||||
created_as_time = torrents[0].Date
|
||||
}
|
||||
feed := &feeds.Feed{
|
||||
Title: "Nyaa Pantsu",
|
||||
|
@ -26,16 +26,15 @@ func RssHandler(w http.ResponseWriter, r *http.Request) {
|
|||
feed.Items = make([]*feeds.Item, len(torrents))
|
||||
|
||||
for i, _ := range torrents {
|
||||
timestamp_as_time := time.Unix(torrents[0].Date, 0)
|
||||
torrent_json := torrents[i].ToJson()
|
||||
feed.Items[i] = &feeds.Item{
|
||||
// need a torrent view first
|
||||
Id: "https://nyaa.pantsu.cat/view/" + strconv.Itoa(torrents[i].Id),
|
||||
Id: "https://" + config.WebAddress + "/view/" + strconv.FormatUint(uint64(torrents[i].Id), 10),
|
||||
Title: torrents[i].Name,
|
||||
Link: &feeds.Link{Href: string(torrent_json.Magnet)},
|
||||
Description: "",
|
||||
Created: timestamp_as_time,
|
||||
Updated: timestamp_as_time,
|
||||
Created: torrents[0].Date,
|
||||
Updated: torrents[0].Date,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
|
||||
var TemplateDir = "templates"
|
||||
|
||||
var homeTemplate, searchTemplate, faqTemplate, uploadTemplate, viewTemplate, viewRegisterTemplate, viewLoginTemplate, viewRegisterSuccessTemplate, viewVerifySuccessTemplate, viewProfileTemplate *template.Template
|
||||
var homeTemplate, searchTemplate, faqTemplate, uploadTemplate, viewTemplate, viewRegisterTemplate, viewLoginTemplate, viewRegisterSuccessTemplate, viewVerifySuccessTemplate *template.Template
|
||||
|
||||
type templateLoader struct {
|
||||
templ **template.Template
|
||||
|
@ -63,11 +63,6 @@ func ReloadTemplates() {
|
|||
name: "user_login",
|
||||
file: "user/login.html",
|
||||
},
|
||||
templateLoader{
|
||||
templ: &viewProfileTemplate,
|
||||
name: "user_profile",
|
||||
file: "user/profile.html",
|
||||
},
|
||||
}
|
||||
for _, templ := range templs {
|
||||
t := template.Must(template.New(templ.name).Funcs(FuncMap).ParseFiles(filepath.Join(TemplateDir, "index.html"), filepath.Join(TemplateDir, templ.file)))
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
"net/url"
|
||||
"strconv"
|
||||
"github.com/nicksnyder/go-i18n/i18n"
|
||||
"github.com/ewhal/nyaa/service/user/permission"
|
||||
)
|
||||
|
||||
var FuncMap = template.FuncMap{
|
||||
|
@ -60,9 +59,4 @@ var FuncMap = template.FuncMap{
|
|||
return template.HTML(ret)
|
||||
},
|
||||
"T": i18n.IdentityTfunc,
|
||||
"getAvatar": func (hash string, size int) string {
|
||||
return "https://www.gravatar.com/avatar/"+hash+"?s="+strconv.Itoa(size)
|
||||
},
|
||||
"CurrentOrAdmin": userPermission.CurrentOrAdmin,
|
||||
"CurrentUserIdentical": userPermission.CurrentUserIdentical,
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
type FaqTemplateVariables struct {
|
||||
Navigation Navigation
|
||||
Search SearchForm
|
||||
User *model.User
|
||||
User model.User
|
||||
URL *url.URL // For parsing Url in templates
|
||||
Route *mux.Route // For getting current route in templates
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ type FaqTemplateVariables struct {
|
|||
type NotFoundTemplateVariables struct {
|
||||
Navigation Navigation
|
||||
Search SearchForm
|
||||
User *model.User
|
||||
User model.User
|
||||
URL *url.URL // For parsing Url in templates
|
||||
Route *mux.Route // For getting current route in templates
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ type ViewTemplateVariables struct {
|
|||
Captcha captcha.Captcha
|
||||
Search SearchForm
|
||||
Navigation Navigation
|
||||
User *model.User
|
||||
User model.User
|
||||
URL *url.URL // For parsing Url in templates
|
||||
Route *mux.Route // For getting current route in templates
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ type UserRegisterTemplateVariables struct {
|
|||
FormErrors map[string][]string
|
||||
Search SearchForm
|
||||
Navigation Navigation
|
||||
User *model.User
|
||||
User model.User
|
||||
URL *url.URL // For parsing Url in templates
|
||||
Route *mux.Route // For getting current route in templates
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ type UserVerifyTemplateVariables struct {
|
|||
FormErrors map[string][]string
|
||||
Search SearchForm
|
||||
Navigation Navigation
|
||||
User *model.User
|
||||
User model.User
|
||||
URL *url.URL // For parsing Url in templates
|
||||
Route *mux.Route // For getting current route in templates
|
||||
}
|
||||
|
@ -67,17 +67,7 @@ type UserLoginFormVariables struct {
|
|||
FormErrors map[string][]string
|
||||
Search SearchForm
|
||||
Navigation Navigation
|
||||
User *model.User
|
||||
URL *url.URL // For parsing Url in templates
|
||||
Route *mux.Route // For getting current route in templates
|
||||
}
|
||||
|
||||
type UserProfileVariables struct {
|
||||
UserProfile *model.User
|
||||
FormErrors map[string][]string
|
||||
Search SearchForm
|
||||
Navigation Navigation
|
||||
User *model.User
|
||||
User model.User
|
||||
URL *url.URL // For parsing Url in templates
|
||||
Route *mux.Route // For getting current route in templates
|
||||
}
|
||||
|
@ -86,7 +76,7 @@ type HomeTemplateVariables struct {
|
|||
ListTorrents []model.TorrentsJson
|
||||
Search SearchForm
|
||||
Navigation Navigation
|
||||
User *model.User
|
||||
User model.User
|
||||
URL *url.URL // For parsing Url in templates
|
||||
Route *mux.Route // For getting current route in templates
|
||||
}
|
||||
|
@ -95,7 +85,7 @@ type UploadTemplateVariables struct {
|
|||
Upload UploadForm
|
||||
Search SearchForm
|
||||
Navigation Navigation
|
||||
User *model.User
|
||||
User model.User
|
||||
URL *url.URL
|
||||
Route *mux.Route
|
||||
}
|
||||
|
@ -146,7 +136,7 @@ func NewSearchForm(params ...string) (searchForm SearchForm) {
|
|||
return
|
||||
}
|
||||
|
||||
func GetUser(r *http.Request) *model.User {
|
||||
func GetUser(r *http.Request) model.User {
|
||||
user, _ , _ := userService.RetrieveCurrentUser(r)
|
||||
return &user
|
||||
return user
|
||||
}
|
||||
|
|
|
@ -34,12 +34,12 @@ func UploadHandler(w http.ResponseWriter, r *http.Request) {
|
|||
Sub_Category: uploadForm.SubCategoryId,
|
||||
Status: 1,
|
||||
Hash: uploadForm.Infohash,
|
||||
Date: time.Now().Unix(),
|
||||
Date: time.Now(),
|
||||
Filesize: uploadForm.Filesize, // FIXME: should set to NULL instead of 0
|
||||
Description: uploadForm.Description}
|
||||
db.ORM.Create(&torrent)
|
||||
fmt.Printf("%+v\n", torrent)
|
||||
url, err := Router.Get("view_torrent").URL("id", strconv.Itoa(torrent.Id))
|
||||
url, err := Router.Get("view_torrent").URL("id", strconv.FormatUint(uint64(torrent.Id), 10))
|
||||
if err == nil {
|
||||
http.Redirect(w, r, url.String(), 302)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
|
||||
"github.com/ewhal/nyaa/service/captcha"
|
||||
"github.com/ewhal/nyaa/service/user"
|
||||
"github.com/ewhal/nyaa/service/user/permission"
|
||||
"github.com/ewhal/nyaa/service/user/form"
|
||||
"github.com/ewhal/nyaa/util/languages"
|
||||
"github.com/ewhal/nyaa/util/modelHelper"
|
||||
|
@ -49,25 +48,7 @@ func UserLoginFormHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// Getting User Profile
|
||||
func UserProfileHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
userProfile, _, errorUser := userService.RetrieveUserForAdmin(id)
|
||||
currentUser := GetUser(r)
|
||||
view := r.URL.Query().Get("view")
|
||||
if (errorUser == nil) {
|
||||
if ((view == "edit")&&(userPermission.CurrentOrAdmin(currentUser, userProfile.Id))) {
|
||||
} else {
|
||||
languages.SetTranslationFromRequest(viewProfileTemplate, r, "en-us")
|
||||
htv := UserProfileVariables{&userProfile, form.NewErrors(), NewSearchForm(), Navigation{}, currentUser, r.URL, mux.CurrentRoute(r)}
|
||||
|
||||
err := viewProfileTemplate.ExecuteTemplate(w, "index.html", htv)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NotFoundHandler(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
// Getting View User Profile Update
|
||||
|
@ -84,7 +65,9 @@ func UserRegisterPostHandler(w http.ResponseWriter, r *http.Request) {
|
|||
err["errors"] = append(err["errors"], "Wrong captcha!")
|
||||
}
|
||||
if (len(err) == 0) {
|
||||
_, err = form.EmailValidation(r.PostFormValue("email"), err)
|
||||
if len(r.PostFormValue("email")) > 0 {
|
||||
_, err = form.EmailValidation(r.PostFormValue("email"), err)
|
||||
}
|
||||
_, err = form.ValidateUsername(r.PostFormValue("username"), err)
|
||||
if (len(err) == 0) {
|
||||
modelHelper.BindValueForm(&b, r)
|
||||
|
|
|
@ -3,6 +3,7 @@ package router
|
|||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/ewhal/nyaa/db"
|
||||
"github.com/ewhal/nyaa/model"
|
||||
|
@ -43,14 +44,13 @@ func PostCommentHandler(w http.ResponseWriter, r *http.Request) {
|
|||
currentUser := GetUser(r)
|
||||
content := p.Sanitize(r.FormValue("comment"))
|
||||
|
||||
idNum, err := strconv.Atoi(id)
|
||||
username := "れんちょん"
|
||||
userId := 0
|
||||
idNum_, err := strconv.Atoi(id)
|
||||
var idNum uint = uint(idNum_)
|
||||
var userId uint = 0
|
||||
if (currentUser.Id > 0) {
|
||||
username = currentUser.Username
|
||||
userId = int(currentUser.Id)
|
||||
userId = currentUser.Id
|
||||
}
|
||||
comment := model.Comment{Username: username, UserId: userId, Content: content, TorrentId: idNum}
|
||||
comment := model.Comment{TorrentId: idNum, UserId: userId, Content: content, CreatedAt: time.Now()}
|
||||
db.ORM.Create(&comment)
|
||||
|
||||
url, err := Router.Get("view_torrent").URL("id", id)
|
||||
|
|
|
@ -45,9 +45,16 @@ func GetFeeds() []model.Feed {
|
|||
func GetTorrentById(id string) (model.Torrents, error) {
|
||||
var torrent model.Torrents
|
||||
|
||||
if db.ORM.Where("torrent_id = ?", id).Preload("Comments").Find(&torrent).RecordNotFound() {
|
||||
if db.ORM.Where("torrent_id = ?", id).
|
||||
Preload("Comments").Preload("OldComments").
|
||||
Find(&torrent).RecordNotFound() {
|
||||
return torrent, errors.New("Article is not found.")
|
||||
}
|
||||
// .Preload("Comments.User") doesn't work
|
||||
for i := range torrent.Comments {
|
||||
torrent.Comments[i].User = new(model.User)
|
||||
db.ORM.Where("user_id = ?", torrent.Comments[i].UserId).Find(torrent.Comments[i].User)
|
||||
}
|
||||
|
||||
return torrent, nil
|
||||
}
|
||||
|
@ -55,21 +62,22 @@ func GetTorrentById(id string) (model.Torrents, error) {
|
|||
func GetTorrentsOrderBy(parameters *WhereParams, orderBy string, limit int, offset int) ([]model.Torrents, int) {
|
||||
var torrents []model.Torrents
|
||||
var count int
|
||||
conditions := "torrent_hash IS NOT NULL" // filter out broken entries
|
||||
var conditionArray []string
|
||||
if strings.HasPrefix(orderBy, "filesize") {
|
||||
// torrents w/ NULL filesize fuck up the sorting on postgres
|
||||
// TODO: fix this properly
|
||||
conditions += " AND filesize IS NOT NULL"
|
||||
conditionArray = append(conditionArray, "filesize IS NOT NULL")
|
||||
}
|
||||
|
||||
var params []interface{}
|
||||
if parameters != nil { // if there is where parameters
|
||||
if len(parameters.Conditions) > 0 {
|
||||
conditions += " AND " + parameters.Conditions
|
||||
conditionArray = append(conditionArray, parameters.Conditions)
|
||||
}
|
||||
params = parameters.Params
|
||||
}
|
||||
conditions := strings.Join(conditionArray, " AND ")
|
||||
db.ORM.Model(&torrents).Where(conditions, params...).Count(&count)
|
||||
|
||||
// build custom db query for performance reasons
|
||||
dbQuery := "SELECT * FROM torrents"
|
||||
if conditions != "" {
|
||||
dbQuery = dbQuery + " WHERE " + conditions
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"golang.org/x/crypto/bcrypt"
|
||||
formStruct "github.com/ewhal/nyaa/service/user/form"
|
||||
|
||||
"github.com/ewhal/nyaa/config"
|
||||
"github.com/ewhal/nyaa/db"
|
||||
"github.com/ewhal/nyaa/model"
|
||||
"github.com/ewhal/nyaa/util/log"
|
||||
|
@ -147,9 +146,9 @@ func CurrentUser(r *http.Request) (model.User, error) {
|
|||
return user, err
|
||||
}
|
||||
}
|
||||
if db.ORM.Select(config.UserPublicFields+", email").Where("token = ?", token).First(&user).RecordNotFound() {
|
||||
if db.ORM.Where("api_token = ?", token).First(&user).RecordNotFound() {
|
||||
return user, errors.New("User is not found.")
|
||||
}
|
||||
db.ORM.Model(&user).Association("Roles").Find(&user.Roles)
|
||||
db.ORM.Model(&user)
|
||||
return user, nil
|
||||
}
|
||||
|
|
|
@ -46,14 +46,14 @@ func IsAgreed(t_and_c string) bool {
|
|||
// RegistrationForm is used when creating a user.
|
||||
type RegistrationForm struct {
|
||||
Username string `form:"username" needed:"true" len_min:"3" len_max:"20"`
|
||||
Email string `form:"email" needed:"true"`
|
||||
Email string `form:"email"`
|
||||
Password string `form:"password" needed:"true" len_min:"6" len_max:"25" equalInput:"Confirm_Password"`
|
||||
Confirm_Password string `form:"password_confirmation" omit:"true" needed:"true"`
|
||||
CaptchaID string `form:"captchaID" omit:"true" needed:"true"`
|
||||
T_and_C bool `form:"t_and_c" omit:"true" needed:"true" equal:"true" hum_name:"Terms and Conditions"`
|
||||
}
|
||||
|
||||
// RegistrationForm is used when creating a user authentication.
|
||||
// LoginForm is used when a user logs in.
|
||||
type LoginForm struct {
|
||||
Username string `form:"username" needed="true"`
|
||||
Password string `form:"password" needed="true"`
|
||||
|
@ -80,19 +80,3 @@ type PasswordResetForm struct {
|
|||
PasswordResetToken string `form:"token"`
|
||||
Password string `form:"newPassword"`
|
||||
}
|
||||
|
||||
// VerifyEmailForm is used when verifying an email.
|
||||
type VerifyEmailForm struct {
|
||||
ActivationToken string `form:"token"`
|
||||
}
|
||||
|
||||
// ActivateForm is used when activating user.
|
||||
type ActivateForm struct {
|
||||
Activation bool `form:"activation"`
|
||||
}
|
||||
|
||||
// UserRoleForm is used when adding or removing a role from a user.
|
||||
type UserRoleForm struct {
|
||||
UserId int `form:"userId"`
|
||||
RoleId int `form:"roleId"`
|
||||
}
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
package userPermission
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"github.com/ewhal/nyaa/model"
|
||||
"github.com/ewhal/nyaa/service/user"
|
||||
"github.com/ewhal/nyaa/util/log"
|
||||
)
|
||||
|
||||
// HasAdmin checks that user has an admin permission.
|
||||
func HasAdmin(user *model.User) bool {
|
||||
name := "admin"
|
||||
for _, role := range user.Roles {
|
||||
log.Debugf("HasAdmin role.Name : %s", role.Name)
|
||||
if role.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
return user.Status == 2
|
||||
}
|
||||
|
||||
// CurrentOrAdmin check that user has admin permission or user is the current user.
|
||||
|
@ -24,10 +20,14 @@ func CurrentOrAdmin(user *model.User, userId uint) bool {
|
|||
}
|
||||
|
||||
// CurrentUserIdentical check that userId is same as current user's Id.
|
||||
func CurrentUserIdentical(user *model.User, userId uint) (bool) {
|
||||
if user.Id != userId {
|
||||
return false
|
||||
func CurrentUserIdentical(r *http.Request, userId uint) (bool, error) {
|
||||
currentUser, err := userService.CurrentUser(r)
|
||||
if err != nil {
|
||||
return false, errors.New("Auth failed.")
|
||||
}
|
||||
if currentUser.Id != userId {
|
||||
return false, errors.New("User is not identical.")
|
||||
}
|
||||
|
||||
return true
|
||||
return true, nil
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"errors"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
||||
|
@ -43,20 +44,24 @@ func SuggestUsername(username string) string {
|
|||
}
|
||||
return usernameCandidate
|
||||
}
|
||||
|
||||
func CheckEmail(email string) bool {
|
||||
if len(email) == 0 {
|
||||
return true
|
||||
}
|
||||
var count int
|
||||
db.ORM.Model(model.User{}).Where(&model.User{Email: email}).Count(&count)
|
||||
db.ORM.Model(model.User{}).Where("email = ?", email).Count(&count)
|
||||
if count == 0 {
|
||||
return false
|
||||
return false // duplicate
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// CreateUserFromForm creates a user from a registration form.
|
||||
func CreateUserFromForm(registrationForm formStruct.RegistrationForm) (model.User, error) {
|
||||
var user model.User
|
||||
log.Debugf("registrationForm %+v\n", registrationForm)
|
||||
modelHelper.AssignValue(&user, ®istrationForm)
|
||||
user.Md5 = crypto.GenerateMD5Hash(user.Email) // Gravatar
|
||||
token, err := crypto.GenerateRandomToken32()
|
||||
if err != nil {
|
||||
return user, errors.New("Token not generated.")
|
||||
|
@ -106,8 +111,8 @@ func RetrieveUser(r *http.Request, id string) (*model.PublicUser, bool, uint, in
|
|||
var isAuthor bool
|
||||
// var publicUser *model.PublicUser
|
||||
// publicUser.User = &user
|
||||
if db.ORM.Select(config.UserPublicFields).First(&user, id).RecordNotFound() {
|
||||
return &model.PublicUser{User: &user}, isAuthor, currentUserId, http.StatusNotFound, errors.New("User is not found.")
|
||||
if db.ORM.First(&user, id).RecordNotFound() {
|
||||
return nil, isAuthor, currentUserId, http.StatusNotFound, errors.New("User is not found.")
|
||||
}
|
||||
currentUser, err := CurrentUser(r)
|
||||
if err == nil {
|
||||
|
@ -115,30 +120,6 @@ func RetrieveUser(r *http.Request, id string) (*model.PublicUser, bool, uint, in
|
|||
isAuthor = currentUser.Id == user.Id
|
||||
}
|
||||
|
||||
var likings []model.User
|
||||
var likingCount int
|
||||
db.ORM.Table("users_followers").Where("users_followers.user_id=?", user.Id).Count(&likingCount)
|
||||
if err = db.ORM.Order("created_at desc").Select(config.UserPublicFields).
|
||||
Joins("JOIN users_followers on users_followers.user_id=?", user.Id).
|
||||
Where("users.id = users_followers.follower_id").
|
||||
Group("users.id").Find(&likings).Error; err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
user.Likings = likings
|
||||
|
||||
var liked []model.User
|
||||
var likedCount int
|
||||
db.ORM.Table("users_followers").Where("users_followers.follower_id=?", user.Id).Count(&likedCount)
|
||||
if err = db.ORM.Order("created_at desc").Select(config.UserPublicFields).
|
||||
Joins("JOIN users_followers on users_followers.follower_id=?", user.Id).
|
||||
Where("users.id = users_followers.user_id").
|
||||
Group("users.id").Find(&liked).Error; err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
user.Liked = liked
|
||||
|
||||
log.Debugf("user liking %v\n", user.Likings)
|
||||
log.Debugf("user liked %v\n", user.Liked)
|
||||
return &model.PublicUser{User: &user}, isAuthor, currentUserId, http.StatusOK, nil
|
||||
}
|
||||
|
||||
|
@ -146,7 +127,7 @@ func RetrieveUser(r *http.Request, id string) (*model.PublicUser, bool, uint, in
|
|||
func RetrieveUsers() []*model.PublicUser {
|
||||
var users []*model.User
|
||||
var userArr []*model.PublicUser
|
||||
db.ORM.Select(config.UserPublicFields).Find(&users)
|
||||
db.ORM.Find(&users)
|
||||
for _, user := range users {
|
||||
userArr = append(userArr, &model.PublicUser{User: user})
|
||||
}
|
||||
|
@ -155,7 +136,6 @@ func RetrieveUsers() []*model.PublicUser {
|
|||
|
||||
// UpdateUserCore updates a user. (Applying the modifed data of user).
|
||||
func UpdateUserCore(user *model.User) (int, error) {
|
||||
user.Md5 = crypto.GenerateMD5Hash(user.Email)
|
||||
token, err := crypto.GenerateRandomToken32()
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, errors.New("Token not generated.")
|
||||
|
@ -165,6 +145,7 @@ func UpdateUserCore(user *model.User) (int, error) {
|
|||
if db.ORM.Save(user).Error != nil {
|
||||
return http.StatusInternalServerError, errors.New("User is not updated.")
|
||||
}
|
||||
user.UpdatedAt = time.Now()
|
||||
return http.StatusOK, nil
|
||||
}
|
||||
|
||||
|
@ -220,49 +201,6 @@ func DeleteUser(w http.ResponseWriter, id string) (int, error) {
|
|||
return status, err
|
||||
}
|
||||
|
||||
// AddRoleToUser adds a role to a user.
|
||||
func AddRoleToUser(r *http.Request) (int, error) {
|
||||
var form formStruct.UserRoleForm
|
||||
var user model.User
|
||||
var role model.Role
|
||||
var roles []model.Role
|
||||
modelHelper.BindValueForm(&form, r)
|
||||
|
||||
if db.ORM.First(&user, form.UserId).RecordNotFound() {
|
||||
return http.StatusNotFound, errors.New("User is not found.")
|
||||
}
|
||||
if db.ORM.First(&role, form.RoleId).RecordNotFound() {
|
||||
return http.StatusNotFound, errors.New("Role is not found.")
|
||||
}
|
||||
log.Debugf("user email : %s", user.Email)
|
||||
log.Debugf("Role name : %s", role.Name)
|
||||
db.ORM.Model(&user).Association("Roles").Append(role)
|
||||
db.ORM.Model(&user).Association("Roles").Find(&roles)
|
||||
if db.ORM.Save(&user).Error != nil {
|
||||
return http.StatusInternalServerError, errors.New("Role not appended to user.")
|
||||
}
|
||||
return http.StatusOK, nil
|
||||
}
|
||||
|
||||
// RemoveRoleFromUser removes a role from a user.
|
||||
func RemoveRoleFromUser(w http.ResponseWriter, r *http.Request, userId string, roleId string) (int, error) {
|
||||
var user model.User
|
||||
var role model.Role
|
||||
if db.ORM.First(&user, userId).RecordNotFound() {
|
||||
return http.StatusNotFound, errors.New("User is not found.")
|
||||
}
|
||||
if db.ORM.First(&role, roleId).RecordNotFound() {
|
||||
return http.StatusNotFound, errors.New("Role is not found.")
|
||||
}
|
||||
|
||||
log.Debugf("user : %v\n", user)
|
||||
log.Debugf("role : %v\n", role)
|
||||
if db.ORM.Model(&user).Association("Roles").Delete(role).Error != nil {
|
||||
return http.StatusInternalServerError, errors.New("Role is not deleted from user.")
|
||||
}
|
||||
return http.StatusOK, nil
|
||||
}
|
||||
|
||||
// RetrieveCurrentUser retrieves a current user.
|
||||
func RetrieveCurrentUser(r *http.Request) (model.User, int, error) {
|
||||
user, err := CurrentUser(r)
|
||||
|
@ -275,7 +213,7 @@ func RetrieveCurrentUser(r *http.Request) (model.User, int, error) {
|
|||
// RetrieveUserByEmail retrieves a user by an email
|
||||
func RetrieveUserByEmail(email string) (*model.PublicUser, string, int, error) {
|
||||
var user model.User
|
||||
if db.ORM.Unscoped().Select(config.UserPublicFields).Where("email like ?", "%"+email+"%").First(&user).RecordNotFound() {
|
||||
if db.ORM.Unscoped().Where("email = ?", email).First(&user).RecordNotFound() {
|
||||
return &model.PublicUser{User: &user}, email, http.StatusNotFound, errors.New("User is not found.")
|
||||
}
|
||||
return &model.PublicUser{User: &user}, email, http.StatusOK, nil
|
||||
|
@ -285,7 +223,7 @@ func RetrieveUserByEmail(email string) (*model.PublicUser, string, int, error) {
|
|||
func RetrieveUsersByEmail(email string) []*model.PublicUser {
|
||||
var users []*model.User
|
||||
var userArr []*model.PublicUser
|
||||
db.ORM.Select(config.UserPublicFields).Where("email like ?", "%"+email+"%").Find(&users)
|
||||
db.ORM.Where("email = ?", email).Find(&users)
|
||||
for _, user := range users {
|
||||
userArr = append(userArr, &model.PublicUser{User: user})
|
||||
}
|
||||
|
@ -295,7 +233,7 @@ func RetrieveUsersByEmail(email string) []*model.PublicUser {
|
|||
// RetrieveUserByUsername retrieves a user by username.
|
||||
func RetrieveUserByUsername(username string) (*model.PublicUser, string, int, error) {
|
||||
var user model.User
|
||||
if db.ORM.Unscoped().Select(config.UserPublicFields).Where("username like ?", "%"+username+"%").First(&user).RecordNotFound() {
|
||||
if db.ORM.Where("username = ?", username).First(&user).RecordNotFound() {
|
||||
return &model.PublicUser{User: &user}, username, http.StatusNotFound, errors.New("User is not found.")
|
||||
}
|
||||
return &model.PublicUser{User: &user}, username, http.StatusOK, nil
|
||||
|
@ -307,8 +245,7 @@ func RetrieveUserForAdmin(id string) (model.User, int, error) {
|
|||
if db.ORM.First(&user, id).RecordNotFound() {
|
||||
return user, http.StatusNotFound, errors.New("User is not found.")
|
||||
}
|
||||
db.ORM.Model(&user).Related("Torrents").Find(&model.Torrents{})
|
||||
db.ORM.Model(&user).Association("Roles").Find(&user.Roles)
|
||||
db.ORM.Model(&user)
|
||||
return user, http.StatusOK, nil
|
||||
}
|
||||
|
||||
|
@ -318,28 +255,12 @@ func RetrieveUsersForAdmin() []model.User {
|
|||
var userArr []model.User
|
||||
db.ORM.Find(&users)
|
||||
for _, user := range users {
|
||||
db.ORM.Model(&user).Related("Torrents").Find(&model.Torrents{})
|
||||
db.ORM.Model(&user).Association("Roles").Find(&user.Roles)
|
||||
db.ORM.Model(&user)
|
||||
userArr = append(userArr, user)
|
||||
}
|
||||
return userArr
|
||||
}
|
||||
|
||||
// ActivateUser toggle activation of a user.
|
||||
func ActivateUser(r *http.Request, id string) (model.User, int, error) {
|
||||
var user model.User
|
||||
var form formStruct.ActivateForm
|
||||
modelHelper.BindValueForm(&form, r)
|
||||
if db.ORM.First(&user, id).RecordNotFound() {
|
||||
return user, http.StatusNotFound, errors.New("User is not found.")
|
||||
}
|
||||
user.Activation = form.Activation
|
||||
if db.ORM.Save(&user).Error != nil {
|
||||
return user, http.StatusInternalServerError, errors.New("User not activated.")
|
||||
}
|
||||
return user, http.StatusOK, nil
|
||||
}
|
||||
|
||||
// CreateUserAuthentication creates user authentication.
|
||||
func CreateUserAuthentication(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
var form formStruct.LoginForm
|
||||
|
|
|
@ -3,15 +3,15 @@ package userService
|
|||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"time"
|
||||
// "time"
|
||||
|
||||
"github.com/ewhal/nyaa/config"
|
||||
"github.com/ewhal/nyaa/db"
|
||||
"github.com/ewhal/nyaa/model"
|
||||
"github.com/ewhal/nyaa/util/crypto"
|
||||
// "github.com/ewhal/nyaa/util/crypto"
|
||||
"github.com/ewhal/nyaa/util/email"
|
||||
"github.com/ewhal/nyaa/util/log"
|
||||
"github.com/ewhal/nyaa/util/timeHelper"
|
||||
// "github.com/ewhal/nyaa/util/log"
|
||||
// "github.com/ewhal/nyaa/util/timeHelper"
|
||||
|
||||
"github.com/nicksnyder/go-i18n/i18n"
|
||||
)
|
||||
|
@ -28,7 +28,7 @@ func SendEmailVerfication(to string, token string, locale string) error {
|
|||
|
||||
// SendVerificationToUser sends an email verification token to user.
|
||||
func SendVerificationToUser(user model.User) (int, error) {
|
||||
var status int
|
||||
/*var status int
|
||||
var err error
|
||||
user.ActivateUntil = timeHelper.TwentyFourHoursLater()
|
||||
user.ActivationToken, err = crypto.GenerateRandomToken32()
|
||||
|
@ -45,12 +45,12 @@ func SendVerificationToUser(user model.User) (int, error) {
|
|||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
return http.StatusOK, err
|
||||
return http.StatusOK, err*/
|
||||
return 0, errors.New("NotImpl")
|
||||
}
|
||||
|
||||
// SendVerification sends an email verification token.
|
||||
func SendVerification(r *http.Request) (int, error) {
|
||||
|
||||
var user model.User
|
||||
currentUser, err := CurrentUser(r)
|
||||
if err != nil {
|
||||
|
@ -65,7 +65,7 @@ func SendVerification(r *http.Request) (int, error) {
|
|||
|
||||
// EmailVerification verifies an email of user.
|
||||
func EmailVerification(token string,w http.ResponseWriter) (int, error) {
|
||||
var user model.User
|
||||
/*var user model.User
|
||||
log.Debugf("verifyEmailForm.ActivationToken : %s", token)
|
||||
if db.ORM.Where(&model.User{ActivationToken: token}).First(&user).RecordNotFound() {
|
||||
return http.StatusNotFound, errors.New("User is not found.")
|
||||
|
@ -85,5 +85,6 @@ func EmailVerification(token string,w http.ResponseWriter) (int, error) {
|
|||
return status, err
|
||||
}
|
||||
status, err = SetCookie(w, user.Token)
|
||||
return status, err
|
||||
return status, err*/
|
||||
return 0, errors.New("NotImpl")
|
||||
}
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
<ul class="nav navbar-nav navbar-right badgemenu">
|
||||
<li class="dropdown">
|
||||
{{if gt .Id 0}}
|
||||
<a href="{{ genRoute "user_profile" "id" (print .Id) "username" .Username }}" class="dropdown-toggle profile-image" data-toggle="dropdown">
|
||||
<img src="{{ getAvatar .Md5 50 }}" class="img-circle special-img"> {{ .Username }} <b class="caret"></b></a>
|
||||
<a href="{{ genRoute "user_profile" "id" (print .Id) "username" .Username }}" class="dropdown-toggle" data-toggle="dropdown">{{ .Username }} <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{{ genRoute "user_profile" "id" (print .Id) "username" .Username }}"><i class="fa fa-cog"></i> {{T "profile"}}</a></li>
|
||||
<li class="divider"></li>
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
{{define "profile_content"}}
|
||||
{{with .UserProfile}}
|
||||
<div class="table-responsive">
|
||||
<table class="table custom-table-hover">
|
||||
<tr>
|
||||
<th>{{T "category"}}</th>
|
||||
<th>{{T "name"}}</th>
|
||||
<th>{{T "date"}}</th>
|
||||
<th>{{T "size"}}</th>
|
||||
<th>{{T "links"}}</th>
|
||||
</tr>
|
||||
{{ range .Torrents }}
|
||||
<tr class="torrent-info
|
||||
{{if eq .Status 2}}remake{{end}}
|
||||
{{if eq .Status 3}}trusted{{end}}
|
||||
{{if eq .Status 4}}aplus{{end}}">
|
||||
<!-- forced width because the <td> gets bigger randomly otherwise -->
|
||||
<td style="width:80px">
|
||||
<a href="{{$.URL.Parse (printf "/search?c=%s_%s" .Category .Sub_Category) }}">
|
||||
<img src="{{$.URL.Parse (printf "/img/torrents/%s.png" .Sub_Category) }}">
|
||||
</a>
|
||||
</td>
|
||||
<td class="name">
|
||||
<a href="{{genRoute "view_torrent" "id" .Id }}">
|
||||
{{.Name}}
|
||||
</a>
|
||||
</td>
|
||||
<td class="date date-short">{{.Date}}</td>
|
||||
<td class="filesize">{{.Filesize}}</td>
|
||||
<td>
|
||||
<a href="{{.Magnet}}" title="Magnet link">
|
||||
<span class="glyphicon glyphicon-magnet" aria-hidden="true"></span>
|
||||
</a>
|
||||
<a href="http://anicache.com/torrent/{{.Hash}}.torrent" title="Torrent file">
|
||||
<span class="glyphicon glyphicon-floppy-save" aria-hidden="true"></span>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</table>
|
||||
<nav class="torrentNav" aria-label="Page navigation">
|
||||
<ul class="pagination">
|
||||
<li><a href="{{ genRoute "search" }}?userId={{ .Id }}" aria-label="Next"><span class="glyphicon glyphicon-add"></span> {{ T "see_more_torrents_from" .Username }}</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
|
@ -7,7 +7,7 @@
|
|||
{{ genNav .Navigation .URL 10 }}
|
||||
</ul>
|
||||
</nav>
|
||||
{{ if gt (len .ListTorrents) 0 }}
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table custom-table-hover">
|
||||
<tr>
|
||||
|
@ -52,8 +52,5 @@
|
|||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
{{else}}
|
||||
<h2 style="text-align: center;">{{T "no_results_found"}}</h2>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
{{define "title"}}{{ T "profile_page" .UserProfile.Username }}{{end}}
|
||||
{{define "contclass"}}cont-view{{end}}
|
||||
{{define "content"}}
|
||||
<div class="row profile">
|
||||
{{with .UserProfile}}
|
||||
<div class="col-md-3">
|
||||
<div class="profile-sidebar">
|
||||
<!-- SIDEBAR USERPIC -->
|
||||
<div class="profile-userpic">
|
||||
<img src="{{ getAvatar .Md5 130 }}" class="img-responsive" alt="{{.Username}}">
|
||||
</div>
|
||||
<!-- END SIDEBAR USERPIC -->
|
||||
<!-- SIDEBAR USER TITLE -->
|
||||
<div class="profile-usertitle">
|
||||
<div class="profile-usertitle-name">
|
||||
{{.Username}}
|
||||
</div>
|
||||
<div class="profile-usertitle-job">
|
||||
{{if .Roles }}{{index .Roles 0 }}{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- END SIDEBAR USER TITLE -->
|
||||
<!-- SIDEBAR BUTTONS -->
|
||||
<div class="profile-userbuttons">
|
||||
{{if gt $.User.Id 0 }}
|
||||
{{if not (CurrentUserIdentical $.User .Id) }}
|
||||
<button type="button" class="btn btn-success btn-sm">{{ T "follow"}}</button>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<!-- <button type="button" class="btn btn-danger btn-sm">Message</button> -->
|
||||
</div>
|
||||
<!-- END SIDEBAR BUTTONS -->
|
||||
<!-- SIDEBAR MENU -->
|
||||
<div class="profile-usermenu">
|
||||
<ul class="nav">
|
||||
<li class="active">
|
||||
<a href="#">
|
||||
<i class="glyphicon glyphicon-home"></i>
|
||||
{{T "torrents"}} </a>
|
||||
</li>
|
||||
{{if gt $.User.Id 0 }}
|
||||
{{if CurrentOrAdmin $.User .Id }}
|
||||
<li>
|
||||
<a href="#">
|
||||
<i class="glyphicon glyphicon-user"></i>
|
||||
{{T "settings"}} </a>
|
||||
</li>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
<!-- END MENU -->
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="col-md-9">
|
||||
<div class="profile-content">
|
||||
{{ block "profile_content" . }}{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
|
@ -3,15 +3,14 @@ package languages
|
|||
import (
|
||||
"github.com/nicksnyder/go-i18n/i18n"
|
||||
"html/template"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func SetTranslation(tmpl *template.Template, language string, languages ...string) {
|
||||
T, _ := i18n.Tfunc(language, languages...)
|
||||
tmpl.Funcs(map[string]interface{}{
|
||||
"T": func(str string, args ...interface{}) template.HTML {
|
||||
return template.HTML(fmt.Sprintf(T(str), args...))
|
||||
"T": func(str string) template.HTML {
|
||||
return template.HTML(T(str))
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ type SearchParam struct {
|
|||
Max int
|
||||
Status string
|
||||
Sort string
|
||||
UserId string
|
||||
}
|
||||
|
||||
func SearchByQuery(r *http.Request, pagenum int) (SearchParam, []model.Torrents, int) {
|
||||
|
@ -38,7 +37,6 @@ func SearchByQuery(r *http.Request, pagenum int) (SearchParam, []model.Torrents,
|
|||
search_param.Status = r.URL.Query().Get("s")
|
||||
search_param.Sort = r.URL.Query().Get("sort")
|
||||
search_param.Order = r.URL.Query().Get("order")
|
||||
search_param.UserId = r.URL.Query().Get("userId")
|
||||
|
||||
catsSplit := strings.Split(search_param.Category, "_")
|
||||
// need this to prevent out of index panics
|
||||
|
@ -95,11 +93,6 @@ func SearchByQuery(r *http.Request, pagenum int) (SearchParam, []model.Torrents,
|
|||
}
|
||||
parameters.Params = append(parameters.Params, search_param.Status)
|
||||
}
|
||||
if search_param.UserId != "" {
|
||||
|
||||
conditions = append(conditions, "owner_id = ?")
|
||||
parameters.Params = append(parameters.Params, search_param.UserId)
|
||||
}
|
||||
searchQuerySplit := strings.Fields(search_param.Query)
|
||||
for i, word := range searchQuerySplit {
|
||||
firstRune, _ := utf8.DecodeRuneInString(word)
|
||||
|
|
Référencer dans un nouveau ticket