Merge pull request #436 from sfan5/treassign
Modpanel: Torrent Reassigning
Cette révision appartient à :
révision
8dd9f59cf5
8 fichiers modifiés avec 198 ajouts et 8 suppressions
|
@ -5,6 +5,7 @@ import (
|
|||
"html"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/ewhal/nyaa/db"
|
||||
"github.com/ewhal/nyaa/model"
|
||||
|
@ -21,6 +22,83 @@ import (
|
|||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
type ReassignForm struct {
|
||||
AssignTo uint
|
||||
By string
|
||||
Data string
|
||||
|
||||
Torrents []uint
|
||||
}
|
||||
|
||||
func (f *ReassignForm) ExtractInfo(r *http.Request) error {
|
||||
f.By = r.FormValue("by")
|
||||
if f.By != "olduser" && f.By != "torrentid" {
|
||||
return fmt.Errorf("what?")
|
||||
}
|
||||
|
||||
f.Data = strings.Trim(r.FormValue("data"), " \r\n")
|
||||
if f.By == "olduser" {
|
||||
if f.Data == "" {
|
||||
return fmt.Errorf("No username given")
|
||||
} else if strings.Contains(f.Data, "\n") {
|
||||
return fmt.Errorf("More than one username given")
|
||||
}
|
||||
} else if f.By == "torrentid" {
|
||||
if f.Data == "" {
|
||||
return fmt.Errorf("No IDs given")
|
||||
}
|
||||
splitData := strings.Split(f.Data, "\n")
|
||||
for i, tmp := range splitData {
|
||||
tmp = strings.Trim(tmp, " \r")
|
||||
torrent_id, err := strconv.ParseUint(tmp, 10, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Couldn't parse number on line %d", i+1)
|
||||
}
|
||||
f.Torrents = append(f.Torrents, uint(torrent_id))
|
||||
}
|
||||
}
|
||||
|
||||
tmp := r.FormValue("to")
|
||||
parsed, err := strconv.ParseUint(tmp, 10, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.AssignTo = uint(parsed)
|
||||
_, _, _, _, err = userService.RetrieveUser(r, tmp)
|
||||
if err != nil {
|
||||
return fmt.Errorf("User to assign to doesn't exist")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *ReassignForm) ExecuteAction() (int, error) {
|
||||
|
||||
var toBeChanged []uint
|
||||
var err error
|
||||
if f.By == "olduser" {
|
||||
toBeChanged, err = userService.RetrieveOldUploadsByUsername(f.Data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
} else if f.By == "torrentid" {
|
||||
toBeChanged = f.Torrents
|
||||
}
|
||||
|
||||
num := 0
|
||||
for _, torrent_id := range toBeChanged {
|
||||
torrent, err2 := torrentService.GetRawTorrentById(torrent_id)
|
||||
if err2 == nil {
|
||||
torrent.UploaderID = f.AssignTo
|
||||
db.ORM.Save(&torrent)
|
||||
num += 1
|
||||
}
|
||||
}
|
||||
// TODO: clean shit from user_uploads_old if needed
|
||||
return num, nil
|
||||
}
|
||||
|
||||
|
||||
func IndexModPanel(w http.ResponseWriter, r *http.Request) {
|
||||
currentUser := GetUser(r)
|
||||
if userPermission.HasAdmin(currentUser) {
|
||||
|
@ -271,3 +349,43 @@ func TorrentReportDeleteModPanel(w http.ResponseWriter, r *http.Request) {
|
|||
http.Error(w, "admins only", http.StatusForbidden)
|
||||
}
|
||||
}
|
||||
|
||||
func TorrentReassignModPanel(w http.ResponseWriter, r *http.Request) {
|
||||
currentUser := GetUser(r)
|
||||
if !userPermission.HasAdmin(currentUser) {
|
||||
http.Error(w, "admins only", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
languages.SetTranslationFromRequest(panelTorrentReassign, r, "en-us")
|
||||
|
||||
htv := PanelTorrentReassignVbs{ReassignForm{}, NewSearchForm(), currentUser, form.NewErrors(), form.NewInfos(), r.URL}
|
||||
err := panelTorrentReassign.ExecuteTemplate(w, "admin_index.html", htv)
|
||||
log.CheckError(err)
|
||||
}
|
||||
|
||||
func TorrentPostReassignModPanel(w http.ResponseWriter, r *http.Request) {
|
||||
currentUser := GetUser(r)
|
||||
if !userPermission.HasAdmin(currentUser) {
|
||||
http.Error(w, "admins only", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
var rForm ReassignForm
|
||||
err := form.NewErrors()
|
||||
infos := form.NewInfos()
|
||||
|
||||
err2 := rForm.ExtractInfo(r)
|
||||
if err2 != nil {
|
||||
err["errors"] = append(err["errors"], err2.Error())
|
||||
} else {
|
||||
count, err2 := rForm.ExecuteAction()
|
||||
if err2 != nil {
|
||||
err["errors"] = append(err["errors"], "Something went wrong")
|
||||
} else {
|
||||
infos["infos"] = append(infos["infos"], fmt.Sprintf("%d torrents updated.", count))
|
||||
}
|
||||
}
|
||||
|
||||
htv := PanelTorrentReassignVbs{rForm, NewSearchForm(), currentUser, err, infos, r.URL}
|
||||
err_ := panelTorrentReassign.ExecuteTemplate(w, "admin_index.html", htv)
|
||||
log.CheckError(err_)
|
||||
}
|
||||
|
|
|
@ -101,17 +101,14 @@ func init() {
|
|||
Router.HandleFunc("/mod/torrent/delete", TorrentDeleteModPanel).Name("mod_tdelete")
|
||||
Router.HandleFunc("/mod/report/delete", TorrentReportDeleteModPanel).Name("mod_trdelete")
|
||||
Router.HandleFunc("/mod/comment/delete", CommentDeleteModPanel).Name("mod_cdelete")
|
||||
Router.HandleFunc("/mod/reassign", TorrentReassignModPanel).Name("mod_treassign").Methods("GET")
|
||||
Router.HandleFunc("/mod/reassign", TorrentPostReassignModPanel).Name("mod_treassign").Methods("POST")
|
||||
|
||||
//reporting a torrent
|
||||
Router.HandleFunc("/report/{id}", ReportTorrentHandler).Methods("POST").Name("post_comment")
|
||||
|
||||
Router.PathPrefix("/captcha").Methods("GET").HandlerFunc(captcha.ServeFiles)
|
||||
|
||||
//Router.HandleFunc("/report/create", gzipTorrentReportCreateHandler).Name("torrent_report_create").Methods("POST")
|
||||
// TODO Allow only moderators to access /moderation/*
|
||||
//Router.HandleFunc("/moderation/report/delete", gzipTorrentReportDeleteHandler).Name("torrent_report_delete").Methods("POST")
|
||||
//Router.HandleFunc("/moderation/torrent/delete", gzipTorrentDeleteHandler).Name("torrent_delete").Methods("POST")
|
||||
|
||||
Router.HandleFunc("/language", SeeLanguagesHandler).Methods("GET").Name("see_languages")
|
||||
Router.HandleFunc("/language", ChangeLanguageHandler).Methods("POST").Name("change_language")
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ var TemplateDir = "templates"
|
|||
|
||||
var homeTemplate, searchTemplate, faqTemplate, uploadTemplate, viewTemplate, viewRegisterTemplate, viewLoginTemplate, viewRegisterSuccessTemplate, viewVerifySuccessTemplate, viewProfileTemplate, viewProfileEditTemplate, viewUserDeleteTemplate, notFoundTemplate, changeLanguageTemplate *template.Template
|
||||
|
||||
var panelIndex, panelTorrentList, panelUserList, panelCommentList, panelTorrentEd, panelTorrentReportList *template.Template
|
||||
var panelIndex, panelTorrentList, panelUserList, panelCommentList, panelTorrentEd, panelTorrentReportList, panelTorrentReassign *template.Template
|
||||
|
||||
type templateLoader struct {
|
||||
templ **template.Template
|
||||
|
@ -127,6 +127,11 @@ func ReloadTemplates() {
|
|||
name: "torrent_report",
|
||||
file: filepath.Join("admin", "torrent_report.html"),
|
||||
},
|
||||
templateLoader{
|
||||
templ: &panelTorrentReassign,
|
||||
name: "torrent_reassign",
|
||||
file: filepath.Join("admin", "reassign.html"),
|
||||
},
|
||||
}
|
||||
|
||||
for idx := range modTempls {
|
||||
|
|
|
@ -157,6 +157,7 @@ type PanelCommentListVbs struct {
|
|||
User *model.User
|
||||
URL *url.URL // For parsing Url in templates
|
||||
}
|
||||
|
||||
type PanelTorrentEdVbs struct {
|
||||
Upload UploadForm
|
||||
Search SearchForm
|
||||
|
@ -174,6 +175,15 @@ type PanelTorrentReportListVbs struct {
|
|||
URL *url.URL // For parsing Url in templates
|
||||
}
|
||||
|
||||
type PanelTorrentReassignVbs struct {
|
||||
Reassign ReassignForm
|
||||
Search SearchForm // unused?
|
||||
User *model.User // unused?
|
||||
FormErrors map[string][]string
|
||||
FormInfos map[string][]string
|
||||
URL *url.URL // For parsing Url in templates
|
||||
}
|
||||
|
||||
/*
|
||||
* Variables used by the upper ones
|
||||
*/
|
||||
|
|
|
@ -71,7 +71,7 @@ func GetTorrentById(id string) (torrent model.Torrent, err error) {
|
|||
torrent.Uploader = new(model.User)
|
||||
db.ORM.Where("user_id = ?", torrent.UploaderID).Find(torrent.Uploader)
|
||||
torrent.OldUploader = ""
|
||||
if torrent.ID <= config.LastOldTorrentID {
|
||||
if torrent.ID <= config.LastOldTorrentID && torrent.UploaderID == 0 {
|
||||
var tmp model.UserUploadsOld
|
||||
if !db.ORM.Where("torrent_id = ?", torrent.ID).Find(&tmp).RecordNotFound() {
|
||||
torrent.OldUploader = tmp.Username
|
||||
|
@ -88,6 +88,15 @@ func GetTorrentById(id string) (torrent model.Torrent, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// won't fetch user or comments
|
||||
func GetRawTorrentById(id uint) (torrent model.Torrent, err error) {
|
||||
err = nil
|
||||
if db.ORM.Where("torrent_id = ?", id).Find(&torrent).RecordNotFound() {
|
||||
err = errors.New("Article is not found.")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetTorrentsOrderByNoCount(parameters *serviceBase.WhereParams, orderBy string, limit int, offset int) (torrents []model.Torrent, err error) {
|
||||
torrents, _, err = getTorrentsOrderBy(parameters, orderBy, limit, offset, false)
|
||||
return
|
||||
|
|
|
@ -253,6 +253,19 @@ func RetrieveUserByUsername(username string) (*model.PublicUser, string, int, er
|
|||
return &model.PublicUser{User: &user}, username, http.StatusOK, nil
|
||||
}
|
||||
|
||||
func RetrieveOldUploadsByUsername(username string) ([]uint, error) {
|
||||
var ret []uint
|
||||
var tmp []*model.UserUploadsOld
|
||||
err := db.ORM.Where("username = ?", username).Find(&tmp).Error
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
for _, tmp2 := range tmp {
|
||||
ret = append(ret, tmp2.TorrentId)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// RetrieveUserForAdmin retrieves a user for an administrator.
|
||||
func RetrieveUserForAdmin(id string) (model.User, int, error) {
|
||||
var user model.User
|
||||
|
|
32
templates/admin/reassign.html
Fichier normal
32
templates/admin/reassign.html
Fichier normal
|
@ -0,0 +1,32 @@
|
|||
{{define "title"}}Torrent Reassign{{end}}
|
||||
{{define "content"}}
|
||||
<form enctype="multipart/form-data" method="POST">
|
||||
{{ range (index $.FormInfos "infos")}}
|
||||
<div class="alert alert-info"><a class="panel-close close" data-dismiss="alert">×</a><i class="glyphicon glyphicon-info-sign"></i> {{ . }}</div>
|
||||
{{end}}
|
||||
{{ range (index $.FormErrors "errors")}}
|
||||
<div class="alert alert-danger"><a class="panel-close close" data-dismiss="alert">×</a><i class="glyphicon glyphicon-exclamation-sign"></i> {{ . }}</div>
|
||||
{{end}}
|
||||
<p>Reassigning torrents to a new user is not easily reverted and should be done with care.</p>
|
||||
|
||||
{{with .Reassign}}
|
||||
<div class="form-group">
|
||||
<label for="name">Reassign to:</label>
|
||||
<input type="text" name="to" class="form-control" placeholder="User ID" {{if ne .AssignTo 0}}value="{{.AssignTo}}"{{end}} required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="by">Reassign based on:</label><br />
|
||||
<input type="radio" name="by" value="olduser" {{if eq .By "olduser"}}selected{{end}} required> Old Username<br />
|
||||
<input type="radio" name="by" value="torrentid" {{if eq .By "torrentid"}}selected{{end}} required> Torrent ID
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<p>One ID per line <b>or</b> a single username</p>
|
||||
<textarea rows="20" cols="40" name="data">{{.Data}}</textarea>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<p>Might take a long time, do <b>NOT</b> abort the request.</p>
|
||||
<button type="submit" class="btn btn-success">{{T "save_changes"}}</button>
|
||||
</form>
|
||||
{{end}}
|
|
@ -47,7 +47,13 @@
|
|||
<li><a href="{{ genRoute "mod_tlist"}}">{{T "Torrents"}}</a></li>
|
||||
<li><a href="{{ genRoute "mod_ulist"}}">{{T "Users"}}</a></li>
|
||||
<li><a href="{{ genRoute "mod_clist"}}">{{T "Comments"}}</a></li>
|
||||
<li><a href="{{ genRoute "mod_trlist"}}">{{T "Torrent Reports"}}</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Other<span class="caret"></span></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{{ genRoute "mod_trlist"}}">{{T "Torrent Reports"}}</a></li>
|
||||
<li><a href="{{ genRoute "mod_treassign" }}">Torrent Reassign</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
{{block "badge_user" .}}{{end}}
|
||||
|
||||
|
|
Référencer dans un nouveau ticket