Albirew/nyaa-pantsu
Archivé
1
0
Bifurcation 0
Ce dépôt a été archivé le 2022-05-07. Vous pouvez voir ses fichiers ou le cloner, mais pas ouvrir de ticket ou de demandes d'ajout, ni soumettre de changements.
nyaa-pantsu/router/modpanel.go
akuma06 93364dac77 activity log for users (#1002)
List Torrent delete log
Torrent edit log
Comment delete log
And every other logged activities
Can be filtered out by a filter tag ("edit" or "delete" supported)
Pages navigation

Can be accessed by /activities

Added some translation string
Fixed hidden username on api request
Fixed comments username on modpanel
New Activity model
New Activity handler
New Activity Service
Fixed some updating issue for ES when moderating torrents

Be aware deleting torrents and comments return the model now!
2017-06-15 12:44:46 +10:00

674 lignes
23 Kio
Go

package router
import (
"encoding/json"
"fmt"
"html"
"net/http"
"strconv"
"strings"
"github.com/NyaaPantsu/nyaa/config"
"github.com/NyaaPantsu/nyaa/db"
"github.com/NyaaPantsu/nyaa/model"
"github.com/NyaaPantsu/nyaa/service"
"github.com/NyaaPantsu/nyaa/service/activity"
"github.com/NyaaPantsu/nyaa/service/api"
"github.com/NyaaPantsu/nyaa/service/comment"
"github.com/NyaaPantsu/nyaa/service/report"
"github.com/NyaaPantsu/nyaa/service/torrent"
"github.com/NyaaPantsu/nyaa/service/user"
"github.com/NyaaPantsu/nyaa/service/user/permission"
"github.com/NyaaPantsu/nyaa/util/categories"
"github.com/NyaaPantsu/nyaa/util/log"
msg "github.com/NyaaPantsu/nyaa/util/messages"
"github.com/NyaaPantsu/nyaa/util/search"
"github.com/gorilla/mux"
)
// ReassignForm : Structure for reassign Form used by the reassign page
type ReassignForm struct {
AssignTo uint
By string
Data string
Torrents []uint
}
// ExtractInfo : Function to assign values from request to ReassignForm
func (f *ReassignForm) ExtractInfo(r *http.Request) error {
f.By = r.FormValue("by")
defer r.Body.Close()
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")
torrentID, 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(torrentID))
}
}
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
}
// ExecuteAction : Function for applying the changes from ReassignForm
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 _, torrentID := range toBeChanged {
torrent, err2 := torrentService.GetRawTorrentByID(torrentID)
if err2 == nil {
torrent.UploaderID = f.AssignTo
db.ORM.Model(&torrent).UpdateColumn(&torrent)
num++
}
}
return num, nil
}
// newPanelSearchForm : Helper that creates a search form without items/page field
// these need to be used when the templateVariables don't include `navigation`
func newPanelSearchForm() searchForm {
form := newSearchForm()
form.ShowItemsPerPage = false
return form
}
//
func newPanelCommonVariables(r *http.Request) commonTemplateVariables {
defer r.Body.Close()
common := newCommonVariables(r)
common.Search = newPanelSearchForm()
return common
}
// IndexModPanel : Controller for showing index page of Mod Panel
func IndexModPanel(w http.ResponseWriter, r *http.Request) {
offset := 10
defer r.Body.Close()
torrents, _, _ := torrentService.GetAllTorrents(offset, 0)
users, _ := userService.RetrieveUsersForAdmin(offset, 0)
comments, _ := commentService.GetAllComments(offset, 0, "", "")
torrentReports, _, _ := reportService.GetAllTorrentReports(offset, 0)
htv := panelIndexVbs{newPanelCommonVariables(r), torrents, model.TorrentReportsToJSON(torrentReports), users, comments}
err := panelIndex.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
}
// TorrentsListPanel : Controller for listing torrents, can accept common search arguments
func TorrentsListPanel(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
page := vars["page"]
messages := msg.GetMessages(r)
defer r.Body.Close()
deleted := r.URL.Query()["deleted"]
unblocked := r.URL.Query()["unblocked"]
blocked := r.URL.Query()["blocked"]
if deleted != nil {
messages.AddInfoTf("infos", "torrent_deleted", "")
}
if blocked != nil {
messages.AddInfoT("infos", "torrent_blocked")
}
if unblocked != nil {
messages.AddInfoT("infos", "torrent_unblocked")
}
var err error
pagenum := 1
if page != "" {
pagenum, err = strconv.Atoi(html.EscapeString(page))
if !log.CheckError(err) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
searchParam, torrents, count, err := search.SearchByQueryWithUser(r, pagenum)
if err != nil {
messages.ImportFromError("errors", err)
}
searchForm := searchForm{
SearchParam: searchParam,
Category: searchParam.Category.String(),
ShowItemsPerPage: true,
}
common := newCommonVariables(r)
common.Navigation = navigation{count, int(searchParam.Max), pagenum, "mod_tlist_page"}
common.Search = searchForm
ptlv := modelListVbs{common, torrents, messages.GetAllErrors(), messages.GetAllInfos()}
err = panelTorrentList.ExecuteTemplate(w, "admin_index.html", ptlv)
log.CheckError(err)
}
// TorrentReportListPanel : Controller for listing torrent reports, can accept pages
func TorrentReportListPanel(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
page := vars["page"]
messages := msg.GetMessages(r)
pagenum := 1
offset := 100
defer r.Body.Close()
var err error
if page != "" {
pagenum, err = strconv.Atoi(html.EscapeString(page))
if !log.CheckError(err) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
torrentReports, nbReports, _ := reportService.GetAllTorrentReports(offset, (pagenum-1)*offset)
reportJSON := model.TorrentReportsToJSON(torrentReports)
common := newCommonVariables(r)
common.Navigation = navigation{nbReports, offset, pagenum, "mod_trlist_page"}
ptrlv := modelListVbs{common, reportJSON, messages.GetAllErrors(), messages.GetAllInfos()}
err = panelTorrentReportList.ExecuteTemplate(w, "admin_index.html", ptrlv)
log.CheckError(err)
}
// UsersListPanel : Controller for listing users, can accept pages
func UsersListPanel(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
page := vars["page"]
pagenum := 1
offset := 100
defer r.Body.Close()
var err error
messages := msg.GetMessages(r)
if page != "" {
pagenum, err = strconv.Atoi(html.EscapeString(page))
if !log.CheckError(err) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
users, nbUsers := userService.RetrieveUsersForAdmin(offset, (pagenum-1)*offset)
common := newCommonVariables(r)
common.Navigation = navigation{nbUsers, offset, pagenum, "mod_ulist_page"}
htv := modelListVbs{common, users, messages.GetAllErrors(), messages.GetAllInfos()}
err = panelUserList.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
}
// CommentsListPanel : Controller for listing comments, can accept pages and userID
func CommentsListPanel(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
page := vars["page"]
pagenum := 1
offset := 100
userid := r.URL.Query().Get("userid")
defer r.Body.Close()
var err error
messages := msg.GetMessages(r)
if page != "" {
pagenum, err = strconv.Atoi(html.EscapeString(page))
if !log.CheckError(err) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
var conditions string
var values []interface{}
if userid != "" {
conditions = "user_id = ?"
values = append(values, userid)
}
comments, nbComments := commentService.GetAllComments(offset, (pagenum-1)*offset, conditions, values...)
common := newCommonVariables(r)
common.Navigation = navigation{nbComments, offset, pagenum, "mod_clist_page"}
htv := modelListVbs{common, comments, messages.GetAllErrors(), messages.GetAllInfos()}
err = panelCommentList.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
}
// TorrentEditModPanel : Controller for editing a torrent after GET request
func TorrentEditModPanel(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
torrent, _ := torrentService.GetTorrentByID(id)
messages := msg.GetMessages(r)
defer r.Body.Close()
torrentJSON := torrent.ToJSON()
uploadForm := apiService.NewTorrentRequest()
uploadForm.Name = torrentJSON.Name
uploadForm.Category = torrentJSON.Category + "_" + torrentJSON.SubCategory
uploadForm.Status = torrentJSON.Status
uploadForm.Hidden = torrent.Hidden
uploadForm.WebsiteLink = string(torrentJSON.WebsiteLink)
uploadForm.Description = string(torrentJSON.Description)
uploadForm.Language = torrent.Language
htv := formTemplateVariables{newPanelCommonVariables(r), uploadForm, messages.GetAllErrors(), messages.GetAllInfos()}
err := panelTorrentEd.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
}
// TorrentPostEditModPanel : Controller for editing a torrent after POST request
func TorrentPostEditModPanel(w http.ResponseWriter, r *http.Request) {
var uploadForm apiService.TorrentRequest
defer r.Body.Close()
id := r.URL.Query().Get("id")
messages := msg.GetMessages(r)
torrent, _ := torrentService.GetTorrentByID(id)
if torrent.ID > 0 {
errUp := uploadForm.ExtractEditInfo(r)
if errUp != nil {
messages.AddErrorT("errors", "fail_torrent_update")
}
if !messages.HasErrors() {
// update some (but not all!) values
torrent.Name = uploadForm.Name
torrent.Category = uploadForm.CategoryID
torrent.SubCategory = uploadForm.SubCategoryID
torrent.Status = uploadForm.Status
torrent.Hidden = uploadForm.Hidden
torrent.WebsiteLink = uploadForm.WebsiteLink
torrent.Description = uploadForm.Description
torrent.Language = uploadForm.Language
_, err := torrentService.UpdateUnscopeTorrent(&torrent)
messages.AddInfoT("infos", "torrent_updated")
if err == nil { // We only log edit torrent for admins
_, username := torrentService.HideTorrentUser(torrent.UploaderID, torrent.Uploader.Username, torrent.Hidden)
activity.Log(&model.User{}, torrent.Identifier(), "edit", "torrent_edited_by", strconv.Itoa(int(torrent.ID)), username, getUser(r).Username)
}
}
}
htv := formTemplateVariables{newPanelCommonVariables(r), uploadForm, messages.GetAllErrors(), messages.GetAllInfos()}
err := panelTorrentEd.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
}
// CommentDeleteModPanel : Controller for deleting a comment
func CommentDeleteModPanel(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
defer r.Body.Close()
comment, _, err := commentService.DeleteComment(id)
if err == nil {
activity.Log(&model.User{}, comment.Identifier(), "delete", "comment_deleted_by", strconv.Itoa(int(comment.ID)), comment.User.Username, getUser(r).Username)
}
url, _ := Router.Get("mod_clist").URL()
http.Redirect(w, r, url.String()+"?deleted", http.StatusSeeOther)
}
// TorrentDeleteModPanel : Controller for deleting a torrent
func TorrentDeleteModPanel(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
definitely := r.URL.Query()["definitely"]
defer r.Body.Close()
var returnRoute string
var err error
var torrent *model.Torrent
if definitely != nil {
torrent, _, err = torrentService.DefinitelyDeleteTorrent(id)
//delete reports of torrent
whereParams := serviceBase.CreateWhereParams("torrent_id = ?", id)
reports, _, _ := reportService.GetTorrentReportsOrderBy(&whereParams, "", 0, 0)
for _, report := range reports {
reportService.DeleteDefinitelyTorrentReport(report.ID)
}
returnRoute = "mod_tlist_deleted"
} else {
torrent, _, err = torrentService.DeleteTorrent(id)
//delete reports of torrent
whereParams := serviceBase.CreateWhereParams("torrent_id = ?", id)
reports, _, _ := reportService.GetTorrentReportsOrderBy(&whereParams, "", 0, 0)
for _, report := range reports {
reportService.DeleteTorrentReport(report.ID)
}
returnRoute = "mod_tlist"
}
if err == nil {
_, username := torrentService.HideTorrentUser(torrent.UploaderID, torrent.Uploader.Username, torrent.Hidden)
activity.Log(&model.User{}, torrent.Identifier(), "delete", "torrent_deleted_by", strconv.Itoa(int(torrent.ID)), username, getUser(r).Username)
}
url, _ := Router.Get(returnRoute).URL()
http.Redirect(w, r, url.String()+"?deleted", http.StatusSeeOther)
}
// TorrentReportDeleteModPanel : Controller for deleting a torrent report
func TorrentReportDeleteModPanel(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
defer r.Body.Close()
fmt.Println(id)
idNum, _ := strconv.ParseUint(id, 10, 64)
_, _, _ = reportService.DeleteTorrentReport(uint(idNum))
/* If we need to log report delete activity
if err == nil {
activity.Log(&model.User{}, torrent.Identifier(), "delete", "torrent_report_deleted_by", strconv.Itoa(int(report.ID)), getUser(r).Username)
}
*/
url, _ := Router.Get("mod_trlist").URL()
http.Redirect(w, r, url.String()+"?deleted", http.StatusSeeOther)
}
// TorrentReassignModPanel : Controller for reassigning a torrent, after GET request
func TorrentReassignModPanel(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
messages := msg.GetMessages(r)
htv := formTemplateVariables{newPanelCommonVariables(r), ReassignForm{}, messages.GetAllErrors(), messages.GetAllInfos()}
err := panelTorrentReassign.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
}
// TorrentPostReassignModPanel : Controller for reassigning a torrent, after POST request
func TorrentPostReassignModPanel(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
var rForm ReassignForm
messages := msg.GetMessages(r)
err2 := rForm.ExtractInfo(r)
if err2 != nil {
messages.ImportFromError("errors", err2)
} else {
count, err2 := rForm.ExecuteAction()
if err2 != nil {
messages.AddErrorT("errors", "something_went_wrong")
} else {
messages.AddInfoTf("infos", "nb_torrents_updated", count)
}
}
htv := formTemplateVariables{newPanelCommonVariables(r), rForm, messages.GetAllErrors(), messages.GetAllInfos()}
err := panelTorrentReassign.ExecuteTemplate(w, "admin_index.html", htv)
log.CheckError(err)
}
// TorrentsPostListPanel : Controller for listing torrents, after POST request when mass update
func TorrentsPostListPanel(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
torrentManyAction(r)
TorrentsListPanel(w, r)
}
// APIMassMod : This function is used on the frontend for the mass
/* Query is: action=status|delete|owner|category|multiple
* Needed: torrent_id[] Ids of torrents in checkboxes of name torrent_id
*
* Needed on context:
* status=0|1|2|3|4 according to config/torrent.go (can be omitted if action=delete|owner|category|multiple)
* owner is the User ID of the new owner of the torrents (can be omitted if action=delete|status|category|multiple)
* category is the category string (eg. 1_3) of the new category of the torrents (can be omitted if action=delete|status|owner|multiple)
*
* withreport is the bool to enable torrent reports deletion (can be omitted)
*
* In case of action=multiple, torrents can be at the same time changed status, owner and category
*/
func APIMassMod(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
torrentManyAction(r)
messages := msg.GetMessages(r) // new util for errors and infos
var apiJSON []byte
w.Header().Set("Content-Type", "application/json")
if !messages.HasErrors() {
mapOk := map[string]interface{}{"ok": true, "infos": messages.GetAllInfos()["infos"]}
apiJSON, _ = json.Marshal(mapOk)
} else { // We need to show error messages
mapNotOk := map[string]interface{}{"ok": false, "errors": messages.GetAllErrors()["errors"]}
apiJSON, _ = json.Marshal(mapNotOk)
}
w.Write(apiJSON)
}
// DeletedTorrentsModPanel : Controller for viewing deleted torrents, accept common search arguments
func DeletedTorrentsModPanel(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
vars := mux.Vars(r)
page := vars["page"]
messages := msg.GetMessages(r) // new util for errors and infos
deleted := r.URL.Query()["deleted"]
unblocked := r.URL.Query()["unblocked"]
blocked := r.URL.Query()["blocked"]
if deleted != nil {
messages.AddInfoT("infos", "torrent_deleted_definitely")
}
if blocked != nil {
messages.AddInfoT("infos", "torrent_blocked")
}
if unblocked != nil {
messages.AddInfoT("infos", "torrent_unblocked")
}
var err error
pagenum := 1
if page != "" {
pagenum, err = strconv.Atoi(html.EscapeString(page))
if !log.CheckError(err) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
searchParam, torrents, count, err := search.SearchByQueryDeleted(r, pagenum)
if err != nil {
messages.ImportFromError("errors", err)
}
searchForm := searchForm{
SearchParam: searchParam,
Category: searchParam.Category.String(),
ShowItemsPerPage: true,
}
common := newCommonVariables(r)
common.Navigation = navigation{count, int(searchParam.Max), pagenum, "mod_tlist_page"}
common.Search = searchForm
ptlv := modelListVbs{common, torrents, messages.GetAllErrors(), messages.GetAllInfos()}
err = panelTorrentList.ExecuteTemplate(w, "admin_index.html", ptlv)
log.CheckError(err)
}
// DeletedTorrentsPostPanel : Controller for viewing deleted torrents after a mass update, accept common search arguments
func DeletedTorrentsPostPanel(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
torrentManyAction(r)
DeletedTorrentsModPanel(w, r)
}
// TorrentBlockModPanel : Controller to lock torrents, redirecting to previous page
func TorrentBlockModPanel(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
id := r.URL.Query().Get("id")
torrent, _, err := torrentService.ToggleBlockTorrent(id)
var returnRoute, action string
if torrent.IsDeleted() {
returnRoute = "mod_tlist_deleted"
} else {
returnRoute = "mod_tlist"
}
if torrent.IsBlocked() {
action = "blocked"
} else {
action = "unblocked"
}
if err == nil {
_, username := torrentService.HideTorrentUser(torrent.UploaderID, torrent.Uploader.Username, torrent.Hidden)
activity.Log(&model.User{}, torrent.Identifier(), action, "torrent_"+action+"_by", strconv.Itoa(int(torrent.ID)), username, getUser(r).Username)
}
url, _ := Router.Get(returnRoute).URL()
http.Redirect(w, r, url.String()+"?"+action, http.StatusSeeOther)
}
/*
* Controller to modify multiple torrents and can be used by the owner of the torrent or admin
*/
func torrentManyAction(r *http.Request) {
defer r.Body.Close()
currentUser := getUser(r)
r.ParseForm()
torrentsSelected := r.Form["torrent_id"] // should be []string
action := r.FormValue("action")
status, _ := strconv.Atoi(r.FormValue("status"))
owner, _ := strconv.Atoi(r.FormValue("owner"))
category := r.FormValue("category")
withReport, _ := strconv.ParseBool(r.FormValue("withreport"))
messages := msg.GetMessages(r) // new util for errors and infos
catID, subCatID := -1, -1
var err error
if action == "" {
messages.AddErrorT("errors", "no_action_selected")
}
if action == "status" && r.FormValue("status") == "" { // We need to check the form value, not the int one because hidden is 0
messages.AddErrorT("errors", "no_move_location_selected")
}
if action == "owner" && r.FormValue("owner") == "" { // We need to check the form value, not the int one because renchon is 0
messages.AddErrorT("errors", "no_owner_selected")
}
if action == "category" && category == "" {
messages.AddErrorT("errors", "no_category_selected")
}
if len(torrentsSelected) == 0 {
messages.AddErrorT("errors", "select_one_element")
}
if r.FormValue("withreport") == "" { // Default behavior for withreport
withReport = false
}
if !config.Conf.Torrents.Status[status] { // Check if the status exist
messages.AddErrorTf("errors", "no_status_exist", status)
status = -1
}
if !userPermission.HasAdmin(currentUser) {
if r.FormValue("status") != "" { // Condition to check if a user try to change torrent status without having the right permission
if (status == model.TorrentStatusTrusted && !currentUser.IsTrusted()) || status == model.TorrentStatusAPlus || status == 0 {
status = model.TorrentStatusNormal
}
}
if r.FormValue("owner") != "" { // Only admins can change owner of torrents
owner = -1
}
withReport = false // Users should not be able to remove reports
}
if r.FormValue("owner") != "" && userPermission.HasAdmin(currentUser) { // We check that the user given exist and if not we return an error
_, _, errorUser := userService.RetrieveUserForAdmin(strconv.Itoa(owner))
if errorUser != nil {
messages.AddErrorTf("errors", "no_user_found_id", owner)
owner = -1
}
}
if category != "" {
catsSplit := strings.Split(category, "_")
// need this to prevent out of index panics
if len(catsSplit) == 2 {
catID, err = strconv.Atoi(catsSplit[0])
if err != nil {
messages.AddErrorT("errors", "invalid_torrent_category")
}
subCatID, err = strconv.Atoi(catsSplit[1])
if err != nil {
messages.AddErrorT("errors", "invalid_torrent_category")
}
if !categories.CategoryExists(category) {
messages.AddErrorT("errors", "invalid_torrent_category")
}
}
}
if !messages.HasErrors() {
for _, torrentID := range torrentsSelected {
torrent, _ := torrentService.GetTorrentByID(torrentID)
if torrent.ID > 0 && userPermission.CurrentOrAdmin(currentUser, torrent.UploaderID) {
if action == "status" || action == "multiple" || action == "category" || action == "owner" {
/* If we don't delete, we make changes according to the form posted and we save at the end */
if r.FormValue("status") != "" && status != -1 {
torrent.Status = status
messages.AddInfoTf("infos", "torrent_moved", torrent.Name)
}
if r.FormValue("owner") != "" && owner != -1 {
torrent.UploaderID = uint(owner)
messages.AddInfoTf("infos", "torrent_owner_changed", torrent.Name)
}
if category != "" && catID != -1 && subCatID != -1 {
torrent.Category = catID
torrent.SubCategory = subCatID
messages.AddInfoTf("infos", "torrent_category_changed", torrent.Name)
}
/* Changes are done, we save */
_, err := torrentService.UpdateUnscopeTorrent(&torrent)
if err == nil {
_, username := torrentService.HideTorrentUser(torrent.UploaderID, torrent.Uploader.Username, torrent.Hidden)
activity.Log(&model.User{}, torrent.Identifier(), "edited", "torrent_edited_by", strconv.Itoa(int(torrent.ID)), username, getUser(r).Username)
}
} else if action == "delete" {
if status == model.TorrentStatusBlocked { // Then we should lock torrents before deleting them
torrent.Status = status
messages.AddInfoTf("infos", "torrent_moved", torrent.Name)
torrentService.UpdateUnscopeTorrent(&torrent)
}
_, _, err = torrentService.DeleteTorrent(torrentID)
if err != nil {
messages.ImportFromError("errors", err)
} else {
messages.AddInfoTf("infos", "torrent_deleted", torrent.Name)
_, username := torrentService.HideTorrentUser(torrent.UploaderID, torrent.Uploader.Username, torrent.Hidden)
activity.Log(&model.User{}, torrent.Identifier(), "deleted", "torrent_deleted_by", strconv.Itoa(int(torrent.ID)), username, getUser(r).Username)
}
} else {
messages.AddErrorTf("errors", "no_action_exist", action)
}
if withReport {
whereParams := serviceBase.CreateWhereParams("torrent_id = ?", torrentID)
reports, _, _ := reportService.GetTorrentReportsOrderBy(&whereParams, "", 0, 0)
for _, report := range reports {
reportService.DeleteTorrentReport(report.ID)
}
messages.AddInfoTf("infos", "torrent_reports_deleted", torrent.Name)
}
} else {
messages.AddErrorTf("errors", "torrent_not_exist", torrentID)
}
}
}
}