Fixed User
Profile Page, badge menu, every thing before previous commit (except email) Added Logout
Cette révision appartient à :
Parent
413f713e8a
révision
84cf511fe3
14 fichiers modifiés avec 330 ajouts et 38 suppressions
|
@ -30,8 +30,7 @@ func GormInit(conf *config.Config) (*gorm.DB, error) {
|
||||||
// db.SingularTable(true)
|
// db.SingularTable(true)
|
||||||
if config.Environment == "DEVELOPMENT" {
|
if config.Environment == "DEVELOPMENT" {
|
||||||
db.LogMode(true)
|
db.LogMode(true)
|
||||||
db.AutoMigrate(&model.User{}, &model.UserFollows{})
|
db.AutoMigrate(&model.Torrents{}, &model.UsersFollowers{}, &model.User{}, &model.Comment{}, &model.OldComment{})
|
||||||
db.AutoMigrate(&model.User{}, &model.Torrents{}, &model.Comment{}, &model.OldComment{})
|
|
||||||
// db.Model(&model.User{}).AddIndex("idx_user_token", "token")
|
// db.Model(&model.User{}).AddIndex("idx_user_token", "token")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,17 +17,25 @@ type User struct {
|
||||||
UpdatedAt time.Time `gorm:"column:updated_at"`
|
UpdatedAt time.Time `gorm:"column:updated_at"`
|
||||||
/*Api*/Token string `gorm:"column:api_token"`
|
/*Api*/Token string `gorm:"column:api_token"`
|
||||||
//ApiTokenExpiry
|
//ApiTokenExpiry
|
||||||
|
|
||||||
|
// 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;"`
|
||||||
|
|
||||||
|
Md5 string `json:"md5"`
|
||||||
TokenExpiration time.Time `gorm:"column:api_token_expiry"`
|
TokenExpiration time.Time `gorm:"column:api_token_expiry"`
|
||||||
Language string `gorm:"column:language"`
|
Language string `gorm:"column:language"`
|
||||||
|
Torrents []Torrents `gorm:"ForeignKey:owner_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PublicUser struct {
|
type PublicUser struct {
|
||||||
User *User
|
User *User
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserFollows struct {
|
// UsersFollowers is a relation table to relate users each other.
|
||||||
User User `gorm:"ForeignKey:user_id"`
|
type UsersFollowers struct {
|
||||||
Following User `gorm:"ForeignKey:following"`
|
UserID uint `gorm:"column:userId"`
|
||||||
|
FollowerID uint `gorm:"column:follower_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -203,6 +203,119 @@ div.container div.blockBody:nth-of-type(2) table tr:first-of-type th:last-of-typ
|
||||||
left: -5px;
|
left: -5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#mainmenu .badgemenu .profile-image {
|
||||||
|
line-height: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#mainmenu .navbar-header, #mainmenu .navbar-nav, #mainmenu .navbar-form {
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
#mainmenu .badgemenu {
|
#mainmenu .badgemenu {
|
||||||
padding-top: 0;
|
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;
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ func init() {
|
||||||
gzipUserVerifyEmailHandler := handlers.CompressHandler(http.HandlerFunc(UserVerifyEmailHandler))
|
gzipUserVerifyEmailHandler := handlers.CompressHandler(http.HandlerFunc(UserVerifyEmailHandler))
|
||||||
gzipUserRegisterPostHandler := handlers.CompressHandler(http.HandlerFunc(UserRegisterPostHandler))
|
gzipUserRegisterPostHandler := handlers.CompressHandler(http.HandlerFunc(UserRegisterPostHandler))
|
||||||
gzipUserLoginPostHandler := handlers.CompressHandler(http.HandlerFunc(UserLoginPostHandler))
|
gzipUserLoginPostHandler := handlers.CompressHandler(http.HandlerFunc(UserLoginPostHandler))
|
||||||
|
gzipUserLogoutHandler := handlers.CompressHandler(http.HandlerFunc(UserLogoutHandler))
|
||||||
gzipUserProfileHandler := handlers.CompressHandler(http.HandlerFunc(UserProfileHandler))
|
gzipUserProfileHandler := handlers.CompressHandler(http.HandlerFunc(UserProfileHandler))
|
||||||
|
|
||||||
Router = mux.NewRouter()
|
Router = mux.NewRouter()
|
||||||
|
@ -58,6 +59,7 @@ func init() {
|
||||||
Router.Handle("/verify/email/{token}", gzipUserVerifyEmailHandler).Name("user_verify").Methods("GET")
|
Router.Handle("/verify/email/{token}", gzipUserVerifyEmailHandler).Name("user_verify").Methods("GET")
|
||||||
Router.Handle("/user/register", gzipUserRegisterPostHandler).Name("user_register").Methods("POST")
|
Router.Handle("/user/register", gzipUserRegisterPostHandler).Name("user_register").Methods("POST")
|
||||||
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/{id}/{username}", gzipUserProfileHandler).Name("user_profile").Methods("GET")
|
Router.Handle("/user/{id}/{username}", gzipUserProfileHandler).Name("user_profile").Methods("GET")
|
||||||
Router.PathPrefix("/captcha").Methods("GET").HandlerFunc(captcha.ServeFiles)
|
Router.PathPrefix("/captcha").Methods("GET").HandlerFunc(captcha.ServeFiles)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
|
|
||||||
var TemplateDir = "templates"
|
var TemplateDir = "templates"
|
||||||
|
|
||||||
var homeTemplate, searchTemplate, faqTemplate, uploadTemplate, viewTemplate, viewRegisterTemplate, viewLoginTemplate, viewRegisterSuccessTemplate, viewVerifySuccessTemplate *template.Template
|
var homeTemplate, searchTemplate, faqTemplate, uploadTemplate, viewTemplate, viewRegisterTemplate, viewLoginTemplate, viewRegisterSuccessTemplate, viewVerifySuccessTemplate, viewProfileTemplate *template.Template
|
||||||
|
|
||||||
type templateLoader struct {
|
type templateLoader struct {
|
||||||
templ **template.Template
|
templ **template.Template
|
||||||
|
@ -63,6 +63,11 @@ func ReloadTemplates() {
|
||||||
name: "user_login",
|
name: "user_login",
|
||||||
file: "user/login.html",
|
file: "user/login.html",
|
||||||
},
|
},
|
||||||
|
templateLoader{
|
||||||
|
templ: &viewProfileTemplate,
|
||||||
|
name: "user_profile",
|
||||||
|
file: "user/profile.html",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, templ := range templs {
|
for _, templ := range templs {
|
||||||
t := template.Must(template.New(templ.name).Funcs(FuncMap).ParseFiles(filepath.Join(TemplateDir, "index.html"), filepath.Join(TemplateDir, templ.file)))
|
t := template.Must(template.New(templ.name).Funcs(FuncMap).ParseFiles(filepath.Join(TemplateDir, "index.html"), filepath.Join(TemplateDir, templ.file)))
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"github.com/nicksnyder/go-i18n/i18n"
|
"github.com/nicksnyder/go-i18n/i18n"
|
||||||
|
"github.com/ewhal/nyaa/service/user/permission"
|
||||||
)
|
)
|
||||||
|
|
||||||
var FuncMap = template.FuncMap{
|
var FuncMap = template.FuncMap{
|
||||||
|
@ -59,4 +60,10 @@ var FuncMap = template.FuncMap{
|
||||||
return template.HTML(ret)
|
return template.HTML(ret)
|
||||||
},
|
},
|
||||||
"T": i18n.IdentityTfunc,
|
"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,
|
||||||
|
"GetRole": userPermission.GetRole,
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import (
|
||||||
type FaqTemplateVariables struct {
|
type FaqTemplateVariables struct {
|
||||||
Navigation Navigation
|
Navigation Navigation
|
||||||
Search SearchForm
|
Search SearchForm
|
||||||
User model.User
|
User *model.User
|
||||||
URL *url.URL // For parsing Url in templates
|
URL *url.URL // For parsing Url in templates
|
||||||
Route *mux.Route // For getting current route in templates
|
Route *mux.Route // For getting current route in templates
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ type FaqTemplateVariables struct {
|
||||||
type NotFoundTemplateVariables struct {
|
type NotFoundTemplateVariables struct {
|
||||||
Navigation Navigation
|
Navigation Navigation
|
||||||
Search SearchForm
|
Search SearchForm
|
||||||
User model.User
|
User *model.User
|
||||||
URL *url.URL // For parsing Url in templates
|
URL *url.URL // For parsing Url in templates
|
||||||
Route *mux.Route // For getting current route in templates
|
Route *mux.Route // For getting current route in templates
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ type ViewTemplateVariables struct {
|
||||||
Captcha captcha.Captcha
|
Captcha captcha.Captcha
|
||||||
Search SearchForm
|
Search SearchForm
|
||||||
Navigation Navigation
|
Navigation Navigation
|
||||||
User model.User
|
User *model.User
|
||||||
URL *url.URL // For parsing Url in templates
|
URL *url.URL // For parsing Url in templates
|
||||||
Route *mux.Route // For getting current route in templates
|
Route *mux.Route // For getting current route in templates
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ type UserRegisterTemplateVariables struct {
|
||||||
FormErrors map[string][]string
|
FormErrors map[string][]string
|
||||||
Search SearchForm
|
Search SearchForm
|
||||||
Navigation Navigation
|
Navigation Navigation
|
||||||
User model.User
|
User *model.User
|
||||||
URL *url.URL // For parsing Url in templates
|
URL *url.URL // For parsing Url in templates
|
||||||
Route *mux.Route // For getting current route in templates
|
Route *mux.Route // For getting current route in templates
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ type UserVerifyTemplateVariables struct {
|
||||||
FormErrors map[string][]string
|
FormErrors map[string][]string
|
||||||
Search SearchForm
|
Search SearchForm
|
||||||
Navigation Navigation
|
Navigation Navigation
|
||||||
User model.User
|
User *model.User
|
||||||
URL *url.URL // For parsing Url in templates
|
URL *url.URL // For parsing Url in templates
|
||||||
Route *mux.Route // For getting current route in templates
|
Route *mux.Route // For getting current route in templates
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,17 @@ type UserLoginFormVariables struct {
|
||||||
FormErrors map[string][]string
|
FormErrors map[string][]string
|
||||||
Search SearchForm
|
Search SearchForm
|
||||||
Navigation Navigation
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserProfileVariables struct {
|
||||||
|
UserProfile *model.User
|
||||||
|
FormErrors map[string][]string
|
||||||
|
Search SearchForm
|
||||||
|
Navigation Navigation
|
||||||
|
User *model.User
|
||||||
URL *url.URL // For parsing Url in templates
|
URL *url.URL // For parsing Url in templates
|
||||||
Route *mux.Route // For getting current route in templates
|
Route *mux.Route // For getting current route in templates
|
||||||
}
|
}
|
||||||
|
@ -76,7 +86,7 @@ type HomeTemplateVariables struct {
|
||||||
ListTorrents []model.TorrentsJson
|
ListTorrents []model.TorrentsJson
|
||||||
Search SearchForm
|
Search SearchForm
|
||||||
Navigation Navigation
|
Navigation Navigation
|
||||||
User model.User
|
User *model.User
|
||||||
URL *url.URL // For parsing Url in templates
|
URL *url.URL // For parsing Url in templates
|
||||||
Route *mux.Route // For getting current route in templates
|
Route *mux.Route // For getting current route in templates
|
||||||
}
|
}
|
||||||
|
@ -85,7 +95,7 @@ type UploadTemplateVariables struct {
|
||||||
Upload UploadForm
|
Upload UploadForm
|
||||||
Search SearchForm
|
Search SearchForm
|
||||||
Navigation Navigation
|
Navigation Navigation
|
||||||
User model.User
|
User *model.User
|
||||||
URL *url.URL
|
URL *url.URL
|
||||||
Route *mux.Route
|
Route *mux.Route
|
||||||
}
|
}
|
||||||
|
@ -136,7 +146,7 @@ func NewSearchForm(params ...string) (searchForm SearchForm) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUser(r *http.Request) model.User {
|
func GetUser(r *http.Request) *model.User {
|
||||||
user, _ , _ := userService.RetrieveCurrentUser(r)
|
user, _ , _ := userService.RetrieveCurrentUser(r)
|
||||||
return user
|
return &user
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"github.com/ewhal/nyaa/service/captcha"
|
"github.com/ewhal/nyaa/service/captcha"
|
||||||
"github.com/ewhal/nyaa/service/user"
|
"github.com/ewhal/nyaa/service/user"
|
||||||
"github.com/ewhal/nyaa/service/user/form"
|
"github.com/ewhal/nyaa/service/user/form"
|
||||||
|
"github.com/ewhal/nyaa/service/user/permission"
|
||||||
"github.com/ewhal/nyaa/util/languages"
|
"github.com/ewhal/nyaa/util/languages"
|
||||||
"github.com/ewhal/nyaa/util/modelHelper"
|
"github.com/ewhal/nyaa/util/modelHelper"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
@ -48,7 +49,25 @@ func UserLoginFormHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// Getting User Profile
|
// Getting User Profile
|
||||||
func UserProfileHandler(w http.ResponseWriter, r *http.Request) {
|
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
|
// Getting View User Profile Update
|
||||||
|
@ -141,6 +160,13 @@ func UserLoginPostHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logout
|
||||||
|
func UserLogoutHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
_, _ = userService.ClearCookie(w)
|
||||||
|
url, _ := Router.Get("home").URL()
|
||||||
|
http.Redirect(w, r, url.String(), http.StatusSeeOther)
|
||||||
|
}
|
||||||
|
|
||||||
// Post Profule Update controller
|
// Post Profule Update controller
|
||||||
func UserProfilePostHandler(w http.ResponseWriter, r *http.Request) {
|
func UserProfilePostHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
package userPermission
|
package userPermission
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
"github.com/ewhal/nyaa/model"
|
"github.com/ewhal/nyaa/model"
|
||||||
"github.com/ewhal/nyaa/service/user"
|
|
||||||
"github.com/ewhal/nyaa/util/log"
|
"github.com/ewhal/nyaa/util/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,14 +17,24 @@ func CurrentOrAdmin(user *model.User, userId uint) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentUserIdentical check that userId is same as current user's Id.
|
// CurrentUserIdentical check that userId is same as current user's Id.
|
||||||
func CurrentUserIdentical(r *http.Request, userId uint) (bool, error) {
|
func CurrentUserIdentical(user *model.User, userId uint) (bool) {
|
||||||
currentUser, err := userService.CurrentUser(r)
|
if user.Id != userId {
|
||||||
if err != nil {
|
return false
|
||||||
return false, errors.New("Auth failed.")
|
|
||||||
}
|
|
||||||
if currentUser.Id != userId {
|
|
||||||
return false, errors.New("User is not identical.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, nil
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRole(user *model.User) string {
|
||||||
|
switch user.Status {
|
||||||
|
case -1 :
|
||||||
|
return "Banned"
|
||||||
|
case 0 :
|
||||||
|
return "Member"
|
||||||
|
case 1 :
|
||||||
|
return "Trusted Member"
|
||||||
|
case 2 :
|
||||||
|
return "Moderator"
|
||||||
|
}
|
||||||
|
return "Member"
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@ func CreateUserFromForm(registrationForm formStruct.RegistrationForm) (model.Use
|
||||||
var user model.User
|
var user model.User
|
||||||
log.Debugf("registrationForm %+v\n", registrationForm)
|
log.Debugf("registrationForm %+v\n", registrationForm)
|
||||||
modelHelper.AssignValue(&user, ®istrationForm)
|
modelHelper.AssignValue(&user, ®istrationForm)
|
||||||
|
user.Md5 = crypto.GenerateMD5Hash(user.Email) // Gravatar
|
||||||
token, err := crypto.GenerateRandomToken32()
|
token, err := crypto.GenerateRandomToken32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return user, errors.New("Token not generated.")
|
return user, errors.New("Token not generated.")
|
||||||
|
@ -136,6 +137,7 @@ func RetrieveUsers() []*model.PublicUser {
|
||||||
|
|
||||||
// UpdateUserCore updates a user. (Applying the modifed data of user).
|
// UpdateUserCore updates a user. (Applying the modifed data of user).
|
||||||
func UpdateUserCore(user *model.User) (int, error) {
|
func UpdateUserCore(user *model.User) (int, error) {
|
||||||
|
user.Md5 = crypto.GenerateMD5Hash(user.Email)
|
||||||
token, err := crypto.GenerateRandomToken32()
|
token, err := crypto.GenerateRandomToken32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, errors.New("Token not generated.")
|
return http.StatusInternalServerError, errors.New("Token not generated.")
|
||||||
|
@ -245,7 +247,7 @@ func RetrieveUserForAdmin(id string) (model.User, int, error) {
|
||||||
if db.ORM.First(&user, id).RecordNotFound() {
|
if db.ORM.First(&user, id).RecordNotFound() {
|
||||||
return user, http.StatusNotFound, errors.New("User is not found.")
|
return user, http.StatusNotFound, errors.New("User is not found.")
|
||||||
}
|
}
|
||||||
db.ORM.Model(&user)
|
db.ORM.Model(&user).Related("Torrents").Find(&model.Torrents{})
|
||||||
return user, http.StatusOK, nil
|
return user, http.StatusOK, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,6 +258,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{})
|
||||||
userArr = append(userArr, user)
|
userArr = append(userArr, user)
|
||||||
}
|
}
|
||||||
return userArr
|
return userArr
|
||||||
|
|
|
@ -3,17 +3,18 @@
|
||||||
<ul class="nav navbar-nav navbar-right badgemenu">
|
<ul class="nav navbar-nav navbar-right badgemenu">
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
{{if gt .Id 0}}
|
{{if gt .Id 0}}
|
||||||
<a href="{{ genRoute "user_profile" "id" (print .Id) "username" .Username }}" class="dropdown-toggle" data-toggle="dropdown">{{ .Username }} <b class="caret"></b></a>
|
<a href="{{ genRoute "user_profile" "id" (print .Id) "username" .Username }}" class="dropdown-toggle profile-image" data-toggle="dropdown">
|
||||||
|
<img src="https://www.gravatar.com/avatar/{{ .Md5 }}?s=50" class="img-circle special-img"> {{ .Username }} <b class="caret"></b></a>
|
||||||
<ul class="dropdown-menu">
|
<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><a href="{{ genRoute "user_profile" "id" (print .Id) "username" .Username }}"><i class="fa fa-cog"></i> Profile</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="#soon"><i class="fa fa-sign-out"></i> {{T "sign_out"}}</a></li>
|
<li><a href="{{ genRoute "user_logout" }}"><i class="fa fa-sign-out"></i> Sign-out</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<a href="#" class="dropdown-toggle profile-image" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Member<span class="caret"></span></a>
|
<a href="#" class="dropdown-toggle profile-image" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Member<span class="caret"></span></a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="{{ genRoute "user_login" }}"><i class="fa fa-sign-out"></i> {{T "sign_in"}}</a></li>
|
<li><a href="{{ genRoute "user_login" }}"><i class="fa fa-sign-out"></i> Sign in</a></li>
|
||||||
<li><a href="{{ genRoute "user_register" }}"><i class="fa fa-cog"></i> {{T "sign_up"}}</a></li>
|
<li><a href="{{ genRoute "user_register" }}"><i class="fa fa-cog"></i> Sign Up</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
{{end}}
|
{{end}}
|
||||||
</li>
|
</li>
|
||||||
|
|
48
templates/_user_list_torrents.html
Fichier normal
48
templates/_user_list_torrents.html
Fichier normal
|
@ -0,0 +1,48 @@
|
||||||
|
{{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}}
|
62
templates/user/profile.html
Fichier normal
62
templates/user/profile.html
Fichier normal
|
@ -0,0 +1,62 @@
|
||||||
|
{{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">
|
||||||
|
{{GetRole . }}
|
||||||
|
</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}}
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"github.com/nicksnyder/go-i18n/i18n"
|
"github.com/nicksnyder/go-i18n/i18n"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Référencer dans un nouveau ticket